gitk: Implement a simple scheduler for the compute-intensive stuff

This allows us to do compute-intensive processing, such as laying out
the graph, relatively efficiently while also having the GUI be
reasonably responsive.  The problem previously was that file events
were serviced before X events, so reading from another process which
supplies data quickly (hi git rev-list :) could mean that X events
didn't get processed for a long time.

With this, gitk finishes laying out the graph slightly sooner and
still responds to the GUI while doing so.

Signed-off-by: Paul Mackerras <paulus@samba.org>
This commit is contained in:
Paul Mackerras 2007-06-17 14:45:00 +10:00
parent e507fd4871
commit 7eb3cb9c68

569
gitk
View File

@ -16,13 +16,75 @@ proc gitdir {} {
} }
} }
# A simple scheduler for compute-intensive stuff.
# The aim is to make sure that event handlers for GUI actions can
# run at least every 50-100 ms. Unfortunately fileevent handlers are
# run before X event handlers, so reading from a fast source can
# make the GUI completely unresponsive.
proc run args {
global isonrunq runq
set script $args
if {[info exists isonrunq($script)]} return
if {$runq eq {}} {
after idle dorunq
}
lappend runq [list {} $script]
set isonrunq($script) 1
}
proc filerun {fd script} {
fileevent $fd readable [list filereadable $fd $script]
}
proc filereadable {fd script} {
global runq
fileevent $fd readable {}
if {$runq eq {}} {
after idle dorunq
}
lappend runq [list $fd $script]
}
proc dorunq {} {
global isonrunq runq
set tstart [clock clicks -milliseconds]
set t0 $tstart
while {$runq ne {}} {
set fd [lindex $runq 0 0]
set script [lindex $runq 0 1]
set repeat [eval $script]
set t1 [clock clicks -milliseconds]
set t [expr {$t1 - $t0}]
set runq [lrange $runq 1 end]
if {$repeat ne {} && $repeat} {
if {$fd eq {} || $repeat == 2} {
# script returns 1 if it wants to be readded
# file readers return 2 if they could do more straight away
lappend runq [list $fd $script]
} else {
fileevent $fd readable [list filereadable $fd $script]
}
} elseif {$fd eq {}} {
unset isonrunq($script)
}
set t0 $t1
if {$t1 - $tstart >= 80} break
}
if {$runq ne {}} {
after idle dorunq
}
}
# Start off a git rev-list process and arrange to read its output
proc start_rev_list {view} { proc start_rev_list {view} {
global startmsecs nextupdate global startmsecs
global commfd leftover tclencoding datemode global commfd leftover tclencoding datemode
global viewargs viewfiles commitidx global viewargs viewfiles commitidx
set startmsecs [clock clicks -milliseconds] set startmsecs [clock clicks -milliseconds]
set nextupdate [expr {$startmsecs + 100}]
set commitidx($view) 0 set commitidx($view) 0
set args $viewargs($view) set args $viewargs($view)
if {$viewfiles($view) ne {}} { if {$viewfiles($view) ne {}} {
@ -45,7 +107,7 @@ proc start_rev_list {view} {
if {$tclencoding != {}} { if {$tclencoding != {}} {
fconfigure $fd -encoding $tclencoding fconfigure $fd -encoding $tclencoding
} }
fileevent $fd readable [list getcommitlines $fd $view] filerun $fd [list getcommitlines $fd $view]
nowbusy $view nowbusy $view
} }
@ -72,7 +134,7 @@ proc getcommits {} {
} }
proc getcommitlines {fd view} { proc getcommitlines {fd view} {
global commitlisted nextupdate global commitlisted
global leftover commfd global leftover commfd
global displayorder commitidx commitrow commitdata global displayorder commitidx commitrow commitdata
global parentlist childlist children curview hlview global parentlist childlist children curview hlview
@ -80,7 +142,9 @@ proc getcommitlines {fd view} {
set stuff [read $fd 500000] set stuff [read $fd 500000]
if {$stuff == {}} { if {$stuff == {}} {
if {![eof $fd]} return if {![eof $fd]} {
return 1
}
global viewname global viewname
unset commfd($view) unset commfd($view)
notbusy $view notbusy $view
@ -105,9 +169,9 @@ proc getcommitlines {fd view} {
error_popup $err error_popup $err
} }
if {$view == $curview} { if {$view == $curview} {
after idle finishcommits run chewcommits $view
} }
return return 0
} }
set start 0 set start 0
set gotsome 0 set gotsome 0
@ -183,29 +247,42 @@ proc getcommitlines {fd view} {
set gotsome 1 set gotsome 1
} }
if {$gotsome} { if {$gotsome} {
if {$view == $curview} { run chewcommits $view
while {[layoutmore $nextupdate]} doupdate
} elseif {[info exists hlview] && $view == $hlview} {
vhighlightmore
}
}
if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate
} }
return 2
} }
proc doupdate {} { proc chewcommits {view} {
global commfd nextupdate numcommits global curview hlview commfd
global selectedline pending_select
foreach v [array names commfd] { set more 0
fileevent $commfd($v) readable {} if {$view == $curview} {
set allread [expr {![info exists commfd($view)]}]
set tlimit [expr {[clock clicks -milliseconds] + 50}]
set more [layoutmore $tlimit $allread]
if {$allread && !$more} {
global displayorder commitidx phase
global numcommits startmsecs
if {[info exists pending_select]} {
set row [expr {[lindex $displayorder 0] eq $nullid}]
selectline $row 1
}
if {$commitidx($curview) > 0} {
#set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
#puts "overall $ms ms for $numcommits commits"
} else {
show_status "No commits selected"
}
notbusy layout
set phase {}
}
} }
update if {[info exists hlview] && $view == $hlview} {
set nextupdate [expr {[clock clicks -milliseconds] + 100}] vhighlightmore
foreach v [array names commfd] {
set fd $commfd($v)
fileevent $fd readable [list getcommitlines $fd $v]
} }
return $more
} }
proc readcommit {id} { proc readcommit {id} {
@ -1594,9 +1671,9 @@ proc newviewok {top n} {
set viewargs($n) $newargs set viewargs($n) $newargs
addviewmenu $n addviewmenu $n
if {!$newishighlight} { if {!$newishighlight} {
after idle showview $n run showview $n
} else { } else {
after idle addvhighlight $n run addvhighlight $n
} }
} else { } else {
# editing an existing view # editing an existing view
@ -1612,7 +1689,7 @@ proc newviewok {top n} {
set viewfiles($n) $files set viewfiles($n) $files
set viewargs($n) $newargs set viewargs($n) $newargs
if {$curview == $n} { if {$curview == $n} {
after idle updatecommits run updatecommits
} }
} }
} }
@ -1670,7 +1747,7 @@ proc showview {n} {
global matchinglines treediffs global matchinglines treediffs
global pending_select phase global pending_select phase
global commitidx rowlaidout rowoptim linesegends global commitidx rowlaidout rowoptim linesegends
global commfd nextupdate global commfd
global selectedview selectfirst global selectedview selectfirst
global vparentlist vchildlist vdisporder vcmitlisted global vparentlist vchildlist vdisporder vcmitlisted
global hlview selectedhlview global hlview selectedhlview
@ -1791,11 +1868,7 @@ proc showview {n} {
if {$phase eq "getcommits"} { if {$phase eq "getcommits"} {
show_status "Reading commits..." show_status "Reading commits..."
} }
if {[info exists commfd($n)]} { run chewcommits $n
layoutmore {}
} else {
finishcommits
}
} elseif {$numcommits == 0} { } elseif {$numcommits == 0} {
show_status "No commits selected" show_status "No commits selected"
} }
@ -1983,7 +2056,7 @@ proc do_file_hl {serial} {
set cmd [concat | git diff-tree -r -s --stdin $gdtargs] set cmd [concat | git diff-tree -r -s --stdin $gdtargs]
set filehighlight [open $cmd r+] set filehighlight [open $cmd r+]
fconfigure $filehighlight -blocking 0 fconfigure $filehighlight -blocking 0
fileevent $filehighlight readable readfhighlight filerun $filehighlight readfhighlight
set fhl_list {} set fhl_list {}
drawvisible drawvisible
flushhighlights flushhighlights
@ -2011,7 +2084,11 @@ proc readfhighlight {} {
global filehighlight fhighlights commitrow curview mainfont iddrawn global filehighlight fhighlights commitrow curview mainfont iddrawn
global fhl_list global fhl_list
while {[gets $filehighlight line] >= 0} { if {![info exists filehighlight]} {
return 0
}
set nr 0
while {[incr nr] <= 100 && [gets $filehighlight line] >= 0} {
set line [string trim $line] set line [string trim $line]
set i [lsearch -exact $fhl_list $line] set i [lsearch -exact $fhl_list $line]
if {$i < 0} continue if {$i < 0} continue
@ -2035,8 +2112,10 @@ proc readfhighlight {} {
puts "oops, git diff-tree died" puts "oops, git diff-tree died"
catch {close $filehighlight} catch {close $filehighlight}
unset filehighlight unset filehighlight
return 0
} }
next_hlcont next_hlcont
return 1
} }
proc find_change {name ix op} { proc find_change {name ix op} {
@ -2103,7 +2182,7 @@ proc vrel_change {name ix op} {
rhighlight_none rhighlight_none
if {$highlight_related ne "None"} { if {$highlight_related ne "None"} {
after idle drawvisible run drawvisible
} }
} }
@ -2118,7 +2197,7 @@ proc rhighlight_sel {a} {
set anc_todo [list $a] set anc_todo [list $a]
if {$highlight_related ne "None"} { if {$highlight_related ne "None"} {
rhighlight_none rhighlight_none
after idle drawvisible run drawvisible
} }
} }
@ -2474,15 +2553,17 @@ proc visiblerows {} {
return [list $r0 $r1] return [list $r0 $r1]
} }
proc layoutmore {tmax} { proc layoutmore {tmax allread} {
global rowlaidout rowoptim commitidx numcommits optim_delay global rowlaidout rowoptim commitidx numcommits optim_delay
global uparrowlen curview global uparrowlen curview rowidlist idinlist
set showdelay $optim_delay
set optdelay [expr {$uparrowlen + 1}]
while {1} { while {1} {
if {$rowoptim - $optim_delay > $numcommits} { if {$rowoptim - $showdelay > $numcommits} {
showstuff [expr {$rowoptim - $optim_delay}] showstuff [expr {$rowoptim - $showdelay}]
} elseif {$rowlaidout - $uparrowlen - 1 > $rowoptim} { } elseif {$rowlaidout - $optdelay > $rowoptim} {
set nr [expr {$rowlaidout - $uparrowlen - 1 - $rowoptim}] set nr [expr {$rowlaidout - $optdelay - $rowoptim}]
if {$nr > 100} { if {$nr > 100} {
set nr 100 set nr 100
} }
@ -2496,10 +2577,23 @@ proc layoutmore {tmax} {
set nr 150 set nr 150
} }
set row $rowlaidout set row $rowlaidout
set rowlaidout [layoutrows $row [expr {$row + $nr}] 0] set rowlaidout [layoutrows $row [expr {$row + $nr}] $allread]
if {$rowlaidout == $row} { if {$rowlaidout == $row} {
return 0 return 0
} }
} elseif {$allread} {
set optdelay 0
set nrows $commitidx($curview)
if {[lindex $rowidlist $nrows] ne {} ||
[array names idinlist] ne {}} {
layouttail
set rowlaidout $commitidx($curview)
} elseif {$rowoptim == $nrows} {
set showdelay 0
if {$numcommits == $nrows} {
return 0
}
}
} else { } else {
return 0 return 0
} }
@ -2715,6 +2809,7 @@ proc layouttail {} {
} }
foreach id [array names idinlist] { foreach id [array names idinlist] {
unset idinlist($id)
addextraid $id $row addextraid $id $row
lset rowidlist $row [list $id] lset rowidlist $row [list $id]
lset rowoffsets $row 0 lset rowoffsets $row 0
@ -3423,19 +3518,6 @@ proc show_status {msg} {
-tags text -fill $fgcolor -tags text -fill $fgcolor
} }
proc finishcommits {} {
global commitidx phase curview
global pending_select
if {$commitidx($curview) > 0} {
drawrest
} else {
show_status "No commits selected"
}
set phase {}
catch {unset pending_select}
}
# Insert a new commit as the child of the commit on row $row. # Insert a new commit as the child of the commit on row $row.
# The new commit will be displayed on row $row and the commits # The new commit will be displayed on row $row and the commits
# on that row and below will move down one row. # on that row and below will move down one row.
@ -3569,24 +3651,6 @@ proc notbusy {what} {
} }
} }
proc drawrest {} {
global startmsecs
global rowlaidout commitidx curview
global pending_select
layoutrows $rowlaidout $commitidx($curview) 1
layouttail
optimize_rows $row 0 $commitidx($curview)
showstuff $commitidx($curview)
if {[info exists pending_select]} {
selectline 0 1
}
set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
#global numcommits
#puts "overall $drawmsecs ms for $numcommits commits"
}
proc findmatches {f} { proc findmatches {f} {
global findtype foundstring foundstrlen global findtype foundstring foundstrlen
if {$findtype == "Regexp"} { if {$findtype == "Regexp"} {
@ -4243,7 +4307,7 @@ proc gettree {id} {
set treefilelist($id) {} set treefilelist($id) {}
set treeidlist($id) {} set treeidlist($id) {}
fconfigure $gtf -blocking 0 fconfigure $gtf -blocking 0
fileevent $gtf readable [list gettreeline $gtf $id] filerun $gtf [list gettreeline $gtf $id]
} }
} else { } else {
setfilelist $id setfilelist $id
@ -4253,14 +4317,21 @@ proc gettree {id} {
proc gettreeline {gtf id} { proc gettreeline {gtf id} {
global treefilelist treeidlist treepending cmitmode diffids global treefilelist treeidlist treepending cmitmode diffids
while {[gets $gtf line] >= 0} { set nl 0
if {[lindex $line 1] ne "blob"} continue while {[incr nl] <= 1000 && [gets $gtf line] >= 0} {
set sha1 [lindex $line 2] set tl [split $line "\t"]
set fname [lindex $line 3] if {[lindex $tl 0 1] ne "blob"} continue
lappend treefilelist($id) $fname set sha1 [lindex $tl 0 2]
set fname [lindex $tl 1]
if {[string index $fname 0] eq "\""} {
set fname [lindex $fname 0]
}
lappend treeidlist($id) $sha1 lappend treeidlist($id) $sha1
lappend treefilelist($id) $fname
}
if {![eof $gtf]} {
return [expr {$nl >= 1000? 2: 1}]
} }
if {![eof $gtf]} return
close $gtf close $gtf
unset treepending unset treepending
if {$cmitmode ne "tree"} { if {$cmitmode ne "tree"} {
@ -4272,6 +4343,7 @@ proc gettreeline {gtf id} {
} else { } else {
setfilelist $id setfilelist $id
} }
return 0
} }
proc showfile {f} { proc showfile {f} {
@ -4289,7 +4361,7 @@ proc showfile {f} {
return return
} }
fconfigure $bf -blocking 0 fconfigure $bf -blocking 0
fileevent $bf readable [list getblobline $bf $diffids] filerun $bf [list getblobline $bf $diffids]
$ctext config -state normal $ctext config -state normal
clear_ctext $commentend clear_ctext $commentend
$ctext insert end "\n" $ctext insert end "\n"
@ -4303,18 +4375,21 @@ proc getblobline {bf id} {
if {$id ne $diffids || $cmitmode ne "tree"} { if {$id ne $diffids || $cmitmode ne "tree"} {
catch {close $bf} catch {close $bf}
return return 0
} }
$ctext config -state normal $ctext config -state normal
while {[gets $bf line] >= 0} { set nl 0
while {[incr nl] <= 1000 && [gets $bf line] >= 0} {
$ctext insert end "$line\n" $ctext insert end "$line\n"
} }
if {[eof $bf]} { if {[eof $bf]} {
# delete last newline # delete last newline
$ctext delete "end - 2c" "end - 1c" $ctext delete "end - 2c" "end - 1c"
close $bf close $bf
return 0
} }
$ctext config -state disabled $ctext config -state disabled
return [expr {$nl >= 1000? 2: 1}]
} }
proc mergediff {id l} { proc mergediff {id l} {
@ -4334,83 +4409,78 @@ proc mergediff {id l} {
fconfigure $mdf -blocking 0 fconfigure $mdf -blocking 0
set mdifffd($id) $mdf set mdifffd($id) $mdf
set np [llength [lindex $parentlist $l]] set np [llength [lindex $parentlist $l]]
fileevent $mdf readable [list getmergediffline $mdf $id $np] filerun $mdf [list getmergediffline $mdf $id $np]
set nextupdate [expr {[clock clicks -milliseconds] + 100}]
} }
proc getmergediffline {mdf id np} { proc getmergediffline {mdf id np} {
global diffmergeid ctext cflist nextupdate mergemax global diffmergeid ctext cflist mergemax
global difffilestart mdifffd global difffilestart mdifffd
set n [gets $mdf line]
if {$n < 0} {
if {[eof $mdf]} {
close $mdf
}
return
}
if {![info exists diffmergeid] || $id != $diffmergeid
|| $mdf != $mdifffd($id)} {
return
}
$ctext conf -state normal $ctext conf -state normal
if {[regexp {^diff --cc (.*)} $line match fname]} { set nr 0
# start of a new file while {[incr nr] <= 1000 && [gets $mdf line] >= 0} {
$ctext insert end "\n" if {![info exists diffmergeid] || $id != $diffmergeid
set here [$ctext index "end - 1c"] || $mdf != $mdifffd($id)} {
lappend difffilestart $here close $mdf
add_flist [list $fname] return 0
set l [expr {(78 - [string length $fname]) / 2}] }
set pad [string range "----------------------------------------" 1 $l] if {[regexp {^diff --cc (.*)} $line match fname]} {
$ctext insert end "$pad $fname $pad\n" filesep # start of a new file
} elseif {[regexp {^@@} $line]} { $ctext insert end "\n"
$ctext insert end "$line\n" hunksep set here [$ctext index "end - 1c"]
} elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} { lappend difffilestart $here
# do nothing add_flist [list $fname]
} else { set l [expr {(78 - [string length $fname]) / 2}]
# parse the prefix - one ' ', '-' or '+' for each parent set pad [string range "----------------------------------------" 1 $l]
set spaces {} $ctext insert end "$pad $fname $pad\n" filesep
set minuses {} } elseif {[regexp {^@@} $line]} {
set pluses {} $ctext insert end "$line\n" hunksep
set isbad 0 } elseif {[regexp {^[0-9a-f]{40}$} $line] || [regexp {^index} $line]} {
for {set j 0} {$j < $np} {incr j} { # do nothing
set c [string range $line $j $j] } else {
if {$c == " "} { # parse the prefix - one ' ', '-' or '+' for each parent
lappend spaces $j set spaces {}
} elseif {$c == "-"} { set minuses {}
lappend minuses $j set pluses {}
} elseif {$c == "+"} { set isbad 0
lappend pluses $j for {set j 0} {$j < $np} {incr j} {
} else { set c [string range $line $j $j]
set isbad 1 if {$c == " "} {
break lappend spaces $j
} elseif {$c == "-"} {
lappend minuses $j
} elseif {$c == "+"} {
lappend pluses $j
} else {
set isbad 1
break
}
} }
} set tags {}
set tags {} set num {}
set num {} if {!$isbad && $minuses ne {} && $pluses eq {}} {
if {!$isbad && $minuses ne {} && $pluses eq {}} { # line doesn't appear in result, parents in $minuses have the line
# line doesn't appear in result, parents in $minuses have the line set num [lindex $minuses 0]
set num [lindex $minuses 0] } elseif {!$isbad && $pluses ne {} && $minuses eq {}} {
} elseif {!$isbad && $pluses ne {} && $minuses eq {}} { # line appears in result, parents in $pluses don't have the line
# line appears in result, parents in $pluses don't have the line lappend tags mresult
lappend tags mresult set num [lindex $spaces 0]
set num [lindex $spaces 0]
}
if {$num ne {}} {
if {$num >= $mergemax} {
set num "max"
} }
lappend tags m$num if {$num ne {}} {
if {$num >= $mergemax} {
set num "max"
}
lappend tags m$num
}
$ctext insert end "$line\n" $tags
} }
$ctext insert end "$line\n" $tags
} }
$ctext conf -state disabled $ctext conf -state disabled
if {[clock clicks -milliseconds] >= $nextupdate} { if {[eof $mdf]} {
incr nextupdate 100 close $mdf
fileevent $mdf readable {} return 0
update
fileevent $mdf readable [list getmergediffline $mdf $id $np]
} }
return [expr {$nr >= 1000? 2: 1}]
} }
proc startdiff {ids} { proc startdiff {ids} {
@ -4441,37 +4511,39 @@ proc gettreediffs {ids} {
{set gdtf [open [concat | git diff-tree --no-commit-id -r $ids] r]} \ {set gdtf [open [concat | git diff-tree --no-commit-id -r $ids] r]} \
]} return ]} return
fconfigure $gdtf -blocking 0 fconfigure $gdtf -blocking 0
fileevent $gdtf readable [list gettreediffline $gdtf $ids] filerun $gdtf [list gettreediffline $gdtf $ids]
} }
proc gettreediffline {gdtf ids} { proc gettreediffline {gdtf ids} {
global treediff treediffs treepending diffids diffmergeid global treediff treediffs treepending diffids diffmergeid
global cmitmode global cmitmode
set n [gets $gdtf line] set nr 0
if {$n < 0} { while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
if {![eof $gdtf]} return set file [lindex $line 5]
close $gdtf lappend treediff $file
set treediffs($ids) $treediff
unset treepending
if {$cmitmode eq "tree"} {
gettree $diffids
} elseif {$ids != $diffids} {
if {![info exists diffmergeid]} {
gettreediffs $diffids
}
} else {
addtocflist $ids
}
return
} }
set file [lindex $line 5] if {![eof $gdtf]} {
lappend treediff $file return [expr {$nr >= 1000? 2: 1}]
}
close $gdtf
set treediffs($ids) $treediff
unset treepending
if {$cmitmode eq "tree"} {
gettree $diffids
} elseif {$ids != $diffids} {
if {![info exists diffmergeid]} {
gettreediffs $diffids
}
} else {
addtocflist $ids
}
return 0
} }
proc getblobdiffs {ids} { proc getblobdiffs {ids} {
global diffopts blobdifffd diffids env curdifftag curtagstart global diffopts blobdifffd diffids env curdifftag curtagstart
global nextupdate diffinhdr treediffs global diffinhdr treediffs
set env(GIT_DIFF_OPTS) $diffopts set env(GIT_DIFF_OPTS) $diffopts
set cmd [concat | git diff-tree --no-commit-id -r -p -C $ids] set cmd [concat | git diff-tree --no-commit-id -r -p -C $ids]
@ -4484,8 +4556,7 @@ proc getblobdiffs {ids} {
set blobdifffd($ids) $bdf set blobdifffd($ids) $bdf
set curdifftag Comments set curdifftag Comments
set curtagstart 0.0 set curtagstart 0.0
fileevent $bdf readable [list getblobdiffline $bdf $diffids] filerun $bdf [list getblobdiffline $bdf $diffids]
set nextupdate [expr {[clock clicks -milliseconds] + 100}]
} }
proc setinlist {var i val} { proc setinlist {var i val} {
@ -4504,81 +4575,78 @@ proc setinlist {var i val} {
proc getblobdiffline {bdf ids} { proc getblobdiffline {bdf ids} {
global diffids blobdifffd ctext curdifftag curtagstart global diffids blobdifffd ctext curdifftag curtagstart
global diffnexthead diffnextnote difffilestart global diffnexthead diffnextnote difffilestart
global nextupdate diffinhdr treediffs global diffinhdr treediffs
set n [gets $bdf line] set nr 0
if {$n < 0} {
if {[eof $bdf]} {
close $bdf
if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
$ctext tag add $curdifftag $curtagstart end
}
}
return
}
if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
return
}
$ctext conf -state normal $ctext conf -state normal
if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} { while {[incr nr] <= 1000 && [gets $bdf line] >= 0} {
# start of a new file if {$ids != $diffids || $bdf != $blobdifffd($ids)} {
$ctext insert end "\n" close $bdf
$ctext tag add $curdifftag $curtagstart end return 0
set here [$ctext index "end - 1c"]
set curtagstart $here
set header $newname
set i [lsearch -exact $treediffs($ids) $fname]
if {$i >= 0} {
setinlist difffilestart $i $here
} }
if {$newname ne $fname} { if {[regexp {^diff --git a/(.*) b/(.*)} $line match fname newname]} {
set i [lsearch -exact $treediffs($ids) $newname] # start of a new file
$ctext insert end "\n"
$ctext tag add $curdifftag $curtagstart end
set here [$ctext index "end - 1c"]
set curtagstart $here
set header $newname
set i [lsearch -exact $treediffs($ids) $fname]
if {$i >= 0} { if {$i >= 0} {
setinlist difffilestart $i $here setinlist difffilestart $i $here
} }
} if {$newname ne $fname} {
set curdifftag "f:$fname" set i [lsearch -exact $treediffs($ids) $newname]
$ctext tag delete $curdifftag if {$i >= 0} {
set l [expr {(78 - [string length $header]) / 2}] setinlist difffilestart $i $here
set pad [string range "----------------------------------------" 1 $l] }
$ctext insert end "$pad $header $pad\n" filesep }
set diffinhdr 1 set curdifftag "f:$fname"
} elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} { $ctext tag delete $curdifftag
# do nothing set l [expr {(78 - [string length $header]) / 2}]
} elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} { set pad [string range "----------------------------------------" \
set diffinhdr 0 1 $l]
} elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \ $ctext insert end "$pad $header $pad\n" filesep
$line match f1l f1c f2l f2c rest]} { set diffinhdr 1
$ctext insert end "$line\n" hunksep } elseif {$diffinhdr && [string compare -length 3 $line "---"] == 0} {
set diffinhdr 0 # do nothing
} else { } elseif {$diffinhdr && [string compare -length 3 $line "+++"] == 0} {
set x [string range $line 0 0] set diffinhdr 0
if {$x == "-" || $x == "+"} { } elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
set tag [expr {$x == "+"}] $line match f1l f1c f2l f2c rest]} {
$ctext insert end "$line\n" d$tag $ctext insert end "$line\n" hunksep
} elseif {$x == " "} { set diffinhdr 0
$ctext insert end "$line\n" } else {
} elseif {$diffinhdr || $x == "\\"} { set x [string range $line 0 0]
# e.g. "\ No newline at end of file" if {$x == "-" || $x == "+"} {
$ctext insert end "$line\n" filesep set tag [expr {$x == "+"}]
} else { $ctext insert end "$line\n" d$tag
# Something else we don't recognize } elseif {$x == " "} {
if {$curdifftag != "Comments"} { $ctext insert end "$line\n"
$ctext insert end "\n" } elseif {$diffinhdr || $x == "\\"} {
$ctext tag add $curdifftag $curtagstart end # e.g. "\ No newline at end of file"
set curtagstart [$ctext index "end - 1c"] $ctext insert end "$line\n" filesep
set curdifftag Comments } else {
# Something else we don't recognize
if {$curdifftag != "Comments"} {
$ctext insert end "\n"
$ctext tag add $curdifftag $curtagstart end
set curtagstart [$ctext index "end - 1c"]
set curdifftag Comments
}
$ctext insert end "$line\n" filesep
} }
$ctext insert end "$line\n" filesep
} }
} }
$ctext conf -state disabled $ctext conf -state disabled
if {[clock clicks -milliseconds] >= $nextupdate} { if {[eof $bdf]} {
incr nextupdate 100 close $bdf
fileevent $bdf readable {} if {$ids == $diffids && $bdf == $blobdifffd($ids)} {
update $ctext tag add $curdifftag $curtagstart end
fileevent $bdf readable "getblobdiffline $bdf {$ids}" }
return 0
} }
return [expr {$nr >= 1000? 2: 1}]
} }
proc changediffdisp {} { proc changediffdisp {} {
@ -5509,11 +5577,7 @@ proc regetallcommits {} {
fconfigure $fd -blocking 0 fconfigure $fd -blocking 0
incr allcommits incr allcommits
nowbusy allcommits nowbusy allcommits
restartgetall $fd filerun $fd [list getallclines $fd]
}
proc restartgetall {fd} {
fileevent $fd readable [list getallclines $fd]
} }
# Since most commits have 1 parent and 1 child, we group strings of # Since most commits have 1 parent and 1 child, we group strings of
@ -5534,13 +5598,10 @@ proc restartgetall {fd} {
proc getallclines {fd} { proc getallclines {fd} {
global allids allparents allchildren idtags nextarc nbmp global allids allparents allchildren idtags nextarc nbmp
global arcnos arcids arctags arcout arcend arcstart archeads growing global arcnos arcids arctags arcout arcend arcstart archeads growing
global seeds allcommits allcstart global seeds allcommits
if {![info exists allcstart]} {
set allcstart [clock clicks -milliseconds]
}
set nid 0 set nid 0
while {[gets $fd line] >= 0} { while {[incr nid] <= 1000 && [gets $fd line] >= 0} {
set id [lindex $line 0] set id [lindex $line 0]
if {[info exists allparents($id)]} { if {[info exists allparents($id)]} {
# seen it already # seen it already
@ -5607,22 +5668,16 @@ proc getallclines {fd} {
lappend arcnos($p) $a lappend arcnos($p) $a
} }
set arcout($id) $ao set arcout($id) $ao
if {[incr nid] >= 50} {
set nid 0
if {[clock clicks -milliseconds] - $allcstart >= 50} {
fileevent $fd readable {}
after idle restartgetall $fd
unset allcstart
return
}
}
} }
if {![eof $fd]} return if {![eof $fd]} {
return [expr {$nid >= 1000? 2: 1}]
}
close $fd close $fd
if {[incr allcommits -1] == 0} { if {[incr allcommits -1] == 0} {
notbusy allcommits notbusy allcommits
} }
dispneartags 0 dispneartags 0
return 0
} }
proc recalcarc {a} { proc recalcarc {a} {
@ -5919,6 +5974,7 @@ proc is_certain {desc anc} {
if {$dl($x)} { if {$dl($x)} {
return 0 return 0
} }
return 0
} }
return 1 return 1
} }
@ -6948,6 +7004,7 @@ if {$i >= 0} {
} }
} }
set runq {}
set history {} set history {}
set historyindex 0 set historyindex 0
set fh_serial 0 set fh_serial 0