Browse Source

Use git-rev-list --header.

With --header, git-rev-list gives us the contents of the commit
in-line, so we don't need to exec a git-cat-file to get it, and we
don't need the readobj command either.
Also fixed a residual problem with handling the commit that
has a parent listed twice.
maint
Paul Mackerras 20 years ago
parent
commit
b490a99176
  1. 188
      gitk

188
gitk

@ -12,30 +12,31 @@ exec wish "$0" -- "${1+$@}"
proc getcommits {rargs} { proc getcommits {rargs} {
global commits commfd phase canv mainfont global commits commfd phase canv mainfont
global startmsecs nextupdate global startmsecs nextupdate
global ctext maincursor textcursor nlines global ctext maincursor textcursor leftover


set commits {} set commits {}
set phase getcommits set phase getcommits
set startmsecs [clock clicks -milliseconds] set startmsecs [clock clicks -milliseconds]
set nextupdate [expr $startmsecs + 100] set nextupdate [expr $startmsecs + 100]
if [catch { if [catch {
set parse_args [concat --default HEAD --merge-order $rargs] set parse_args [concat --default HEAD $rargs]
set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"] set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
}] { }] {
# if git-rev-parse failed for some reason...
if {$rargs == {}} { if {$rargs == {}} {
set rargs HEAD set rargs HEAD
} }
set parsed_args [concat --merge-order $rargs] set parsed_args $rargs
} }
if [catch { if [catch {
set commfd [open "|git-rev-list $parsed_args" r] set commfd [open "|git-rev-list --header --merge-order $parsed_args" r]
} err] { } err] {
puts stderr "Error executing git-rev-list: $err" puts stderr "Error executing git-rev-list: $err"
exit 1 exit 1
} }
set nlines 0 set leftover {}
fconfigure $commfd -blocking 0 fconfigure $commfd -blocking 0 -translation binary
fileevent $commfd readable "getcommitline $commfd" fileevent $commfd readable "getcommitlines $commfd"
$canv delete all $canv delete all
$canv create text 3 3 -anchor nw -text "Reading commits..." \ $canv create text 3 3 -anchor nw -text "Reading commits..." \
-font $mainfont -tags textitems -font $mainfont -tags textitems
@ -43,13 +44,13 @@ proc getcommits {rargs} {
$ctext config -cursor watch $ctext config -cursor watch
} }


proc getcommitline {commfd} { proc getcommitlines {commfd} {
global commits parents cdate children nchildren global commits parents cdate children nchildren
global commitlisted phase commitinfo nextupdate global commitlisted phase commitinfo nextupdate
global stopped redisplaying nlines global stopped redisplaying leftover


set n [gets $commfd line] set stuff [read $commfd]
if {$n < 0} { if {$stuff == {}} {
if {![eof $commfd]} return if {![eof $commfd]} return
# this works around what is apparently a bug in Tcl... # this works around what is apparently a bug in Tcl...
fconfigure $commfd -blocking 1 fconfigure $commfd -blocking 1
@ -68,35 +69,41 @@ to allow selection of commits to be displayed.)}
error_popup $err error_popup $err
exit 1 exit 1
} }
incr nlines set start 0
if {![regexp {^[0-9a-f]{40}$} $line id]} { while 1 {
error_popup "Can't parse git-rev-list output: {$line}" set i [string first "\0" $stuff $start]
exit 1 if {$i < 0} {
} set leftover [string range $stuff $start end]
lappend commits $id return
set commitlisted($id) 1
if {![info exists commitinfo($id)]} {
readcommit $id
}
foreach p $parents($id) {
if {[info exists commitlisted($p)]} {
puts "oops, parent $p before child $id"
} }
} set cmit [string range $stuff $start [expr {$i - 1}]]
drawcommit $id if {$start == 0} {
if {[clock clicks -milliseconds] >= $nextupdate} { set cmit "$leftover$cmit"
doupdate }
} set start [expr {$i + 1}]
while {$redisplaying} { if {![regexp {^([0-9a-f]{40})\n} $cmit match id]} {
set redisplaying 0 error_popup "Can't parse git-rev-list output: {$cmit}"
if {$stopped == 1} { exit 1
set stopped 0 }
set phase "getcommits" set cmit [string range $cmit 41 end]
foreach id $commits { lappend commits $id
drawcommit $id set commitlisted($id) 1
if {$stopped} break parsecommit $id $cmit 1
if {[clock clicks -milliseconds] >= $nextupdate} { drawcommit $id
doupdate if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate
}
while {$redisplaying} {
set redisplaying 0
if {$stopped == 1} {
set stopped 0
set phase "getcommits"
foreach id $commits {
drawcommit $id
if {$stopped} break
if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate
}
} }
} }
} }
@ -109,12 +116,16 @@ proc doupdate {} {
incr nextupdate 100 incr nextupdate 100
fileevent $commfd readable {} fileevent $commfd readable {}
update update
fileevent $commfd readable "getcommitline $commfd" fileevent $commfd readable "getcommitlines $commfd"
} }


