From b74fd579662c9d05db5cfb4b0e2b95f8919b9916 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 16 Jul 2005 07:46:13 -0400 Subject: [PATCH 1/6] Add "Files" and "Pickaxe" to the find menu. "Files" matches the find string against each of the files modified by each commit, and can do exact, case-ignoring or regexp matching. "Pickaxe" uses git-diff-tree -S'string' and can only do exact matching. I called it "pickaxe" rather than "find within patch" since it only finds commits where the string is present in the child but not the parents or vice versa, and "pickaxe" is what the author of that feature calls it. --- gitk | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 247 insertions(+), 18 deletions(-) diff --git a/gitk b/gitk index f969c14f18..a1d65fa87a 100755 --- a/gitk +++ b/gitk @@ -270,7 +270,7 @@ proc error_popup msg { proc makewindow {} { global canv canv2 canv3 linespc charspc ctext cflist textfont - global findtype findloc findstring fstring geometry + global findtype findtypemenu findloc findstring fstring geometry global entries sha1entry sha1string sha1but global maincursor textcursor global rowctxmenu @@ -342,12 +342,15 @@ proc makewindow {} { entry $fstring -width 30 -font $textfont -textvariable findstring pack $fstring -side left -expand 1 -fill x set findtype Exact - tk_optionMenu .ctop.top.bar.findtype findtype Exact IgnCase Regexp + set findtypemenu [tk_optionMenu .ctop.top.bar.findtype \ + findtype Exact IgnCase Regexp] set findloc "All fields" tk_optionMenu .ctop.top.bar.findloc findloc "All fields" Headline \ - Comments Author Committer + Comments Author Committer Files Pickaxe pack .ctop.top.bar.findloc -side right pack .ctop.top.bar.findtype -side right + # for making sure type==Exact whenever loc==Pickaxe + trace add variable findloc write findlocchange panedwindow .ctop.cdet -orient horizontal .ctop add .ctop.cdet @@ -397,12 +400,13 @@ proc makewindow {} { bindkey b "$ctext yview scroll -1 pages" bindkey d "$ctext yview scroll 18 units" bindkey u "$ctext yview scroll -18 units" - bindkey / findnext + bindkey / {findnext 1} + bindkey {findnext 0} bindkey ? findprev bindkey f nextfile bind . doquit bind . dofind - bind . findnext + bind . {findnext 0} bind . findprev bind . {incrfont 1} bind . {incrfont 1} @@ -1136,10 +1140,15 @@ proc dofind {} { global numcommits lineid linehtag linentag linedtag global mainfont namefont canv canv2 canv3 selectedline global matchinglines foundstring foundstrlen + + stopfindproc unmarkmatches focus . set matchinglines {} - set fldtypes {Headline Author Date Committer CDate Comment} + if {$findloc == "Pickaxe"} { + findpatches + return + } if {$findtype == "IgnCase"} { set foundstring [string tolower $findstring] } else { @@ -1147,12 +1156,17 @@ proc dofind {} { } set foundstrlen [string length $findstring] if {$foundstrlen == 0} return + if {$findloc == "Files"} { + findfiles + return + } if {![info exists selectedline]} { set oldsel -1 } else { set oldsel $selectedline } set didsel 0 + set fldtypes {Headline Author Date Committer CDate Comment} for {set l 0} {$l < $numcommits} {incr l} { set id $lineid($l) set info $commitinfo($id) @@ -1202,10 +1216,12 @@ proc findselectline {l} { } } -proc findnext {} { +proc findnext {restart} { global matchinglines selectedline if {![info exists matchinglines]} { - dofind + if {$restart} { + dofind + } return } if {![info exists selectedline]} return @@ -1237,6 +1253,203 @@ proc findprev {} { } } +proc findlocchange {name ix op} { + global findloc findtype findtypemenu + if {$findloc == "Pickaxe"} { + set findtype Exact + set state disabled + } else { + set state normal + } + $findtypemenu entryconf 1 -state $state + $findtypemenu entryconf 2 -state $state +} + +proc stopfindproc {{done 0}} { + global findprocpid findprocfile findids + global ctext findoldcursor phase maincursor textcursor + global findinprogress + + catch {unset findids} + if {[info exists findprocpid]} { + if {!$done} { + catch {exec kill $findprocpid} + } + catch {close $findprocfile} + unset findprocpid + } + if {[info exists findinprogress]} { + unset findinprogress + if {$phase != "incrdraw"} { + . config -cursor $maincursor + $ctext config -cursor $textcursor + } + } +} + +proc findpatches {} { + global findstring selectedline numcommits + global findprocpid findprocfile + global finddidsel ctext lineid findinprogress + + if {$numcommits == 0} return + + # make a list of all the ids to search, starting at the one + # after the selected line (if any) + if {[info exists selectedline]} { + set l $selectedline + } else { + set l -1 + } + set inputids {} + for {set i 0} {$i < $numcommits} {incr i} { + if {[incr l] >= $numcommits} { + set l 0 + } + append inputids $lineid($l) "\n" + } + + if {[catch { + set f [open [list | git-diff-tree --stdin -s -r -S$findstring \ + << $inputids] r] + } err]} { + error_popup "Error starting search process: $err" + return + } + + set findprocfile $f + set findprocpid [pid $f] + fconfigure $f -blocking 0 + fileevent $f readable readfindproc + set finddidsel 0 + . config -cursor watch + $ctext config -cursor watch + set findinprogress 1 +} + +proc readfindproc {} { + global findprocfile finddidsel + global idline matchinglines + + set n [gets $findprocfile line] + if {$n < 0} { + if {[eof $findprocfile]} { + stopfindproc 1 + if {!$finddidsel} { + bell + } + } + return + } + if {![regexp {^[0-9a-f]{40}} $line id]} { + error_popup "Can't parse git-diff-tree output: $line" + stopfindproc + return + } + if {![info exists idline($id)]} { + puts stderr "spurious id: $id" + return + } + set l $idline($id) + lappend matchinglines $l + if {!$finddidsel} { + findselectline $l + set finddidsel 1 + } +} + +proc findfiles {} { + global selectedline numcommits lineid + global ffileline finddidsel parents findstartline + global findinprogress ctext + + if {$numcommits == 0} return + + if {[info exists selectedline]} { + set l [expr {$selectedline + 1}] + } else { + set l 0 + } + set ffileline $l + set finddidsel 0 + set findstartline $l + set id $lineid($l) + set p [lindex $parents($id) 0] + . config -cursor watch + $ctext config -cursor watch + set findinprogress 1 + update + findcont [list $id $p] +} + +proc findcont {ids} { + global findids treediffs parents nparents treepending + global ffileline findstartline finddidsel + global lineid numcommits matchinglines findinprogress + global findmergefiles + + set id [lindex $ids 0] + set p [lindex $ids 1] + set pi [lsearch -exact $parents($id) $p] + set l $ffileline + while 1 { + if {$findmergefiles || $nparents($id) == 1} { + if {![info exists treediffs($ids)]} { + set findids $ids + set ffileline $l + if {![info exists treepending]} { + gettreediffs $ids + } + return + } + set doesmatch 0 + foreach f $treediffs($ids) { + set x [findmatches $f] + if {$x != {}} { + set doesmatch 1 + break + } + } + if {$doesmatch} { + lappend matchinglines $l + markheadline $l $id + if {!$finddidsel} { + findselectline $l + set finddidsel 1 + } + set pi $nparents($id) + } + } else { + set pi $nparents($id) + } + if {[incr pi] >= $nparents($id)} { + set pi 0 + if {[incr l] >= $numcommits} { + set l 0 + } + if {$l == $findstartline} break + set id $lineid($l) + } + set p [lindex $parents($id) $pi] + set ids [list $id $p] + } + stopfindproc + if {!$finddidsel} { + bell + } +} + +# mark a commit as matching by putting a yellow background +# behind the headline +proc markheadline {l id} { + global canv mainfont linehtag commitinfo + + set bbox [$canv bbox $linehtag($l)] + set t [$canv create rect $bbox -outline {} -tags matches -fill yellow] + $canv lower $t +} + +# mark the bits of a headline, author or date that match a find string proc markmatches {canv l str tag matches font} { set bbox [$canv bbox $tag] set x0 [lindex $bbox 0] @@ -1255,9 +1468,10 @@ proc markmatches {canv l str tag matches font} { } proc unmarkmatches {} { - global matchinglines + global matchinglines findids allcanvs delete matches catch {unset matchinglines} + catch {unset findids} } proc selcanvline {w x y} { @@ -1393,11 +1607,7 @@ proc selnextline {dir} { } proc addtocflist {ids} { - global diffids treediffs cflist - if {$ids != $diffids} { - gettreediffs $diffids - return - } + global treediffs cflist foreach f $treediffs($ids) { $cflist insert end $f } @@ -1416,13 +1626,28 @@ proc gettreediffs {ids} { } proc gettreediffline {gdtf ids} { - global treediffs treepending + global treediffs treepending diffids findids set n [gets $gdtf line] if {$n < 0} { if {![eof $gdtf]} return close $gdtf unset treepending - addtocflist $ids + if {[info exists diffids]} { + if {$ids != $diffids} { + gettreediffs $diffids + } else { + addtocflist $ids + } + } + if {[info exists findids]} { + if {$ids != $findids} { + if {![info exists treepending]} { + gettreediffs $findids + } + } else { + findcont $ids + } + } return } set file [lindex $line 5] @@ -1459,14 +1684,17 @@ proc getblobdiffline {bdf ids} { if {$n < 0} { if {[eof $bdf]} { close $bdf - if {$ids == $diffids && $bdf == $blobdifffd($ids)} { + if {[info exists diffids] && $ids == $diffids + && $bdf == $blobdifffd($ids)} { $ctext tag add $curdifftag $curtagstart end set seenfile($curdifftag) 1 + unset diffids } } return } - if {$ids != $diffids || $bdf != $blobdifffd($ids)} { + if {![info exists diffids] || $ids != $diffids + || $bdf != $blobdifffd($ids)} { return } $ctext conf -state normal @@ -2044,6 +2272,7 @@ set wrcomcmd "git-diff-tree --stdin -p --pretty" set mainfont {Helvetica 9} set textfont {Courier 9} +set findmergefiles 0 set colors {green red blue magenta darkgrey brown orange} From 14c9dbd69bfed89011f99278c7f293b0d186ffc7 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sat, 16 Jul 2005 21:53:55 -0400 Subject: [PATCH 2/6] Make searching in files changed faster, and fix some bugs. We now kick off a single git-diff-tree -r --stdin and feed it all the commit pairs we want to know about, instead of doing a separate git-diff-tree invocation for each. --- gitk | 180 +++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 137 insertions(+), 43 deletions(-) diff --git a/gitk b/gitk index a1d65fa87a..e190ce6e6e 100755 --- a/gitk +++ b/gitk @@ -1291,6 +1291,7 @@ proc findpatches {} { global findstring selectedline numcommits global findprocpid findprocfile global finddidsel ctext lineid findinprogress + global findinsertpos if {$numcommits == 0} return @@ -1317,6 +1318,7 @@ proc findpatches {} { return } + set findinsertpos end set findprocfile $f set findprocpid [pid $f] fconfigure $f -blocking 0 @@ -1329,7 +1331,7 @@ proc findpatches {} { proc readfindproc {} { global findprocfile finddidsel - global idline matchinglines + global idline matchinglines findinsertpos set n [gets $findprocfile line] if {$n < 0} { @@ -1351,7 +1353,24 @@ proc readfindproc {} { return } set l $idline($id) - lappend matchinglines $l + insertmatch $l $id +} + +proc insertmatch {l id} { + global matchinglines findinsertpos finddidsel + + if {$findinsertpos == "end"} { + if {$matchinglines != {} && $l < [lindex $matchinglines 0]} { + set matchinglines [linsert $matchinglines 0 $l] + set findinsertpos 1 + } else { + lappend matchinglines $l + } + } else { + set matchinglines [linsert $matchinglines $findinsertpos $l] + incr findinsertpos + } + markheadline $l $id if {!$finddidsel} { findselectline $l set finddidsel 1 @@ -1359,9 +1378,11 @@ proc readfindproc {} { } proc findfiles {} { - global selectedline numcommits lineid - global ffileline finddidsel parents findstartline - global findinprogress ctext + global selectedline numcommits lineid ctext + global ffileline finddidsel parents nparents + global findinprogress findstartline findinsertpos + global treediffs fdiffids fdiffsneeded fdiffpos + global findmergefiles if {$numcommits == 0} return @@ -1371,15 +1392,107 @@ proc findfiles {} { set l 0 } set ffileline $l - set finddidsel 0 set findstartline $l + set diffsneeded {} + set fdiffsneeded {} + while 1 { + set id $lineid($l) + if {$findmergefiles || $nparents($id) == 1} { + foreach p $parents($id) { + if {![info exists treediffs([list $id $p])]} { + append diffsneeded "$id $p\n" + lappend fdiffsneeded [list $id $p] + } + } + } + if {[incr l] >= $numcommits} { + set l 0 + } + if {$l == $findstartline} break + } + + # start off a git-diff-tree process if needed + if {$diffsneeded ne {}} { + if {[catch { + set df [open [list | git-diff-tree -r --stdin << $diffsneeded] r] + } err ]} { + error_popup "Error starting search process: $err" + return + } + catch {unset fdiffids} + set fdiffpos 0 + fconfigure $df -blocking 0 + fileevent $df readable [list readfilediffs $df] + } + + set finddidsel 0 + set findinsertpos end set id $lineid($l) set p [lindex $parents($id) 0] . config -cursor watch $ctext config -cursor watch set findinprogress 1 - update findcont [list $id $p] + update +} + +proc readfilediffs {df} { + global findids fdiffids fdiffs + + set n [gets $df line] + if {$n < 0} { + if {[eof $df]} { + donefilediff + if {[catch {close $df} err]} { + stopfindproc + bell + error_popup "Error in git-diff-tree: $err" + } elseif {[info exists findids]} { + set ids $findids + stopfindproc + bell + error_popup "Couldn't find diffs for {$ids}" + } + } + return + } + if {[regexp {^([0-9a-f]{40}) \(from ([0-9a-f]{40})\)} $line match id p]} { + # start of a new string of diffs + donefilediff + set fdiffids [list $id $p] + set fdiffs {} + } elseif {[string match ":*" $line]} { + lappend fdiffs [lindex $line 5] + } +} + +proc donefilediff {} { + global fdiffids fdiffs treediffs findids + global fdiffsneeded fdiffpos + + if {[info exists fdiffids]} { + while {[lindex $fdiffsneeded $fdiffpos] ne $fdiffids + && $fdiffpos < [llength $fdiffsneeded]} { + # git-diff-tree doesn't output anything for a commit + # which doesn't change anything + set nullids [lindex $fdiffsneeded $fdiffpos] + set treediffs($nullids) {} + if {[info exists findids] && $nullids eq $findids} { + unset findids + findcont $nullids + } + incr fdiffpos + } + incr fdiffpos + + if {![info exists treediffs($fdiffids)]} { + set treediffs($fdiffids) $fdiffs + } + if {[info exists findids] && $fdiffids eq $findids} { + unset findids + findcont $fdiffids + } + } } proc findcont {ids} { @@ -1397,9 +1510,6 @@ proc findcont {ids} { if {![info exists treediffs($ids)]} { set findids $ids set ffileline $l - if {![info exists treepending]} { - gettreediffs $ids - } return } set doesmatch 0 @@ -1411,12 +1521,7 @@ proc findcont {ids} { } } if {$doesmatch} { - lappend matchinglines $l - markheadline $l $id - if {!$finddidsel} { - findselectline $l - set finddidsel 1 - } + insertmatch $l $id set pi $nparents($id) } } else { @@ -1496,7 +1601,7 @@ proc selectline {l} { global canv canv2 canv3 ctext commitinfo selectedline global lineid linehtag linentag linedtag global canvy0 linespc parents nparents - global cflist currentid sha1entry diffids + global cflist currentid sha1entry global commentend seenfile idtags $canv delete hover if {![info exists lineid($l)] || ![info exists linehtag($l)]} return @@ -1550,7 +1655,6 @@ proc selectline {l} { set id $lineid($l) set currentid $id - set diffids [concat $id $parents($id)] $sha1entry delete 0 end $sha1entry insert 0 $id $sha1entry selection from 0 @@ -1581,20 +1685,21 @@ proc selectline {l} { $cflist delete 0 end $cflist insert end "Comments" if {$nparents($id) == 1} { - startdiff + startdiff [concat $id $parents($id)] } catch {unset seenfile} } -proc startdiff {} { +proc startdiff {ids} { global treediffs diffids treepending - if {![info exists treediffs($diffids)]} { + if {![info exists treediffs($ids)]} { + set diffids $ids if {![info exists treepending]} { - gettreediffs $diffids + gettreediffs $ids } } else { - addtocflist $diffids + addtocflist $ids } } @@ -1626,7 +1731,7 @@ proc gettreediffs {ids} { } proc gettreediffline {gdtf ids} { - global treediffs treepending diffids findids + global treediffs treepending diffids set n [gets $gdtf line] if {$n < 0} { if {![eof $gdtf]} return @@ -1636,18 +1741,10 @@ proc gettreediffline {gdtf ids} { if {$ids != $diffids} { gettreediffs $diffids } else { + unset diffids addtocflist $ids } } - if {[info exists findids]} { - if {$ids != $findids} { - if {![info exists treepending]} { - gettreediffs $findids - } - } else { - findcont $ids - } - } return } set file [lindex $line 5] @@ -1655,7 +1752,7 @@ proc gettreediffline {gdtf ids} { } proc getblobdiffs {ids} { - global diffopts blobdifffd env curdifftag curtagstart + global diffopts blobdifffd blobdiffids env curdifftag curtagstart global diffindex difffilestart nextupdate set id [lindex $ids 0] @@ -1666,6 +1763,7 @@ proc getblobdiffs {ids} { return } fconfigure $bdf -blocking 0 + set blobdiffids $ids set blobdifffd($ids) $bdf set curdifftag Comments set curtagstart 0.0 @@ -1676,7 +1774,7 @@ proc getblobdiffs {ids} { } proc getblobdiffline {bdf ids} { - global diffids blobdifffd ctext curdifftag curtagstart seenfile + global blobdiffids blobdifffd ctext curdifftag curtagstart seenfile global diffnexthead diffnextnote diffindex difffilestart global nextupdate @@ -1684,17 +1782,14 @@ proc getblobdiffline {bdf ids} { if {$n < 0} { if {[eof $bdf]} { close $bdf - if {[info exists diffids] && $ids == $diffids - && $bdf == $blobdifffd($ids)} { + if {$ids == $blobdiffids && $bdf == $blobdifffd($ids)} { $ctext tag add $curdifftag $curtagstart end set seenfile($curdifftag) 1 - unset diffids } } return } - if {![info exists diffids] || $ids != $diffids - || $bdf != $blobdifffd($ids)} { + if {$ids != $blobdiffids || $bdf != $blobdifffd($ids)} { return } $ctext conf -state normal @@ -2009,7 +2104,7 @@ proc rowmenu {x y id} { proc diffvssel {dirn} { global rowmenuid selectedline lineid global ctext cflist - global diffids commitinfo + global commitinfo if {![info exists selectedline]} return if {$dirn} { @@ -2033,8 +2128,7 @@ proc diffvssel {dirn} { $ctext conf -state disabled $ctext tag delete Comments $ctext tag remove found 1.0 end - set diffids [list $newid $oldid] - startdiff + startdiff [list $newid $oldid] } proc mkpatch {} { From e2ed4324b0b99fd3cb93bd14b6e1599c6fcbfe23 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 17 Jul 2005 03:39:44 -0400 Subject: [PATCH 3/6] First cut at displaying the diffs for a merge. We display the files where the child differs from the first parent first in black in the file list window, followed by the second parent in blue, and so on using different colors for each parent (provided you don't have more than 6 parents; if you do we cycle around). --- gitk | 53 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/gitk b/gitk index e190ce6e6e..2db187c017 100755 --- a/gitk +++ b/gitk @@ -1684,13 +1684,25 @@ proc selectline {l} { $cflist delete 0 end $cflist insert end "Comments" - if {$nparents($id) == 1} { - startdiff [concat $id $parents($id)] - } + startdiff $id $parents($id) +} + +proc startdiff {id vs} { + global diffpending diffpindex + global diffindex difffilestart seenfile + global curdifftag curtagstart + + set diffpending $vs + set diffpindex 0 catch {unset seenfile} + set diffindex 0 + catch {unset difffilestart} + set curdifftag Comments + set curtagstart 0.0 + contdiff [list $id [lindex $vs 0]] } -proc startdiff {ids} { +proc contdiff {ids} { global treediffs diffids treepending if {![info exists treediffs($ids)]} { @@ -1712,9 +1724,13 @@ proc selnextline {dir} { } proc addtocflist {ids} { - global treediffs cflist + global treediffs cflist diffpindex + + set colors {black blue green red cyan magenta} + set color [lindex $colors [expr {$diffpindex % [llength $colors]}]] foreach f $treediffs($ids) { $cflist insert end $f + $cflist itemconf end -foreground $color } getblobdiffs $ids } @@ -1741,7 +1757,6 @@ proc gettreediffline {gdtf ids} { if {$ids != $diffids} { gettreediffs $diffids } else { - unset diffids addtocflist $ids } } @@ -1752,8 +1767,8 @@ proc gettreediffline {gdtf ids} { } proc getblobdiffs {ids} { - global diffopts blobdifffd blobdiffids env curdifftag curtagstart - global diffindex difffilestart nextupdate + global diffopts blobdifffd diffids env + global nextupdate set id [lindex $ids 0] set p [lindex $ids 1] @@ -1763,33 +1778,33 @@ proc getblobdiffs {ids} { return } fconfigure $bdf -blocking 0 - set blobdiffids $ids set blobdifffd($ids) $bdf - set curdifftag Comments - set curtagstart 0.0 - set diffindex 0 - catch {unset difffilestart} - fileevent $bdf readable "getblobdiffline $bdf {$ids}" + fileevent $bdf readable [list getblobdiffline $bdf $ids] set nextupdate [expr {[clock clicks -milliseconds] + 100}] } proc getblobdiffline {bdf ids} { - global blobdiffids blobdifffd ctext curdifftag curtagstart seenfile + global diffids blobdifffd ctext curdifftag curtagstart seenfile global diffnexthead diffnextnote diffindex difffilestart - global nextupdate + global nextupdate diffpending diffpindex set n [gets $bdf line] if {$n < 0} { if {[eof $bdf]} { close $bdf - if {$ids == $blobdiffids && $bdf == $blobdifffd($ids)} { + if {$ids == $diffids && $bdf == $blobdifffd($ids)} { $ctext tag add $curdifftag $curtagstart end set seenfile($curdifftag) 1 + if {[incr diffpindex] < [llength $diffpending]} { + set id [lindex $ids 0] + set p [lindex $diffpending $diffpindex] + contdiff [list $id $p] + } } } return } - if {$ids != $blobdiffids || $bdf != $blobdifffd($ids)} { + if {$ids != $diffids || $bdf != $blobdifffd($ids)} { return } $ctext conf -state normal @@ -1882,7 +1897,7 @@ proc nextfile {} { } proc listboxsel {} { - global ctext cflist currentid treediffs seenfile + global ctext cflist currentid treediffs if {![info exists currentid]} return set sel [lsort [$cflist curselection]] if {$sel eq {}} return From 4f2c2642ca7331e4950e8d6c1d112eef1918c980 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Sun, 17 Jul 2005 11:11:44 -0400 Subject: [PATCH 4/6] Fix display of mode changes in details pane. Also simplified the parsing of the git-diff-tree -p output and got rid of the unused 'seenfile' variable. --- gitk | 46 +++++++++++++--------------------------------- 1 file changed, 13 insertions(+), 33 deletions(-) diff --git a/gitk b/gitk index 2db187c017..d994eec915 100755 --- a/gitk +++ b/gitk @@ -1602,7 +1602,7 @@ proc selectline {l} { global lineid linehtag linentag linedtag global canvy0 linespc parents nparents global cflist currentid sha1entry - global commentend seenfile idtags + global commentend idtags $canv delete hover if {![info exists lineid($l)] || ![info exists linehtag($l)]} return $canv delete secsel @@ -1689,12 +1689,11 @@ proc selectline {l} { proc startdiff {id vs} { global diffpending diffpindex - global diffindex difffilestart seenfile + global diffindex difffilestart global curdifftag curtagstart set diffpending $vs set diffpindex 0 - catch {unset seenfile} set diffindex 0 catch {unset difffilestart} set curdifftag Comments @@ -1705,8 +1704,8 @@ proc startdiff {id vs} { proc contdiff {ids} { global treediffs diffids treepending + set diffids $ids if {![info exists treediffs($ids)]} { - set diffids $ids if {![info exists treepending]} { gettreediffs $ids } @@ -1768,7 +1767,7 @@ proc gettreediffline {gdtf ids} { proc getblobdiffs {ids} { global diffopts blobdifffd diffids env - global nextupdate + global nextupdate diffinhdr set id [lindex $ids 0] set p [lindex $ids 1] @@ -1777,6 +1776,7 @@ proc getblobdiffs {ids} { puts "error getting diffs: $err" return } + set diffinhdr 0 fconfigure $bdf -blocking 0 set blobdifffd($ids) $bdf fileevent $bdf readable [list getblobdiffline $bdf $ids] @@ -1784,9 +1784,9 @@ proc getblobdiffs {ids} { } proc getblobdiffline {bdf ids} { - global diffids blobdifffd ctext curdifftag curtagstart seenfile + global diffids blobdifffd ctext curdifftag curtagstart global diffnexthead diffnextnote diffindex difffilestart - global nextupdate diffpending diffpindex + global nextupdate diffpending diffpindex diffinhdr set n [gets $bdf line] if {$n < 0} { @@ -1794,7 +1794,6 @@ proc getblobdiffline {bdf ids} { close $bdf if {$ids == $diffids && $bdf == $blobdifffd($ids)} { $ctext tag add $curdifftag $curtagstart end - set seenfile($curdifftag) 1 if {[incr diffpindex] < [llength $diffpending]} { set id [lindex $ids 0] set p [lindex $diffpending $diffpindex] @@ -1808,18 +1807,12 @@ proc getblobdiffline {bdf ids} { return } $ctext conf -state normal - if {[regexp {^---[ \t]+([^/])*/(.*)} $line match s1 fname]} { + if {[regexp {^diff --git a/(.*) b/} $line match fname]} { # start of a new file $ctext insert end "\n" $ctext tag add $curdifftag $curtagstart end - set seenfile($curdifftag) 1 set curtagstart [$ctext index "end - 1c"] set header $fname - if {[info exists diffnexthead]} { - set fname $diffnexthead - set header "$diffnexthead ($diffnextnote)" - unset diffnexthead - } set here [$ctext index "end - 1c"] set difffilestart($diffindex) $here incr diffindex @@ -1831,27 +1824,15 @@ proc getblobdiffline {bdf ids} { set l [expr {(78 - [string length $header]) / 2}] set pad [string range "----------------------------------------" 1 $l] $ctext insert end "$pad $header $pad\n" filesep - } elseif {[string range $line 0 2] == "+++"} { - # no need to do anything with this - } elseif {[regexp {^Created: (.*) \((mode: *[0-7]*)\)} $line match fn m]} { - set diffnexthead $fn - set diffnextnote "created, mode $m" - } elseif {[string range $line 0 8] == "Deleted: "} { - set diffnexthead [string range $line 9 end] - set diffnextnote "deleted" - } elseif {[regexp {^diff --git a/(.*) b/} $line match fn]} { - # save the filename in case the next thing is "new file mode ..." - set diffnexthead $fn - set diffnextnote "modified" - } elseif {[regexp {^new file mode ([0-7]+)} $line match m]} { - set diffnextnote "new file, mode $m" - } elseif {[string range $line 0 11] == "deleted file"} { - set diffnextnote "deleted" + set diffinhdr 1 + } elseif {[regexp {^(---|\+\+\+)} $line]} { + set diffinhdr 0 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \ $line match f1l f1c f2l f2c rest]} { $ctext insert end "\t" hunksep $ctext insert end " $f1l " d0 " $f2l " d1 $ctext insert end " $rest \n" hunksep + set diffinhdr 0 } else { set x [string range $line 0 0] if {$x == "-" || $x == "+"} { @@ -1861,7 +1842,7 @@ proc getblobdiffline {bdf ids} { } elseif {$x == " "} { set line [string range $line 1 end] $ctext insert end "$line\n" - } elseif {$x == "\\"} { + } elseif {$diffinhdr || $x == "\\"} { # e.g. "\ No newline at end of file" $ctext insert end "$line\n" filesep } else { @@ -1869,7 +1850,6 @@ proc getblobdiffline {bdf ids} { if {$curdifftag != "Comments"} { $ctext insert end "\n" $ctext tag add $curdifftag $curtagstart end - set seenfile($curdifftag) 1 set curtagstart [$ctext index "end - 1c"] set curdifftag Comments } From f3b8b3ce3ec672ac096bb1431ea7e609f4624f45 Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 18 Jul 2005 12:16:35 -0400 Subject: [PATCH 5/6] Allow short SHA1 IDs in the SHA1 entry field. --- gitk | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/gitk b/gitk index d994eec915..9e52a35791 100755 --- a/gitk +++ b/gitk @@ -1949,18 +1949,35 @@ proc sha1change {n1 n2 op} { proc gotocommit {} { global sha1string currentid idline tagids + global lineid numcommits + if {$sha1string == {} || ([info exists currentid] && $sha1string == $currentid)} return if {[info exists tagids($sha1string)]} { set id $tagids($sha1string) } else { set id [string tolower $sha1string] + if {[regexp {^[0-9a-f]{4,39}$} $id]} { + set matches {} + for {set l 0} {$l < $numcommits} {incr l} { + if {[string match $id* $lineid($l)]} { + lappend matches $lineid($l) + } + } + if {$matches ne {}} { + if {[llength $matches] > 1} { + error_popup "Short SHA1 id $id is ambiguous" + return + } + set id [lindex $matches 0] + } + } } if {[info exists idline($id)]} { selectline $idline($id) return } - if {[regexp {^[0-9a-fA-F]{40}$} $sha1string]} { + if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} { set type "SHA1 id" } else { set type "Tag" From f06548617ddb79d26108a5293c918efd60774f0d Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Mon, 18 Jul 2005 14:29:03 -0400 Subject: [PATCH 6/6] Make the diff display less gaudy. The old style is still available as an option (we still need a preferences window so we can set/clear it though). --- gitk | 46 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/gitk b/gitk index 9e52a35791..1de5ad9316 100755 --- a/gitk +++ b/gitk @@ -60,7 +60,7 @@ proc getcommitlines {commfd} { set stuff [read $commfd] if {$stuff == {}} { if {![eof $commfd]} return - # this works around what is apparently a bug in Tcl... + # set it blocking so we wait for the process to terminate fconfigure $commfd -blocking 1 if {![catch {close $commfd} err]} { after idle finishcommits @@ -273,7 +273,7 @@ proc makewindow {} { global findtype findtypemenu findloc findstring fstring geometry global entries sha1entry sha1string sha1but global maincursor textcursor - global rowctxmenu + global rowctxmenu gaudydiff menu .bar .bar add cascade -label "File" -menu .bar.file @@ -364,11 +364,17 @@ proc makewindow {} { pack $ctext -side left -fill both -expand 1 .ctop.cdet add .ctop.cdet.left - $ctext tag conf filesep -font [concat $textfont bold] - $ctext tag conf hunksep -back blue -fore white - $ctext tag conf d0 -back "#ff8080" - $ctext tag conf d1 -back green - $ctext tag conf found -back yellow + $ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa" + if {$gaudydiff} { + $ctext tag conf hunksep -back blue -fore white + $ctext tag conf d0 -back "#ff8080" + $ctext tag conf d1 -back green + } else { + $ctext tag conf hunksep -fore blue + $ctext tag conf d0 -fore red + $ctext tag conf d1 -fore "#00a000" + $ctext tag conf found -back yellow + } frame .ctop.cdet.right set cflist .ctop.cdet.right.cfiles @@ -465,8 +471,10 @@ proc savestuff {w} { if {![winfo viewable .]} return catch { set f [open "~/.gitk-new" w] - puts $f "set mainfont {$mainfont}" - puts $f "set textfont {$textfont}" + puts $f [list set mainfont $mainfont] + puts $f [list set textfont $textfont] + puts $f [list set findmergefiles $findmergefiles] + puts $f [list set gaudydiff $gaudydiff] puts $f "set geometry(width) [winfo width .ctop]" puts $f "set geometry(height) [winfo height .ctop]" puts $f "set geometry(canv1) [expr [winfo width $canv]-2]" @@ -1787,6 +1795,7 @@ proc getblobdiffline {bdf ids} { global diffids blobdifffd ctext curdifftag curtagstart global diffnexthead diffnextnote diffindex difffilestart global nextupdate diffpending diffpindex diffinhdr + global gaudydiff set n [gets $bdf line] if {$n < 0} { @@ -1829,18 +1838,26 @@ proc getblobdiffline {bdf ids} { set diffinhdr 0 } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \ $line match f1l f1c f2l f2c rest]} { - $ctext insert end "\t" hunksep - $ctext insert end " $f1l " d0 " $f2l " d1 - $ctext insert end " $rest \n" hunksep + if {$gaudydiff} { + $ctext insert end "\t" hunksep + $ctext insert end " $f1l " d0 " $f2l " d1 + $ctext insert end " $rest \n" hunksep + } else { + $ctext insert end "$line\n" hunksep + } set diffinhdr 0 } else { set x [string range $line 0 0] if {$x == "-" || $x == "+"} { set tag [expr {$x == "+"}] - set line [string range $line 1 end] + if {$gaudydiff} { + set line [string range $line 1 end] + } $ctext insert end "$line\n" d$tag } elseif {$x == " "} { - set line [string range $line 1 end] + if {$gaudydiff} { + set line [string range $line 1 end] + } $ctext insert end "$line\n" } elseif {$diffinhdr || $x == "\\"} { # e.g. "\ No newline at end of file" @@ -2379,6 +2396,7 @@ set wrcomcmd "git-diff-tree --stdin -p --pretty" set mainfont {Helvetica 9} set textfont {Courier 9} set findmergefiles 0 +set gaudydiff 0 set colors {green red blue magenta darkgrey brown orange}