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.
This commit is contained in:
Paul Mackerras 2005-07-16 21:53:55 -04:00
parent b74fd57966
commit 14c9dbd69b

178
gitk
View File

@ -1291,6 +1291,7 @@ proc findpatches {} {
global findstring selectedline numcommits global findstring selectedline numcommits
global findprocpid findprocfile global findprocpid findprocfile
global finddidsel ctext lineid findinprogress global finddidsel ctext lineid findinprogress
global findinsertpos
if {$numcommits == 0} return if {$numcommits == 0} return
@ -1317,6 +1318,7 @@ proc findpatches {} {
return return
} }
set findinsertpos end
set findprocfile $f set findprocfile $f
set findprocpid [pid $f] set findprocpid [pid $f]
fconfigure $f -blocking 0 fconfigure $f -blocking 0
@ -1329,7 +1331,7 @@ proc findpatches {} {
proc readfindproc {} { proc readfindproc {} {
global findprocfile finddidsel global findprocfile finddidsel
global idline matchinglines global idline matchinglines findinsertpos
set n [gets $findprocfile line] set n [gets $findprocfile line]
if {$n < 0} { if {$n < 0} {
@ -1351,7 +1353,24 @@ proc readfindproc {} {
return return
} }
set l $idline($id) set l $idline($id)
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 lappend matchinglines $l
}
} else {
set matchinglines [linsert $matchinglines $findinsertpos $l]
incr findinsertpos
}
markheadline $l $id
if {!$finddidsel} { if {!$finddidsel} {
findselectline $l findselectline $l
set finddidsel 1 set finddidsel 1
@ -1359,9 +1378,11 @@ proc readfindproc {} {
} }
proc findfiles {} { proc findfiles {} {
global selectedline numcommits lineid global selectedline numcommits lineid ctext
global ffileline finddidsel parents findstartline global ffileline finddidsel parents nparents
global findinprogress ctext global findinprogress findstartline findinsertpos
global treediffs fdiffids fdiffsneeded fdiffpos
global findmergefiles
if {$numcommits == 0} return if {$numcommits == 0} return
@ -1371,15 +1392,107 @@ proc findfiles {} {
set l 0 set l 0
} }
set ffileline $l set ffileline $l
set finddidsel 0
set findstartline $l 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 id $lineid($l)
set p [lindex $parents($id) 0] set p [lindex $parents($id) 0]
. config -cursor watch . config -cursor watch
$ctext config -cursor watch $ctext config -cursor watch
set findinprogress 1 set findinprogress 1
update
findcont [list $id $p] 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} { proc findcont {ids} {
@ -1397,9 +1510,6 @@ proc findcont {ids} {
if {![info exists treediffs($ids)]} { if {![info exists treediffs($ids)]} {
set findids $ids set findids $ids
set ffileline $l set ffileline $l
if {![info exists treepending]} {
gettreediffs $ids
}
return return
} }
set doesmatch 0 set doesmatch 0
@ -1411,12 +1521,7 @@ proc findcont {ids} {
} }
} }
if {$doesmatch} { if {$doesmatch} {
lappend matchinglines $l insertmatch $l $id
markheadline $l $id
if {!$finddidsel} {
findselectline $l
set finddidsel 1
}
set pi $nparents($id) set pi $nparents($id)
} }
} else { } else {
@ -1496,7 +1601,7 @@ proc selectline {l} {
global canv canv2 canv3 ctext commitinfo selectedline global canv canv2 canv3 ctext commitinfo selectedline
global lineid linehtag linentag linedtag global lineid linehtag linentag linedtag
global canvy0 linespc parents nparents global canvy0 linespc parents nparents
global cflist currentid sha1entry diffids global cflist currentid sha1entry
global commentend seenfile idtags global commentend seenfile idtags
$canv delete hover $canv delete hover
if {![info exists lineid($l)] || ![info exists linehtag($l)]} return if {![info exists lineid($l)] || ![info exists linehtag($l)]} return
@ -1550,7 +1655,6 @@ proc selectline {l} {
set id $lineid($l) set id $lineid($l)
set currentid $id set currentid $id
set diffids [concat $id $parents($id)]
$sha1entry delete 0 end $sha1entry delete 0 end
$sha1entry insert 0 $id $sha1entry insert 0 $id
$sha1entry selection from 0 $sha1entry selection from 0
@ -1581,20 +1685,21 @@ proc selectline {l} {
$cflist delete 0 end $cflist delete 0 end
$cflist insert end "Comments" $cflist insert end "Comments"
if {$nparents($id) == 1} { if {$nparents($id) == 1} {
startdiff startdiff [concat $id $parents($id)]
} }
catch {unset seenfile} catch {unset seenfile}
} }
proc startdiff {} { proc startdiff {ids} {
global treediffs diffids treepending global treediffs diffids treepending
if {![info exists treediffs($diffids)]} { if {![info exists treediffs($ids)]} {
set diffids $ids
if {![info exists treepending]} { if {![info exists treepending]} {
gettreediffs $diffids gettreediffs $ids
} }
} else { } else {
addtocflist $diffids addtocflist $ids
} }
} }
@ -1626,7 +1731,7 @@ proc gettreediffs {ids} {
} }
proc gettreediffline {gdtf ids} { proc gettreediffline {gdtf ids} {
global treediffs treepending diffids findids global treediffs treepending diffids
set n [gets $gdtf line] set n [gets $gdtf line]
if {$n < 0} { if {$n < 0} {
if {![eof $gdtf]} return if {![eof $gdtf]} return
@ -1636,18 +1741,10 @@ proc gettreediffline {gdtf ids} {
if {$ids != $diffids} { if {$ids != $diffids} {
gettreediffs $diffids gettreediffs $diffids
} else { } else {
unset diffids
addtocflist $ids addtocflist $ids
} }
} }
if {[info exists findids]} {
if {$ids != $findids} {
if {![info exists treepending]} {
gettreediffs $findids
}
} else {
findcont $ids
}
}
return return
} }
set file [lindex $line 5] set file [lindex $line 5]
@ -1655,7 +1752,7 @@ proc gettreediffline {gdtf ids} {
} }
proc getblobdiffs {ids} { proc getblobdiffs {ids} {
global diffopts blobdifffd env curdifftag curtagstart global diffopts blobdifffd blobdiffids env curdifftag curtagstart
global diffindex difffilestart nextupdate global diffindex difffilestart nextupdate
set id [lindex $ids 0] set id [lindex $ids 0]
@ -1666,6 +1763,7 @@ proc getblobdiffs {ids} {
return return
} }
fconfigure $bdf -blocking 0 fconfigure $bdf -blocking 0
set blobdiffids $ids
set blobdifffd($ids) $bdf set blobdifffd($ids) $bdf
set curdifftag Comments set curdifftag Comments
set curtagstart 0.0 set curtagstart 0.0
@ -1676,7 +1774,7 @@ proc getblobdiffs {ids} {
} }
proc getblobdiffline {bdf 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 diffnexthead diffnextnote diffindex difffilestart
global nextupdate global nextupdate
@ -1684,17 +1782,14 @@ proc getblobdiffline {bdf ids} {
if {$n < 0} { if {$n < 0} {
if {[eof $bdf]} { if {[eof $bdf]} {
close $bdf close $bdf
if {[info exists diffids] && $ids == $diffids if {$ids == $blobdiffids && $bdf == $blobdifffd($ids)} {
&& $bdf == $blobdifffd($ids)} {
$ctext tag add $curdifftag $curtagstart end $ctext tag add $curdifftag $curtagstart end
set seenfile($curdifftag) 1 set seenfile($curdifftag) 1
unset diffids
} }
} }
return return
} }
if {![info exists diffids] || $ids != $diffids if {$ids != $blobdiffids || $bdf != $blobdifffd($ids)} {
|| $bdf != $blobdifffd($ids)} {
return return
} }
$ctext conf -state normal $ctext conf -state normal
@ -2009,7 +2104,7 @@ proc rowmenu {x y id} {
proc diffvssel {dirn} { proc diffvssel {dirn} {
global rowmenuid selectedline lineid global rowmenuid selectedline lineid
global ctext cflist global ctext cflist
global diffids commitinfo global commitinfo
if {![info exists selectedline]} return if {![info exists selectedline]} return
if {$dirn} { if {$dirn} {
@ -2033,8 +2128,7 @@ proc diffvssel {dirn} {
$ctext conf -state disabled $ctext conf -state disabled
$ctext tag delete Comments $ctext tag delete Comments
$ctext tag remove found 1.0 end $ctext tag remove found 1.0 end
set diffids [list $newid $oldid] startdiff [list $newid $oldid]
startdiff
} }
proc mkpatch {} { proc mkpatch {} {