proc readcommit {id} { proc readcommit {id} {
if [catch {set contents [exec git-cat-file commit $id]}] return
parsecommit $id $contents 0
}

proc parsecommit {id contents listed} {
global commitinfo children nchildren parents nparents cdate ncleft global commitinfo children nchildren parents nparents cdate ncleft
global noreadobj


set inhdr 1 set inhdr 1
set comment {} set comment {}
@ -130,13 +141,6 @@ proc readcommit {id} {
} }
set parents($id) {} set parents($id) {}
set nparents($id) 0 set nparents($id) 0
if {$noreadobj} {
if [catch {set contents [exec git-cat-file commit $id]}] return
} else {
if [catch {set x [readobj $id]}] return
if {[lindex $x 0] != "commit"} return
set contents [lindex $x 1]
}
foreach line [split $contents "\n"] { foreach line [split $contents "\n"] {
if {$inhdr} { if {$inhdr} {
if {$line == {}} { if {$line == {}} {
@ -153,7 +157,7 @@ proc readcommit {id} {
lappend parents($id) $p lappend parents($id) $p
incr nparents($id) incr nparents($id)
# sometimes we get a commit that lists a parent twice... # sometimes we get a commit that lists a parent twice...
if {[lsearch -exact $children($p) $id] < 0} { if {$listed && [lsearch -exact $children($p) $id] < 0} {
lappend children($p) $id lappend children($p) $id
incr nchildren($p) incr nchildren($p)
incr ncleft($p) incr ncleft($p)
@ -545,7 +549,7 @@ proc assigncolor {id} {
global parents nparents children nchildren global parents nparents children nchildren
if [info exists colormap($id)] return if [info exists colormap($id)] return
set ncolors [llength $colors] set ncolors [llength $colors]
if {$nparents($id) == 1 && $nchildren($id) == 1} { if {$nparents($id) <= 1 && $nchildren($id) == 1} {
set child [lindex $children($id) 0] set child [lindex $children($id) 0]
if {[info exists colormap($child)] if {[info exists colormap($child)]
&& $nparents($child) == 1} { && $nparents($child) == 1} {
@ -583,7 +587,7 @@ proc assigncolor {id} {


proc initgraph {} { proc initgraph {} {
global canvy canvy0 lineno numcommits lthickness nextcolor linespc global canvy canvy0 lineno numcommits lthickness nextcolor linespc
global glines global mainline sidelines
global nchildren ncleft global nchildren ncleft


allcanvs delete all allcanvs delete all
@ -592,7 +596,8 @@ proc initgraph {} {
set lineno -1 set lineno -1
set numcommits 0 set numcommits 0
set lthickness [expr {int($linespc / 9) + 1}] set lthickness [expr {int($linespc / 9) + 1}]
catch {unset glines} catch {unset mainline}
catch {unset sidelines}
foreach id [array names nchildren] { foreach id [array names nchildren] {
set ncleft($id) $nchildren($id) set ncleft($id) $nchildren($id)
} }
@ -610,12 +615,11 @@ proc bindline {t id} {
proc drawcommitline {level} { proc drawcommitline {level} {
global parents children nparents nchildren todo global parents children nparents nchildren todo
global canv canv2 canv3 mainfont namefont canvx0 canvy linespc global canv canv2 canv3 mainfont namefont canvx0 canvy linespc
global datemode cdate
global lineid linehtag linentag linedtag commitinfo global lineid linehtag linentag linedtag commitinfo
global colormap numcommits currentparents dupparents global colormap numcommits currentparents dupparents
global oldlevel oldnlines oldtodo global oldlevel oldnlines oldtodo
global idtags idline idheads global idtags idline idheads
global lineno lthickness glines global lineno lthickness mainline sidelines
global commitlisted global commitlisted


incr numcommits incr numcommits
@ -631,6 +635,7 @@ proc drawcommitline {level} {
set nparents($id) 0 set nparents($id) 0
} }
} }
assigncolor $id
set currentparents {} set currentparents {}
set dupparents {} set dupparents {}
if {[info exists commitlisted($id)] && [info exists parents($id)]} { if {[info exists commitlisted($id)] && [info exists parents($id)]} {
@ -648,21 +653,31 @@ proc drawcommitline {level} {
set canvy [expr $canvy + $linespc] set canvy [expr $canvy + $linespc]
allcanvs conf -scrollregion \ allcanvs conf -scrollregion \
[list 0 0 0 [expr $y1 + 0.5 * $linespc + 2]] [list 0 0 0 [expr $y1 + 0.5 * $linespc + 2]]
if {[info exists glines($id)]} { if {[info exists mainline($id)]} {
lappend glines($id) $x $y1 lappend mainline($id) $x $y1
set t [$canv create line $glines($id) \ set t [$canv create line $mainline($id) \
-width $lthickness -fill $colormap($id)] -width $lthickness -fill $colormap($id)]
$canv lower $t $canv lower $t
bindline $t $id bindline $t $id
} }
if {[info exists sidelines($id)]} {
foreach ls $sidelines($id) {
set coords [lindex $ls 0]
set thick [lindex $ls 1]
set t [$canv create line $coords -fill $colormap($id) \
-width [expr {$thick * $lthickness}]]
$canv lower $t
bindline $t $id
}
}
set orad [expr {$linespc / 3}] set orad [expr {$linespc / 3}]
set t [$canv create oval [expr $x - $orad] [expr $y1 - $orad] \ set t [$canv create oval [expr $x - $orad] [expr $y1 - $orad] \
[expr $x + $orad - 1] [expr $y1 + $orad - 1] \ [expr $x + $orad - 1] [expr $y1 + $orad - 1] \
-fill $ofill -outline black -width 1] -fill $ofill -outline black -width 1]
$canv raise $t $canv raise $t
set xt [expr $canvx0 + [llength $todo] * $linespc] set xt [expr $canvx0 + [llength $todo] * $linespc]
if {$nparents($id) > 2} { if {[llength $currentparents] > 2} {
set xt [expr {$xt + ($nparents($id) - 2) * $linespc}] set xt [expr {$xt + ([llength $currentparents] - 2) * $linespc}]
} }
set marks {} set marks {}
set ntags 0 set ntags 0
@ -718,38 +733,32 @@ proc drawcommitline {level} {
} }


proc updatetodo {level noshortcut} { proc updatetodo {level noshortcut} {
global datemode currentparents ncleft todo global currentparents ncleft todo
global glines oldlevel oldtodo oldnlines global mainline oldlevel oldtodo oldnlines
global canvx0 canvy linespc glines global canvx0 canvy linespc mainline
global commitinfo global commitinfo


foreach p $currentparents { set oldlevel $level
if {![info exists commitinfo($p)]} { set oldtodo $todo
readcommit $p set oldnlines [llength $todo]
}
}
set x [expr $canvx0 + $level * $linespc]
set y [expr $canvy - $linespc]
if {!$noshortcut && [llength $currentparents] == 1} { if {!$noshortcut && [llength $currentparents] == 1} {
set p [lindex $currentparents 0] set p [lindex $currentparents 0]
if {$ncleft($p) == 0 && [lsearch -exact $todo $p] < 0} { if {$ncleft($p) == 1 && [lsearch -exact $todo $p] < 0} {
assigncolor $p set ncleft($p) 0
set glines($p) [list $x $y] set x [expr $canvx0 + $level * $linespc]
set y [expr $canvy - $linespc]
set mainline($p) [list $x $y]
set todo [lreplace $todo $level $level $p] set todo [lreplace $todo $level $level $p]
return 0 return 0
} }
} }


set oldlevel $level
set oldtodo $todo
set oldnlines [llength $todo]
set todo [lreplace $todo $level $level] set todo [lreplace $todo $level $level]
set i $level set i $level
foreach p $currentparents { foreach p $currentparents {
incr ncleft($p) -1 incr ncleft($p) -1
set k [lsearch -exact $todo $p] set k [lsearch -exact $todo $p]
if {$k < 0} { if {$k < 0} {
assigncolor $p
set todo [linsert $todo $i $p] set todo [linsert $todo $i $p]
incr i incr i
} }
@ -758,7 +767,7 @@ proc updatetodo {level noshortcut} {
} }


proc drawslants {} { proc drawslants {} {
global canv glines canvx0 canvy linespc global canv mainline sidelines canvx0 canvy linespc
global oldlevel oldtodo todo currentparents dupparents global oldlevel oldtodo todo currentparents dupparents
global lthickness linespc canvy colormap global lthickness linespc canvy colormap


@ -782,33 +791,27 @@ proc drawslants {} {
if {[lsearch -exact $dupparents $p] >= 0} { if {[lsearch -exact $dupparents $p] >= 0} {
# draw a double-width line to indicate the doubled parent # draw a double-width line to indicate the doubled parent
lappend coords $xj $y2 lappend coords $xj $y2
set t [$canv create line $coords \ lappend sidelines($p) [list $coords 2]
-width [expr 2*$lthickness] -fill $colormap($p)] if {![info exists mainline($p)]} {
$canv lower $t set mainline($p) [list $xj $y2]
bindline $t $p
if {![info exists glines($p)]} {
set glines($p) [list $xj $y2]
} }
} else { } else {
# normal case, no parent duplicated # normal case, no parent duplicated
if {![info exists glines($p)]} { if {![info exists mainline($p)]} {
if {$i != $j} { if {$i != $j} {
lappend coords $xj $y2 lappend coords $xj $y2
} }
set glines($p) $coords set mainline($p) $coords
} else { } else {
lappend coords $xj $y2 lappend coords $xj $y2
set t [$canv create line $coords \ lappend sidelines($p) [list $coords 1]
-width $lthickness -fill $colormap($p)]
$canv lower $t
bindline $t $p
} }
} }
} }
} elseif {[lindex $todo $i] != $id} { } elseif {[lindex $todo $i] != $id} {
set j [lsearch -exact $todo $id] set j [lsearch -exact $todo $id]
set xj [expr {$canvx0 + $j * $linespc}] set xj [expr {$canvx0 + $j * $linespc}]
lappend glines($id) $xi $y1 $xj $y2 lappend mainline($id) $xi $y1 $xj $y2
} }
} }
} }
@ -849,7 +852,7 @@ proc decidenext {} {
if {$todo != {}} { if {$todo != {}} {
puts "ERROR: none of the pending commits can be done yet:" puts "ERROR: none of the pending commits can be done yet:"
foreach p $todo { foreach p $todo {
puts " $p" puts " $p ($ncleft($p))"
} }
} }
return -1 return -1
@ -888,14 +891,12 @@ proc drawcommit {id} {
set todo $id set todo $id
set startcommits $id set startcommits $id
initgraph initgraph
assigncolor $id
drawcommitline 0 drawcommitline 0
updatetodo 0 $datemode updatetodo 0 $datemode
} else { } else {
if {$nchildren($id) == 0} { if {$nchildren($id) == 0} {
lappend todo $id lappend todo $id
lappend startcommits $id lappend startcommits $id
assigncolor $id
} }
set level [decidenext] set level [decidenext]
if {$id != [lindex $todo $level]} { if {$id != [lindex $todo $level]} {
@ -1636,7 +1637,6 @@ foreach arg $argv {
} }
} }


set noreadobj [catch {load libreadobj.so.0.0}]
set stopped 0 set stopped 0
set redisplaying 0 set redisplaying 0
set stuffsaved 0 set stuffsaved 0

Loading…
Cancel
Save