X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gitk;h=8699e1bb4f97dc3e1a6ec9d5a43e4fdf6323a3e8;hb=17529cf9bc50e8b2bc0ea930a966b8b47056853e;hp=290deff7b223c9baea87219b9a7e2560d537fcdd;hpb=8d73b242a53da9ea36800a8ff0f9993e5100ea24;p=git.git diff --git a/gitk b/gitk index 290deff7b..8699e1bb4 100755 --- a/gitk +++ b/gitk @@ -47,12 +47,24 @@ proc filereadable {fd script} { lappend runq [list $fd $script] } +proc nukefile {fd} { + global runq + + for {set i 0} {$i < [llength $runq]} {} { + if {[lindex $runq $i 0] eq $fd} { + set runq [lreplace $runq $i $i] + } else { + incr i + } + } +} + proc dorunq {} { global isonrunq runq set tstart [clock clicks -milliseconds] set t0 $tstart - while {$runq ne {}} { + while {[llength $runq] > 0} { set fd [lindex $runq 0 0] set script [lindex $runq 0 1] set repeat [eval $script] @@ -85,24 +97,34 @@ proc start_rev_list {view} { global viewargs viewfiles commitidx viewcomplete vnextroot global showlocalchanges commitinterest mainheadid global progressdirn progresscoords proglastnc curview + global viewincl viewactive loginstance viewinstances set startmsecs [clock clicks -milliseconds] set commitidx($view) 0 set viewcomplete($view) 0 + set viewactive($view) 1 set vnextroot($view) 0 - set order "--topo-order" - if {$datemode} { - set order "--date-order" + varcinit $view + + set commits [eval exec git rev-parse --default HEAD --revs-only \ + $viewargs($view)] + set viewincl($view) {} + foreach c $commits { + if {[regexp {^[0-9a-fA-F]{40}$} $c]} { + lappend viewincl($view) $c + } } if {[catch { - set fd [open [concat | git log -z --pretty=raw $order --parents \ - --boundary $viewargs($view) "--" $viewfiles($view)] r] + set fd [open [concat | git log --no-color -z --pretty=raw --parents \ + --boundary $commits "--" $viewfiles($view)] r] } err]} { - error_popup "Error executing git rev-list: $err" + error_popup "[mc "Error executing git log:"] $err" exit 1 } - set commfd($view) $fd - set leftover($view) {} + set i [incr loginstance] + set viewinstances($view) [list $i] + set commfd($i) $fd + set leftover($i) {} if {$showlocalchanges} { lappend commitinterest($mainheadid) {dodiffindex} } @@ -110,8 +132,8 @@ proc start_rev_list {view} { if {$tclencoding != {}} { fconfigure $fd -encoding $tclencoding } - filerun $fd [list getcommitlines $fd $view] - nowbusy $view + filerun $fd [list getcommitlines $fd $i $view] + nowbusy $view [mc "Reading"] if {$view == $curview} { set progressdirn 1 set progresscoords {0 0} @@ -119,26 +141,125 @@ proc start_rev_list {view} { } } -proc stop_rev_list {} { - global commfd curview +proc stop_rev_list {view} { + global commfd viewinstances leftover - if {![info exists commfd($curview)]} return - set fd $commfd($curview) - catch { - set pid [pid $fd] - exec kill $pid + foreach inst $viewinstances($view) { + set fd $commfd($inst) + catch { + set pid [pid $fd] + exec kill $pid + } + catch {close $fd} + nukefile $fd + unset commfd($inst) + unset leftover($inst) } - catch {close $fd} - unset commfd($curview) + set viewinstances($view) {} } proc getcommits {} { - global phase canv curview + global canv curview - set phase getcommits initlayout start_rev_list $curview - show_status "Reading commits..." + show_status [mc "Reading commits..."] +} + +proc updatecommits {} { + global curview viewargs viewfiles viewincl viewinstances + global viewactive viewcomplete loginstance tclencoding mainheadid + global varcid startmsecs commfd showneartags showlocalchanges leftover + global mainheadid + + set oldmainid $mainheadid + rereadrefs + if {$showlocalchanges} { + if {$mainheadid ne $oldmainid} { + dohidelocalchanges + } + if {[commitinview $mainheadid $curview]} { + dodiffindex + } + } + set view $curview + set commits [exec git rev-parse --default HEAD --revs-only \ + $viewargs($view)] + set pos {} + set neg {} + set flags {} + foreach c $commits { + if {[string match "^*" $c]} { + lappend neg $c + } elseif {[regexp {^[0-9a-fA-F]{40}$} $c]} { + if {!([info exists varcid($view,$c)] || + [lsearch -exact $viewincl($view) $c] >= 0)} { + lappend pos $c + } + } else { + lappend flags $c + } + } + if {$pos eq {}} { + return + } + foreach id $viewincl($view) { + lappend neg "^$id" + } + set viewincl($view) [concat $viewincl($view) $pos] + if {[catch { + set fd [open [concat | git log --no-color -z --pretty=raw --parents \ + --boundary $pos $neg $flags "--" $viewfiles($view)] r] + } err]} { + error_popup "Error executing git log: $err" + exit 1 + } + if {$viewactive($view) == 0} { + set startmsecs [clock clicks -milliseconds] + } + set i [incr loginstance] + lappend viewinstances($view) $i + set commfd($i) $fd + set leftover($i) {} + fconfigure $fd -blocking 0 -translation lf -eofchar {} + if {$tclencoding != {}} { + fconfigure $fd -encoding $tclencoding + } + filerun $fd [list getcommitlines $fd $i $view] + incr viewactive($view) + set viewcomplete($view) 0 + nowbusy $view "Reading" + if {$showneartags} { + getallcommits + } +} + +proc reloadcommits {} { + global curview viewcomplete selectedline currentid thickerline + global showneartags treediffs commitinterest cached_commitrow + global progresscoords targetid + + if {!$viewcomplete($curview)} { + stop_rev_list $curview + set progresscoords {0 0} + adjustprogress + } + resetvarcs $curview + catch {unset selectedline} + catch {unset currentid} + catch {unset thickerline} + catch {unset treediffs} + readrefs + changedrefs + if {$showneartags} { + getallcommits + } + clear_display + catch {unset commitinterest} + catch {unset cached_commitrow} + catch {unset targetid} + setcanvscroll + getcommits } # This makes a string representation of a positive integer which @@ -154,46 +275,672 @@ proc strrep {n} { return [format "z%.8x" $n] } -proc getcommitlines {fd view} { - global commitlisted commitinterest - global leftover commfd - global displayorder commitidx viewcomplete commitrow commitdata - global parentlist children curview hlview - global vparentlist vdisporder vcmitlisted - global ordertok vnextroot idpending +# Procedures used in reordering commits from git log (without +# --topo-order) into the order for display. + +proc varcinit {view} { + global varcstart vupptr vdownptr vleftptr vbackptr varctok varcrow + global vtokmod varcmod vrowmod varcix vlastins + + set varcstart($view) {{}} + set vupptr($view) {0} + set vdownptr($view) {0} + set vleftptr($view) {0} + set vbackptr($view) {0} + set varctok($view) {{}} + set varcrow($view) {{}} + set vtokmod($view) {} + set varcmod($view) 0 + set vrowmod($view) 0 + set varcix($view) {{}} + set vlastins($view) {0} +} + +proc resetvarcs {view} { + global varcid varccommits parents children vseedcount ordertok + + foreach vid [array names varcid $view,*] { + unset varcid($vid) + unset children($vid) + unset parents($vid) + } + # some commits might have children but haven't been seen yet + foreach vid [array names children $view,*] { + unset children($vid) + } + foreach va [array names varccommits $view,*] { + unset varccommits($va) + } + foreach vd [array names vseedcount $view,*] { + unset vseedcount($vd) + } + catch {unset ordertok} +} + +proc newvarc {view id} { + global varcid varctok parents children datemode + global vupptr vdownptr vleftptr vbackptr varcrow varcix varcstart + global commitdata commitinfo vseedcount varccommits vlastins + + set a [llength $varctok($view)] + set vid $view,$id + if {[llength $children($vid)] == 0 || $datemode} { + if {![info exists commitinfo($id)]} { + parsecommit $id $commitdata($id) 1 + } + set cdate [lindex $commitinfo($id) 4] + if {![string is integer -strict $cdate]} { + set cdate 0 + } + if {![info exists vseedcount($view,$cdate)]} { + set vseedcount($view,$cdate) -1 + } + set c [incr vseedcount($view,$cdate)] + set cdate [expr {$cdate ^ 0xffffffff}] + set tok "s[strrep $cdate][strrep $c]" + } else { + set tok {} + } + set ka 0 + if {[llength $children($vid)] > 0} { + set kid [lindex $children($vid) end] + set k $varcid($view,$kid) + if {[string compare [lindex $varctok($view) $k] $tok] > 0} { + set ki $kid + set ka $k + set tok [lindex $varctok($view) $k] + } + } + if {$ka != 0} { + set i [lsearch -exact $parents($view,$ki) $id] + set j [expr {[llength $parents($view,$ki)] - 1 - $i}] + append tok [strrep $j] + } + set c [lindex $vlastins($view) $ka] + if {$c == 0 || [string compare $tok [lindex $varctok($view) $c]] < 0} { + set c $ka + set b [lindex $vdownptr($view) $ka] + } else { + set b [lindex $vleftptr($view) $c] + } + while {$b != 0 && [string compare $tok [lindex $varctok($view) $b]] >= 0} { + set c $b + set b [lindex $vleftptr($view) $c] + } + if {$c == $ka} { + lset vdownptr($view) $ka $a + lappend vbackptr($view) 0 + } else { + lset vleftptr($view) $c $a + lappend vbackptr($view) $c + } + lset vlastins($view) $ka $a + lappend vupptr($view) $ka + lappend vleftptr($view) $b + if {$b != 0} { + lset vbackptr($view) $b $a + } + lappend varctok($view) $tok + lappend varcstart($view) $id + lappend vdownptr($view) 0 + lappend varcrow($view) {} + lappend varcix($view) {} + set varccommits($view,$a) {} + lappend vlastins($view) 0 + return $a +} + +proc splitvarc {p v} { + global varcid varcstart varccommits varctok + global vupptr vdownptr vleftptr vbackptr varcix varcrow vlastins + + set oa $varcid($v,$p) + set ac $varccommits($v,$oa) + set i [lsearch -exact $varccommits($v,$oa) $p] + if {$i <= 0} return + set na [llength $varctok($v)] + # "%" sorts before "0"... + set tok "[lindex $varctok($v) $oa]%[strrep $i]" + lappend varctok($v) $tok + lappend varcrow($v) {} + lappend varcix($v) {} + set varccommits($v,$oa) [lrange $ac 0 [expr {$i - 1}]] + set varccommits($v,$na) [lrange $ac $i end] + lappend varcstart($v) $p + foreach id $varccommits($v,$na) { + set varcid($v,$id) $na + } + lappend vdownptr($v) [lindex $vdownptr($v) $oa] + lset vdownptr($v) $oa $na + lappend vupptr($v) $oa + lappend vleftptr($v) 0 + lappend vbackptr($v) 0 + lappend vlastins($v) 0 + for {set b [lindex $vdownptr($v) $na]} {$b != 0} {set b [lindex $vleftptr($v) $b]} { + lset vupptr($v) $b $na + } +} + +proc renumbervarc {a v} { + global parents children varctok varcstart varccommits + global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod datemode + + set t1 [clock clicks -milliseconds] + set todo {} + set isrelated($a) 1 + set kidchanged($a) 1 + set ntot 0 + while {$a != 0} { + if {[info exists isrelated($a)]} { + lappend todo $a + set id [lindex $varccommits($v,$a) end] + foreach p $parents($v,$id) { + if {[info exists varcid($v,$p)]} { + set isrelated($varcid($v,$p)) 1 + } + } + } + incr ntot + set b [lindex $vdownptr($v) $a] + if {$b == 0} { + while {$a != 0} { + set b [lindex $vleftptr($v) $a] + if {$b != 0} break + set a [lindex $vupptr($v) $a] + } + } + set a $b + } + foreach a $todo { + if {![info exists kidchanged($a)]} continue + set id [lindex $varcstart($v) $a] + if {[llength $children($v,$id)] > 1} { + set children($v,$id) [lsort -command [list vtokcmp $v] \ + $children($v,$id)] + } + set oldtok [lindex $varctok($v) $a] + if {!$datemode} { + set tok {} + } else { + set tok $oldtok + } + set ka 0 + set kid [last_real_child $v,$id] + if {$kid ne {}} { + set k $varcid($v,$kid) + if {[string compare [lindex $varctok($v) $k] $tok] > 0} { + set ki $kid + set ka $k + set tok [lindex $varctok($v) $k] + } + } + if {$ka != 0} { + set i [lsearch -exact $parents($v,$ki) $id] + set j [expr {[llength $parents($v,$ki)] - 1 - $i}] + append tok [strrep $j] + } + if {$tok eq $oldtok} { + continue + } + set id [lindex $varccommits($v,$a) end] + foreach p $parents($v,$id) { + if {[info exists varcid($v,$p)]} { + set kidchanged($varcid($v,$p)) 1 + } else { + set sortkids($p) 1 + } + } + lset varctok($v) $a $tok + set b [lindex $vupptr($v) $a] + if {$b != $ka} { + if {[string compare [lindex $varctok($v) $ka] $vtokmod($v)] < 0} { + modify_arc $v $ka + } + if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} { + modify_arc $v $b + } + set c [lindex $vbackptr($v) $a] + set d [lindex $vleftptr($v) $a] + if {$c == 0} { + lset vdownptr($v) $b $d + } else { + lset vleftptr($v) $c $d + } + if {$d != 0} { + lset vbackptr($v) $d $c + } + lset vupptr($v) $a $ka + set c [lindex $vlastins($v) $ka] + if {$c == 0 || \ + [string compare $tok [lindex $varctok($v) $c]] < 0} { + set c $ka + set b [lindex $vdownptr($v) $ka] + } else { + set b [lindex $vleftptr($v) $c] + } + while {$b != 0 && \ + [string compare $tok [lindex $varctok($v) $b]] >= 0} { + set c $b + set b [lindex $vleftptr($v) $c] + } + if {$c == $ka} { + lset vdownptr($v) $ka $a + lset vbackptr($v) $a 0 + } else { + lset vleftptr($v) $c $a + lset vbackptr($v) $a $c + } + lset vleftptr($v) $a $b + if {$b != 0} { + lset vbackptr($v) $b $a + } + lset vlastins($v) $ka $a + } + } + foreach id [array names sortkids] { + if {[llength $children($v,$id)] > 1} { + set children($v,$id) [lsort -command [list vtokcmp $v] \ + $children($v,$id)] + } + } + set t2 [clock clicks -milliseconds] + #puts "renumbervarc did [llength $todo] of $ntot arcs in [expr {$t2-$t1}]ms" +} + +proc fix_reversal {p a v} { + global varcid varcstart varctok vupptr + + set pa $varcid($v,$p) + if {$p ne [lindex $varcstart($v) $pa]} { + splitvarc $p $v + set pa $varcid($v,$p) + } + # seeds always need to be renumbered + if {[lindex $vupptr($v) $pa] == 0 || + [string compare [lindex $varctok($v) $a] \ + [lindex $varctok($v) $pa]] > 0} { + renumbervarc $pa $v + } +} + +proc insertrow {id p v} { + global varcid varccommits parents children cmitlisted + global commitidx varctok vtokmod targetid targetrow + + set a $varcid($v,$p) + set i [lsearch -exact $varccommits($v,$a) $p] + if {$i < 0} { + puts "oops: insertrow can't find [shortids $p] on arc $a" + return + } + set children($v,$id) {} + set parents($v,$id) [list $p] + set varcid($v,$id) $a + lappend children($v,$p) $id + set cmitlisted($v,$id) 1 + incr commitidx($v) + # note we deliberately don't update varcstart($v) even if $i == 0 + set varccommits($v,$a) [linsert $varccommits($v,$a) $i $id] + if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} { + modify_arc $v $a $i + } + if {[info exists targetid]} { + if {![comes_before $targetid $p]} { + incr targetrow + } + } + drawvisible +} + +proc removerow {id v} { + global varcid varccommits parents children commitidx + global varctok vtokmod cmitlisted currentid selectedline + global targetid + + if {[llength $parents($v,$id)] != 1} { + puts "oops: removerow [shortids $id] has [llength $parents($v,$id)] parents" + return + } + set p [lindex $parents($v,$id) 0] + set a $varcid($v,$id) + set i [lsearch -exact $varccommits($v,$a) $id] + if {$i < 0} { + puts "oops: removerow can't find [shortids $id] on arc $a" + return + } + unset varcid($v,$id) + set varccommits($v,$a) [lreplace $varccommits($v,$a) $i $i] + unset parents($v,$id) + unset children($v,$id) + unset cmitlisted($v,$id) + incr commitidx($v) -1 + set j [lsearch -exact $children($v,$p) $id] + if {$j >= 0} { + set children($v,$p) [lreplace $children($v,$p) $j $j] + } + if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} { + modify_arc $v $a $i + } + if {[info exist currentid] && $id eq $currentid} { + unset currentid + unset selectedline + } + if {[info exists targetid] && $targetid eq $id} { + set targetid $p + } + drawvisible +} + +proc first_real_child {vp} { + global children nullid nullid2 + + foreach id $children($vp) { + if {$id ne $nullid && $id ne $nullid2} { + return $id + } + } + return {} +} + +proc last_real_child {vp} { + global children nullid nullid2 + + set kids $children($vp) + for {set i [llength $kids]} {[incr i -1] >= 0} {} { + set id [lindex $kids $i] + if {$id ne $nullid && $id ne $nullid2} { + return $id + } + } + return {} +} + +proc vtokcmp {v a b} { + global varctok varcid + + return [string compare [lindex $varctok($v) $varcid($v,$a)] \ + [lindex $varctok($v) $varcid($v,$b)]] +} + +proc modify_arc {v a {lim {}}} { + global varctok vtokmod varcmod varcrow vupptr curview vrowmod varccommits + + set vtokmod($v) [lindex $varctok($v) $a] + set varcmod($v) $a + if {$v == $curview} { + while {$a != 0 && [lindex $varcrow($v) $a] eq {}} { + set a [lindex $vupptr($v) $a] + set lim {} + } + set r 0 + if {$a != 0} { + if {$lim eq {}} { + set lim [llength $varccommits($v,$a)] + } + set r [expr {[lindex $varcrow($v) $a] + $lim}] + } + set vrowmod($v) $r + undolayout $r + } +} + +proc update_arcrows {v} { + global vtokmod varcmod vrowmod varcrow commitidx currentid selectedline + global varcid vrownum varcorder varcix varccommits + global vupptr vdownptr vleftptr varctok + global displayorder parentlist curview cached_commitrow + + set narctot [expr {[llength $varctok($v)] - 1}] + set a $varcmod($v) + while {$a != 0 && [lindex $varcix($v) $a] eq {}} { + # go up the tree until we find something that has a row number, + # or we get to a seed + set a [lindex $vupptr($v) $a] + } + if {$a == 0} { + set a [lindex $vdownptr($v) 0] + if {$a == 0} return + set vrownum($v) {0} + set varcorder($v) [list $a] + lset varcix($v) $a 0 + lset varcrow($v) $a 0 + set arcn 0 + set row 0 + } else { + set arcn [lindex $varcix($v) $a] + # see if a is the last arc; if so, nothing to do + if {$arcn == $narctot - 1} { + return + } + if {[llength $vrownum($v)] > $arcn + 1} { + set vrownum($v) [lrange $vrownum($v) 0 $arcn] + set varcorder($v) [lrange $varcorder($v) 0 $arcn] + } + set row [lindex $varcrow($v) $a] + } + if {$v == $curview} { + if {[llength $displayorder] > $vrowmod($v)} { + set displayorder [lrange $displayorder 0 [expr {$vrowmod($v) - 1}]] + set parentlist [lrange $parentlist 0 [expr {$vrowmod($v) - 1}]] + } + catch {unset cached_commitrow} + } + while {1} { + set p $a + incr row [llength $varccommits($v,$a)] + # go down if possible + set b [lindex $vdownptr($v) $a] + if {$b == 0} { + # if not, go left, or go up until we can go left + while {$a != 0} { + set b [lindex $vleftptr($v) $a] + if {$b != 0} break + set a [lindex $vupptr($v) $a] + } + if {$a == 0} break + } + set a $b + incr arcn + lappend vrownum($v) $row + lappend varcorder($v) $a + lset varcix($v) $a $arcn + lset varcrow($v) $a $row + } + set vtokmod($v) [lindex $varctok($v) $p] + set varcmod($v) $p + set vrowmod($v) $row + if {[info exists currentid]} { + set selectedline [rowofcommit $currentid] + } +} + +# Test whether view $v contains commit $id +proc commitinview {id v} { + global varcid + + return [info exists varcid($v,$id)] +} + +# Return the row number for commit $id in the current view +proc rowofcommit {id} { + global varcid varccommits varcrow curview cached_commitrow + global varctok vtokmod + + set v $curview + if {![info exists varcid($v,$id)]} { + puts "oops rowofcommit no arc for [shortids $id]" + return {} + } + set a $varcid($v,$id) + if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] >= 0} { + update_arcrows $v + } + if {[info exists cached_commitrow($id)]} { + return $cached_commitrow($id) + } + set i [lsearch -exact $varccommits($v,$a) $id] + if {$i < 0} { + puts "oops didn't find commit [shortids $id] in arc $a" + return {} + } + incr i [lindex $varcrow($v) $a] + set cached_commitrow($id) $i + return $i +} + +# Returns 1 if a is on an earlier row than b, otherwise 0 +proc comes_before {a b} { + global varcid varctok curview + + set v $curview + if {$a eq $b || ![info exists varcid($v,$a)] || \ + ![info exists varcid($v,$b)]} { + return 0 + } + if {$varcid($v,$a) != $varcid($v,$b)} { + return [expr {[string compare [lindex $varctok($v) $varcid($v,$a)] \ + [lindex $varctok($v) $varcid($v,$b)]] < 0}] + } + return [expr {[rowofcommit $a] < [rowofcommit $b]}] +} + +proc bsearch {l elt} { + if {[llength $l] == 0 || $elt <= [lindex $l 0]} { + return 0 + } + set lo 0 + set hi [llength $l] + while {$hi - $lo > 1} { + set mid [expr {int(($lo + $hi) / 2)}] + set t [lindex $l $mid] + if {$elt < $t} { + set hi $mid + } elseif {$elt > $t} { + set lo $mid + } else { + return $mid + } + } + return $lo +} + +# Make sure rows $start..$end-1 are valid in displayorder and parentlist +proc make_disporder {start end} { + global vrownum curview commitidx displayorder parentlist + global varccommits varcorder parents vrowmod varcrow + global d_valid_start d_valid_end + + if {$end > $vrowmod($curview)} { + update_arcrows $curview + } + set ai [bsearch $vrownum($curview) $start] + set start [lindex $vrownum($curview) $ai] + set narc [llength $vrownum($curview)] + for {set r $start} {$ai < $narc && $r < $end} {incr ai} { + set a [lindex $varcorder($curview) $ai] + set l [llength $displayorder] + set al [llength $varccommits($curview,$a)] + if {$l < $r + $al} { + if {$l < $r} { + set pad [ntimes [expr {$r - $l}] {}] + set displayorder [concat $displayorder $pad] + set parentlist [concat $parentlist $pad] + } elseif {$l > $r} { + set displayorder [lrange $displayorder 0 [expr {$r - 1}]] + set parentlist [lrange $parentlist 0 [expr {$r - 1}]] + } + foreach id $varccommits($curview,$a) { + lappend displayorder $id + lappend parentlist $parents($curview,$id) + } + } elseif {[lindex $displayorder [expr {$r + $al - 1}]] eq {}} { + set i $r + foreach id $varccommits($curview,$a) { + lset displayorder $i $id + lset parentlist $i $parents($curview,$id) + incr i + } + } + incr r $al + } +} + +proc commitonrow {row} { + global displayorder + + set id [lindex $displayorder $row] + if {$id eq {}} { + make_disporder $row [expr {$row + 1}] + set id [lindex $displayorder $row] + } + return $id +} + +proc closevarcs {v} { + global varctok varccommits varcid parents children + global cmitlisted commitidx commitinterest vtokmod + + set missing_parents 0 + set scripts {} + set narcs [llength $varctok($v)] + for {set a 1} {$a < $narcs} {incr a} { + set id [lindex $varccommits($v,$a) end] + foreach p $parents($v,$id) { + if {[info exists varcid($v,$p)]} continue + # add p as a new commit + incr missing_parents + set cmitlisted($v,$p) 0 + set parents($v,$p) {} + if {[llength $children($v,$p)] == 1 && + [llength $parents($v,$id)] == 1} { + set b $a + } else { + set b [newvarc $v $p] + } + set varcid($v,$p) $b + if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} { + modify_arc $v $b + } + lappend varccommits($v,$b) $p + incr commitidx($v) + if {[info exists commitinterest($p)]} { + foreach script $commitinterest($p) { + lappend scripts [string map [list "%I" $p] $script] + } + unset commitinterest($id) + } + } + } + if {$missing_parents > 0} { + foreach s $scripts { + eval $s + } + } +} + +proc getcommitlines {fd inst view} { + global cmitlisted commitinterest leftover + global commitidx commitdata datemode + global parents children curview hlview + global vnextroot idpending ordertok + global varccommits varcid varctok vtokmod set stuff [read $fd 500000] # git log doesn't terminate the last commit with a null... - if {$stuff == {} && $leftover($view) ne {} && [eof $fd]} { + if {$stuff == {} && $leftover($inst) ne {} && [eof $fd]} { set stuff "\0" } if {$stuff == {}} { if {![eof $fd]} { return 1 } - # Check if we have seen any ids listed as parents that haven't - # appeared in the list - foreach vid [array names idpending "$view,*"] { - # should only get here if git log is buggy - set id [lindex [split $vid ","] 1] - set commitrow($vid) $commitidx($view) - incr commitidx($view) - if {$view == $curview} { - lappend parentlist {} - lappend displayorder $id - lappend commitlisted 0 - } else { - lappend vparentlist($view) {} - lappend vdisporder($view) $id - lappend vcmitlisted($view) 0 - } + global commfd viewcomplete viewactive viewname progresscoords + global viewinstances + unset commfd($inst) + set i [lsearch -exact $viewinstances($view) $inst] + if {$i >= 0} { + set viewinstances($view) [lreplace $viewinstances($view) $i $i] } - set viewcomplete($view) 1 - global viewname progresscoords - unset commfd($view) - notbusy $view - set progresscoords {0 0} - adjustprogress # set it blocking so we wait for the process to terminate fconfigure $fd -blocking 1 if {[catch {close $fd} err]} { @@ -214,6 +961,15 @@ proc getcommitlines {fd view} { } error_popup $err } + if {[incr viewactive($view) -1] <= 0} { + set viewcomplete($view) 1 + # Check if we have seen any ids listed as parents that haven't + # appeared in the list + closevarcs $view + notbusy $view + set progresscoords {0 0} + adjustprogress + } if {$view == $curview} { run chewcommits $view } @@ -221,16 +977,17 @@ proc getcommitlines {fd view} { } set start 0 set gotsome 0 + set scripts {} while 1 { set i [string first "\0" $stuff $start] if {$i < 0} { - append leftover($view) [string range $stuff $start end] + append leftover($inst) [string range $stuff $start end] break } if {$start == 0} { - set cmit $leftover($view) + set cmit $leftover($inst) append cmit [string range $stuff 0 [expr {$i - 1}]] - set leftover($view) {} + set leftover($inst) {} } else { set cmit [string range $stuff $start [expr {$i - 1}]] } @@ -261,61 +1018,62 @@ proc getcommitlines {fd view} { if {[string length $shortcmit] > 80} { set shortcmit "[string range $shortcmit 0 80]..." } - error_popup "Can't parse git log output: {$shortcmit}" + error_popup "[mc "Can't parse git log output:"] {$shortcmit}" exit 1 } set id [lindex $ids 0] - if {![info exists ordertok($view,$id)]} { - set otok "o[strrep $vnextroot($view)]" - incr vnextroot($view) - set ordertok($view,$id) $otok - } else { - set otok $ordertok($view,$id) - unset idpending($view,$id) - } + set vid $view,$id + if {!$listed && [info exists parents($vid)]} continue if {$listed} { set olds [lrange $ids 1 end] - if {[llength $olds] == 1} { - set p [lindex $olds 0] - lappend children($view,$p) $id - if {![info exists ordertok($view,$p)]} { - set ordertok($view,$p) $ordertok($view,$id) - set idpending($view,$p) 1 - } - } else { - set i 0 - foreach p $olds { - if {$i == 0 || [lsearch -exact $olds $p] >= $i} { - lappend children($view,$p) $id - } - if {![info exists ordertok($view,$p)]} { - set ordertok($view,$p) "$otok[strrep $i]]" - set idpending($view,$p) 1 - } - incr i - } - } } else { set olds {} } - if {![info exists children($view,$id)]} { - set children($view,$id) {} - } set commitdata($id) [string range $cmit [expr {$j + 1}] end] - set commitrow($view,$id) $commitidx($view) - incr commitidx($view) - if {$view == $curview} { - lappend parentlist $olds - lappend displayorder $id - lappend commitlisted $listed - } else { - lappend vparentlist($view) $olds - lappend vdisporder($view) $id - lappend vcmitlisted($view) $listed + set cmitlisted($vid) $listed + set parents($vid) $olds + set a 0 + if {![info exists children($vid)]} { + set children($vid) {} + } elseif {[llength $children($vid)] == 1} { + set k [lindex $children($vid) 0] + if {[llength $parents($view,$k)] == 1 && + (!$datemode || + $varcid($view,$k) == [llength $varctok($view)] - 1)} { + set a $varcid($view,$k) + } + } + if {$a == 0} { + # new arc + set a [newvarc $view $id] + } + set varcid($vid) $a + if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} { + modify_arc $view $a + } + lappend varccommits($view,$a) $id + + set i 0 + foreach p $olds { + if {$i == 0 || [lsearch -exact $olds $p] >= $i} { + set vp $view,$p + if {[llength [lappend children($vp) $id]] > 1 && + [vtokcmp $view [lindex $children($vp) end-1] $id] > 0} { + set children($vp) [lsort -command [list vtokcmp $view] \ + $children($vp)] + catch {unset ordertok} + } + if {[info exists varcid($view,$p)]} { + fix_reversal $p $a $view + } + } + incr i } + + incr commitidx($view) if {[info exists commitinterest($id)]} { foreach script $commitinterest($id) { - eval [string map [list "%I" $id] $script] + lappend scripts [string map [list "%I" $id] $script] } unset commitinterest($id) } @@ -323,6 +1081,9 @@ proc getcommitlines {fd view} { } if {$gotsome} { run chewcommits $view + foreach s $scripts { + eval $s + } if {$view == $curview} { # update progress bar global progressdirn progresscoords proglastnc @@ -356,13 +1117,14 @@ proc getcommitlines {fd view} { proc chewcommits {view} { global curview hlview viewcomplete - global selectedline pending_select + global pending_select if {$view == $curview} { layoutmore if {$viewcomplete($view)} { - global displayorder commitidx phase + global commitidx varctok global numcommits startmsecs + global mainheadid commitinfo nullid if {[info exists pending_select]} { set row [first_real_row] @@ -371,11 +1133,11 @@ proc chewcommits {view} { if {$commitidx($curview) > 0} { #set ms [expr {[clock clicks -milliseconds] - $startmsecs}] #puts "overall $ms ms for $numcommits commits" + #puts "[llength $varctok($view)] arcs, $commitidx($view) commits" } else { - show_status "No commits selected" + show_status [mc "No commits selected"] } notbusy layout - set phase {} } } if {[info exists hlview] && $view == $hlview} { @@ -389,35 +1151,6 @@ proc readcommit {id} { parsecommit $id $contents 0 } -proc updatecommits {} { - global viewdata curview phase displayorder ordertok idpending - global children commitrow selectedline thickerline showneartags - - if {$phase ne {}} { - stop_rev_list - set phase {} - } - set n $curview - foreach id $displayorder { - catch {unset children($n,$id)} - catch {unset commitrow($n,$id)} - catch {unset ordertok($n,$id)} - } - foreach vid [array names idpending "$n,*"] { - unset idpending($vid) - } - set curview -1 - catch {unset selectedline} - catch {unset thickerline} - catch {unset viewdata($n)} - readrefs - changedrefs - if {$showneartags} { - getallcommits - } - showview $n -} - proc parsecommit {id contents listed} { global commitinfo cdate @@ -483,7 +1216,7 @@ proc getcommit {id} { } else { readcommit $id if {![info exists commitinfo($id)]} { - set commitinfo($id) {"No commit information available"} + set commitinfo($id) [list [mc "No commit information available"]] } } return 1 @@ -544,10 +1277,10 @@ proc readrefs {} { # skip over fake commits proc first_real_row {} { - global nullid nullid2 displayorder numcommits + global nullid nullid2 numcommits for {set row 0} {$row < $numcommits} {incr row} { - set id [lindex $displayorder $row] + set id [commitonrow $row] if {$id ne $nullid && $id ne $nullid2} { break } @@ -582,7 +1315,7 @@ proc removehead {id name} { proc show_error {w top msg} { message $w.m -text $msg -justify center -aspect 400 pack $w.m -side top -fill x -padx 20 -pady 20 - button $w.ok -text OK -command "destroy $top" + button $w.ok -text [mc OK] -command "destroy $top" pack $w.ok -side bottom -fill x bind $top "grab $top; focus $top" bind $top "destroy $top" @@ -604,17 +1337,30 @@ proc confirm_popup msg { wm transient $w . message $w.m -text $msg -justify center -aspect 400 pack $w.m -side top -fill x -padx 20 -pady 20 - button $w.ok -text OK -command "set confirm_ok 1; destroy $w" + button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w" pack $w.ok -side left -fill x - button $w.cancel -text Cancel -command "destroy $w" + button $w.cancel -text [mc Cancel] -command "destroy $w" pack $w.cancel -side right -fill x bind $w "grab $w; focus $w" tkwait window $w return $confirm_ok } +proc setoptions {} { + option add *Panedwindow.showHandle 1 startupFile + option add *Panedwindow.sashRelief raised startupFile + option add *Button.font uifont startupFile + option add *Checkbutton.font uifont startupFile + option add *Radiobutton.font uifont startupFile + option add *Menu.font uifont startupFile + option add *Menubutton.font uifont startupFile + option add *Label.font uifont startupFile + option add *Message.font uifont startupFile + option add *Entry.font uifont startupFile +} + proc makewindow {} { - global canv canv2 canv3 linespc charspc ctext cflist + global canv canv2 canv3 linespc charspc ctext cflist cscroll global tabstop global findtype findtypemenu findloc findstring fstring geometry global entries sha1entry sha1string sha1but @@ -626,37 +1372,36 @@ proc makewindow {} { global bgcolor fgcolor bglist fglist diffcolors selectbgcolor global headctxmenu progresscanv progressitem progresscoords statusw global fprogitem fprogcoord lastprogupdate progupdatepending + global rprogitem rprogcoord global have_tk85 menu .bar - .bar add cascade -label "File" -menu .bar.file - .bar configure -font uifont + .bar add cascade -label [mc "File"] -menu .bar.file menu .bar.file - .bar.file add command -label "Update" -command updatecommits - .bar.file add command -label "Reread references" -command rereadrefs - .bar.file add command -label "List references" -command showrefs - .bar.file add command -label "Quit" -command doquit - .bar.file configure -font uifont + .bar.file add command -label [mc "Update"] -command updatecommits + .bar.file add command -label [mc "Reload"] -command reloadcommits + .bar.file add command -label [mc "Reread references"] -command rereadrefs + .bar.file add command -label [mc "List references"] -command showrefs + .bar.file add command -label [mc "Quit"] -command doquit menu .bar.edit - .bar add cascade -label "Edit" -menu .bar.edit - .bar.edit add command -label "Preferences" -command doprefs - .bar.edit configure -font uifont - - menu .bar.view -font uifont - .bar add cascade -label "View" -menu .bar.view - .bar.view add command -label "New view..." -command {newview 0} - .bar.view add command -label "Edit view..." -command editview \ + .bar add cascade -label [mc "Edit"] -menu .bar.edit + .bar.edit add command -label [mc "Preferences"] -command doprefs + + menu .bar.view + .bar add cascade -label [mc "View"] -menu .bar.view + .bar.view add command -label [mc "New view..."] -command {newview 0} + .bar.view add command -label [mc "Edit view..."] -command editview \ -state disabled - .bar.view add command -label "Delete view" -command delview -state disabled + .bar.view add command -label [mc "Delete view"] -command delview -state disabled .bar.view add separator - .bar.view add radiobutton -label "All files" -command {showview 0} \ + .bar.view add radiobutton -label [mc "All files"] -command {showview 0} \ -variable selectedview -value 0 menu .bar.help - .bar add cascade -label "Help" -menu .bar.help - .bar.help add command -label "About gitk" -command about - .bar.help add command -label "Key bindings" -command keys - .bar.help configure -font uifont + .bar add cascade -label [mc "Help"] -menu .bar.help + .bar.help add command -label [mc "About gitk"] -command about + .bar.help add command -label [mc "Key bindings"] -command keys + .bar.help configure . configure -menu .bar # the gui has upper and lower half, parts of a paned window. @@ -712,8 +1457,8 @@ proc makewindow {} { set sha1entry .tf.bar.sha1 set entries $sha1entry set sha1but .tf.bar.sha1label - button $sha1but -text "SHA1 ID: " -state disabled -relief flat \ - -command gotocommit -width 8 -font uifont + button $sha1but -text [mc "SHA1 ID: "] -state disabled -relief flat \ + -command gotocommit -width 8 $sha1but conf -disabledforeground [$sha1but cget -foreground] pack .tf.bar.sha1label -side left entry $sha1entry -width 40 -font textfont -textvariable sha1string @@ -745,35 +1490,35 @@ proc makewindow {} { # Status label and progress bar set statusw .tf.bar.status - label $statusw -width 15 -relief sunken -font uifont + label $statusw -width 15 -relief sunken pack $statusw -side left -padx 5 set h [expr {[font metrics uifont -linespace] + 2}] set progresscanv .tf.bar.progress canvas $progresscanv -relief sunken -height $h -borderwidth 2 set progressitem [$progresscanv create rect -1 0 0 $h -fill green] set fprogitem [$progresscanv create rect -1 0 0 $h -fill yellow] + set rprogitem [$progresscanv create rect -1 0 0 $h -fill red] pack $progresscanv -side right -expand 1 -fill x set progresscoords {0 0} set fprogcoord 0 + set rprogcoord 0 bind $progresscanv adjustprogress set lastprogupdate [clock clicks -milliseconds] set progupdatepending 0 # build up the bottom bar of upper window - label .tf.lbar.flabel -text "Find " -font uifont - button .tf.lbar.fnext -text "next" -command dofind -font uifont - button .tf.lbar.fprev -text "prev" -command {dofind 1} -font uifont - label .tf.lbar.flab2 -text " commit " -font uifont + label .tf.lbar.flabel -text "[mc "Find"] " + button .tf.lbar.fnext -text [mc "next"] -command {dofind 1 1} + button .tf.lbar.fprev -text [mc "prev"] -command {dofind -1 1} + label .tf.lbar.flab2 -text " [mc "commit"] " pack .tf.lbar.flabel .tf.lbar.fnext .tf.lbar.fprev .tf.lbar.flab2 \ -side left -fill y - set gdttype "containing:" + set gdttype [mc "containing:"] set gm [tk_optionMenu .tf.lbar.gdttype gdttype \ - "containing:" \ - "touching paths:" \ - "adding/removing string:"] + [mc "containing:"] \ + [mc "touching paths:"] \ + [mc "adding/removing string:"]] trace add variable gdttype write gdttype_change - $gm conf -font uifont - .tf.lbar.gdttype conf -font uifont pack .tf.lbar.gdttype -side left -fill y set findstring {} @@ -781,18 +1526,14 @@ proc makewindow {} { lappend entries $fstring entry $fstring -width 30 -font textfont -textvariable findstring trace add variable findstring write find_change - set findtype Exact + set findtype [mc "Exact"] set findtypemenu [tk_optionMenu .tf.lbar.findtype \ - findtype Exact IgnCase Regexp] + findtype [mc "Exact"] [mc "IgnCase"] [mc "Regexp"]] trace add variable findtype write findcom_change - .tf.lbar.findtype configure -font uifont - .tf.lbar.findtype.menu configure -font uifont - set findloc "All fields" - tk_optionMenu .tf.lbar.findloc findloc "All fields" Headline \ - Comments Author Committer + set findloc [mc "All fields"] + tk_optionMenu .tf.lbar.findloc findloc [mc "All fields"] [mc "Headline"] \ + [mc "Comments"] [mc "Author"] [mc "Committer"] trace add variable findloc write find_change - .tf.lbar.findloc configure -font uifont - .tf.lbar.findloc.menu configure -font uifont pack .tf.lbar.findloc -side right pack .tf.lbar.findtype -side right pack $fstring -side left -expand 1 -fill x @@ -819,22 +1560,20 @@ proc makewindow {} { frame .bleft.top frame .bleft.mid - button .bleft.top.search -text "Search" -command dosearch \ - -font uifont + button .bleft.top.search -text [mc "Search"] -command dosearch pack .bleft.top.search -side left -padx 5 set sstring .bleft.top.sstring entry $sstring -width 20 -font textfont -textvariable searchstring lappend entries $sstring trace add variable searchstring write incrsearch pack $sstring -side left -expand 1 -fill x - radiobutton .bleft.mid.diff -text "Diff" \ + radiobutton .bleft.mid.diff -text [mc "Diff"] \ -command changediffdisp -variable diffelide -value {0 0} - radiobutton .bleft.mid.old -text "Old version" \ + radiobutton .bleft.mid.old -text [mc "Old version"] \ -command changediffdisp -variable diffelide -value {0 1} - radiobutton .bleft.mid.new -text "New version" \ + radiobutton .bleft.mid.new -text [mc "New version"] \ -command changediffdisp -variable diffelide -value {1 0} - label .bleft.mid.labeldiffcontext -text " Lines of context: " \ - -font uifont + label .bleft.mid.labeldiffcontext -text " [mc "Lines of context"]: " pack .bleft.mid.diff .bleft.mid.old .bleft.mid.new -side left spinbox .bleft.mid.diffcontext -width 5 -font textfont \ -from 1 -increment 1 -to 10000000 \ @@ -892,12 +1631,10 @@ proc makewindow {} { # lower right frame .bright frame .bright.mode - radiobutton .bright.mode.patch -text "Patch" \ + radiobutton .bright.mode.patch -text [mc "Patch"] \ -command reselectline -variable cmitmode -value "patch" - .bright.mode.patch configure -font uifont - radiobutton .bright.mode.tree -text "Tree" \ + radiobutton .bright.mode.tree -text [mc "Tree"] \ -command reselectline -variable cmitmode -value "tree" - .bright.mode.tree configure -font uifont grid .bright.mode.patch .bright.mode.tree -sticky ew pack .bright.mode -side top -fill x set cflist .bright.cfiles @@ -943,6 +1680,12 @@ proc makewindow {} { } else { bindall "allcanvs yview scroll -5 units" bindall "allcanvs yview scroll 5 units" + if {[tk windowingsystem] eq "aqua"} { + bindall { + set delta [expr {- (%D)}] + allcanvs yview scroll $delta units + } + } } bindall <2> "canvscan mark %W %x %y" bindall "canvscan dragto %W %x %y" @@ -950,6 +1693,8 @@ proc makewindow {} { bindkey sellastline bind . "selnextline -1" bind . "selnextline 1" + bind . "dofind -1 0" + bind . "dofind 1 0" bindkey "goforw" bindkey "goback" bind . "selnextpage -1" @@ -974,14 +1719,14 @@ 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 1} - bindkey {findnext 0} - bindkey ? findprev + bindkey / {dofind 1 1} + bindkey {dofind 1 1} + bindkey ? {dofind -1 1} bindkey f nextfile bindkey updatecommits bind . <$M1B-q> doquit - bind . <$M1B-f> dofind - bind . <$M1B-g> {findnext 0} + bind . <$M1B-f> {dofind 1 1} + bind . <$M1B-g> {dofind 1 0} bind . <$M1B-r> dosearchback bind . <$M1B-s> dosearch bind . <$M1B-equal> {incrfont 1} @@ -990,7 +1735,7 @@ proc makewindow {} { bind . <$M1B-KP_Subtract> {incrfont -1} wm protocol . WM_DELETE_WINDOW doquit bind . "click %W" - bind $fstring dofind + bind $fstring {dofind 1 1} bind $sha1entry gotocommit bind $sha1entry <> clearsha1 bind $cflist <1> {sel_flist %W %x %y; break} @@ -1004,43 +1749,43 @@ proc makewindow {} { set rowctxmenu .rowctxmenu menu $rowctxmenu -tearoff 0 - $rowctxmenu add command -label "Diff this -> selected" \ + $rowctxmenu add command -label [mc "Diff this -> selected"] \ -command {diffvssel 0} - $rowctxmenu add command -label "Diff selected -> this" \ + $rowctxmenu add command -label [mc "Diff selected -> this"] \ -command {diffvssel 1} - $rowctxmenu add command -label "Make patch" -command mkpatch - $rowctxmenu add command -label "Create tag" -command mktag - $rowctxmenu add command -label "Write commit to file" -command writecommit - $rowctxmenu add command -label "Create new branch" -command mkbranch - $rowctxmenu add command -label "Cherry-pick this commit" \ + $rowctxmenu add command -label [mc "Make patch"] -command mkpatch + $rowctxmenu add command -label [mc "Create tag"] -command mktag + $rowctxmenu add command -label [mc "Write commit to file"] -command writecommit + $rowctxmenu add command -label [mc "Create new branch"] -command mkbranch + $rowctxmenu add command -label [mc "Cherry-pick this commit"] \ -command cherrypick - $rowctxmenu add command -label "Reset HEAD branch to here" \ + $rowctxmenu add command -label [mc "Reset HEAD branch to here"] \ -command resethead set fakerowmenu .fakerowmenu menu $fakerowmenu -tearoff 0 - $fakerowmenu add command -label "Diff this -> selected" \ + $fakerowmenu add command -label [mc "Diff this -> selected"] \ -command {diffvssel 0} - $fakerowmenu add command -label "Diff selected -> this" \ + $fakerowmenu add command -label [mc "Diff selected -> this"] \ -command {diffvssel 1} - $fakerowmenu add command -label "Make patch" -command mkpatch -# $fakerowmenu add command -label "Commit" -command {mkcommit 0} -# $fakerowmenu add command -label "Commit all" -command {mkcommit 1} -# $fakerowmenu add command -label "Revert local changes" -command revertlocal + $fakerowmenu add command -label [mc "Make patch"] -command mkpatch +# $fakerowmenu add command -label [mc "Commit"] -command {mkcommit 0} +# $fakerowmenu add command -label [mc "Commit all"] -command {mkcommit 1} +# $fakerowmenu add command -label [mc "Revert local changes"] -command revertlocal set headctxmenu .headctxmenu menu $headctxmenu -tearoff 0 - $headctxmenu add command -label "Check out this branch" \ + $headctxmenu add command -label [mc "Check out this branch"] \ -command cobranch - $headctxmenu add command -label "Remove this branch" \ + $headctxmenu add command -label [mc "Remove this branch"] \ -command rmbranch global flist_menu set flist_menu .flistctxmenu menu $flist_menu -tearoff 0 - $flist_menu add command -label "Highlight this too" \ + $flist_menu add command -label [mc "Highlight this too"] \ -command {flist_hl 0} - $flist_menu add command -label "Highlight this only" \ + $flist_menu add command -label [mc "Highlight this only"] \ -command {flist_hl 1} } @@ -1077,7 +1822,7 @@ proc canvscan {op w x y} { proc scrollcanv {cscroll f0 f1} { $cscroll set $f0 $f1 - drawfrac $f0 $f1 + drawvisible flushhighlights } @@ -1110,6 +1855,7 @@ proc click {w} { proc adjustprogress {} { global progresscanv progressitem progresscoords global fprogitem fprogcoord lastprogupdate progupdatepending + global rprogitem rprogcoord set w [expr {[winfo width $progresscanv] - 4}] set x0 [expr {$w * [lindex $progresscoords 0]}] @@ -1117,6 +1863,7 @@ proc adjustprogress {} { set h [winfo height $progresscanv] $progresscanv coords $progressitem $x0 0 $x1 $h $progresscanv coords $fprogitem 0 0 [expr {$w * $fprogcoord}] $h + $progresscanv coords $rprogitem 0 0 [expr {$w * $rprogcoord}] $h set now [clock clicks -milliseconds] if {$now >= $lastprogupdate + 100} { set progupdatepending 0 @@ -1142,7 +1889,7 @@ proc savestuff {w} { global stuffsaved findmergefiles maxgraphpct global maxwidth showneartags showlocalchanges global viewname viewfiles viewargs viewperm nextviewnum - global cmitmode wrapcomment datetimeformat + global cmitmode wrapcomment datetimeformat limitdiffs global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor if {$stuffsaved} return @@ -1161,6 +1908,7 @@ proc savestuff {w} { puts $f [list set showneartags $showneartags] puts $f [list set showlocalchanges $showlocalchanges] puts $f [list set datetimeformat $datetimeformat] + puts $f [list set limitdiffs $limitdiffs] puts $f [list set bgcolor $bgcolor] puts $f [list set fgcolor $fgcolor] puts $f [list set colors $colors] @@ -1263,26 +2011,23 @@ proc about {} { return } toplevel $w - wm title $w "About gitk" - message $w.m -text { + wm title $w [mc "About gitk"] + message $w.m -text [mc " Gitk - a commit viewer for git -Copyright © 2005-2006 Paul Mackerras +Copyright © 2005-2006 Paul Mackerras -Use and redistribute under the terms of the GNU General Public License} \ +Use and redistribute under the terms of the GNU General Public License"] \ -justify center -aspect 400 -border 2 -bg white -relief groove pack $w.m -side top -fill x -padx 2 -pady 2 - $w.m configure -font uifont - button $w.ok -text Close -command "destroy $w" -default active + button $w.ok -text [mc "Close"] -command "destroy $w" -default active pack $w.ok -side bottom - $w.ok configure -font uifont bind $w "focus $w.ok" bind $w "destroy $w" bind $w "destroy $w" } proc keys {} { - global uifont set w .keys if {[winfo exists $w]} { raise $w @@ -1294,8 +2039,8 @@ proc keys {} { set M1T Ctrl } toplevel $w - wm title $w "Gitk key bindings" - message $w.m -text " + wm title $w [mc "Gitk key bindings"] + message $w.m -text [mc " Gitk key bindings: <$M1T-Q> Quit @@ -1313,8 +2058,8 @@ Gitk key bindings: <$M1T-Down> Scroll commit list down one line <$M1T-PageUp> Scroll commit list up one page <$M1T-PageDown> Scroll commit list down one page - Move to previous highlighted line - Move to next highlighted line + Find backwards (upwards, later commits) + Find forwards (downwards, earlier commits) , b Scroll diff view up one page Scroll diff view up one page Scroll diff view down one page @@ -1333,13 +2078,11 @@ f Scroll diff view to next file <$M1T-KP-> Decrease font size <$M1T-minus> Decrease font size Update -" \ +"] \ -justify left -bg white -border 2 -relief groove pack $w.m -side top -fill both -padx 2 -pady 2 - $w.m configure -font uifont - button $w.ok -text Close -command "destroy $w" -default active + button $w.ok -text [mc "Close"] -command "destroy $w" -default active pack $w.ok -side bottom - $w.ok configure -font uifont bind $w "focus $w.ok" bind $w "destroy $w" bind $w "destroy $w" @@ -1629,7 +2372,7 @@ image create bitmap reficon-o -background black -foreground "#ddddff" \ -data $rectdata -maskdata $rectmask proc init_flist {first} { - global cflist cflist_top selectedline difffilestart + global cflist cflist_top difffilestart $cflist conf -state normal $cflist delete 0.0 end @@ -1729,12 +2472,12 @@ proc flist_hl {only} { global flist_menu_file findstring gdttype set x [shellquote $flist_menu_file] - if {$only || $findstring eq {} || $gdttype ne "touching paths:"} { + if {$only || $findstring eq {} || $gdttype ne [mc "touching paths:"]} { set findstring $x } else { append findstring " " $x } - set gdttype "touching paths:" + set gdttype [mc "touching paths:"] } # Functions for adding and removing shell-type quoting @@ -1834,7 +2577,7 @@ proc shellsplit {str} { # Code to implement multiple views proc newview {ishighlight} { - global nextviewnum newviewname newviewperm uifont newishighlight + global nextviewnum newviewname newviewperm newishighlight global newviewargs revtreeargs set newishighlight $ishighlight @@ -1846,7 +2589,7 @@ proc newview {ishighlight} { set newviewname($nextviewnum) "View $nextviewnum" set newviewperm($nextviewnum) 0 set newviewargs($nextviewnum) [shellarglist $revtreeargs] - vieweditor $top $nextviewnum "Gitk view definition" + vieweditor $top $nextviewnum [mc "Gitk view definition"] } proc editview {} { @@ -1866,27 +2609,26 @@ proc editview {} { } proc vieweditor {top n title} { - global newviewname newviewperm viewfiles - global uifont + global newviewname newviewperm viewfiles bgcolor toplevel $top wm title $top $title - label $top.nl -text "Name" -font uifont - entry $top.name -width 20 -textvariable newviewname($n) -font uifont + label $top.nl -text [mc "Name"] + entry $top.name -width 20 -textvariable newviewname($n) grid $top.nl $top.name -sticky w -pady 5 - checkbutton $top.perm -text "Remember this view" -variable newviewperm($n) \ - -font uifont + checkbutton $top.perm -text [mc "Remember this view"] \ + -variable newviewperm($n) grid $top.perm - -pady 5 -sticky w - message $top.al -aspect 1000 -font uifont \ - -text "Commits to include (arguments to git rev-list):" + message $top.al -aspect 1000 \ + -text [mc "Commits to include (arguments to git rev-list):"] grid $top.al - -sticky w -pady 5 entry $top.args -width 50 -textvariable newviewargs($n) \ - -background white -font uifont + -background $bgcolor grid $top.args - -sticky ew -padx 5 - message $top.l -aspect 1000 -font uifont \ - -text "Enter files and directories to include, one per line:" + message $top.l -aspect 1000 \ + -text [mc "Enter files and directories to include, one per line:"] grid $top.l - -sticky w - text $top.t -width 40 -height 10 -background white -font uifont + text $top.t -width 40 -height 10 -background $bgcolor -font uifont if {[info exists viewfiles($n)]} { foreach f $viewfiles($n) { $top.t insert end $f @@ -1897,10 +2639,8 @@ proc vieweditor {top n title} { } grid $top.t - -sticky ew -padx 5 frame $top.buts - button $top.buts.ok -text "OK" -command [list newviewok $top $n] \ - -font uifont - button $top.buts.can -text "Cancel" -command [list destroy $top] \ - -font uifont + button $top.buts.ok -text [mc "OK"] -command [list newviewok $top $n] + button $top.buts.can -text [mc "Cancel"] -command [list destroy $top] grid $top.buts.ok $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -1933,7 +2673,7 @@ proc newviewok {top n} { if {[catch { set newargs [shellsplit $newviewargs($n)] } err]} { - error_popup "Error in commit selection arguments: $err" + error_popup "[mc "Error in commit selection arguments:"] $err" wm raise $top focus $top return @@ -1972,7 +2712,7 @@ proc newviewok {top n} { set viewfiles($n) $files set viewargs($n) $newargs if {$curview == $n} { - run updatecommits + run reloadcommits } } } @@ -1980,15 +2720,14 @@ proc newviewok {top n} { } proc delview {} { - global curview viewdata viewperm hlview selectedhlview + global curview viewperm hlview selectedhlview if {$curview == 0} return if {[info exists hlview] && $hlview == $curview} { - set selectedhlview None + set selectedhlview [mc "None"] unset hlview } allviewmenus $curview delete - set viewdata($curview) {} set viewperm($curview) 0 showview 0 } @@ -2002,52 +2741,30 @@ proc addviewmenu {n} { # -command [list addvhighlight $n] -variable selectedhlview } -proc flatten {var} { - global $var - - set ret {} - foreach i [array names $var] { - lappend ret $i [set $var\($i\)] - } - return $ret -} - -proc unflatten {var l} { - global $var - - catch {unset $var} - foreach {i v} $l { - set $var\($i\) $v - } -} - proc showview {n} { - global curview viewdata viewfiles + global curview viewfiles cached_commitrow ordertok global displayorder parentlist rowidlist rowisopt rowfinal - global colormap rowtextx commitrow nextcolor canvxmax - global numcommits commitlisted + global colormap rowtextx nextcolor canvxmax + global numcommits viewcomplete global selectedline currentid canv canvy0 global treediffs - global pending_select phase + global pending_select global commitidx - global commfd global selectedview selectfirst - global vparentlist vdisporder vcmitlisted global hlview selectedhlview commitinterest if {$n == $curview} return set selid {} + set ymax [lindex [$canv cget -scrollregion] 3] + set span [$canv yview] + set ytop [expr {[lindex $span 0] * $ymax}] + set ybot [expr {[lindex $span 1] * $ymax}] + set yscreen [expr {($ybot - $ytop) / 2}] if {[info exists selectedline]} { set selid $currentid set y [yc $selectedline] - set ymax [lindex [$canv cget -scrollregion] 3] - set span [$canv yview] - set ytop [expr {[lindex $span 0] * $ymax}] - set ybot [expr {[lindex $span 1] * $ymax}] if {$ytop < $y && $y < $ybot} { set yscreen [expr {$y - $ytop}] - } else { - set yscreen [expr {($ybot - $ytop) / 2}] } } elseif {[info exists pending_select]} { set selid $pending_select @@ -2055,32 +2772,23 @@ proc showview {n} { } unselectline normalline - if {$curview >= 0} { - set vparentlist($curview) $parentlist - set vdisporder($curview) $displayorder - set vcmitlisted($curview) $commitlisted - if {$phase ne {} || - ![info exists viewdata($curview)] || - [lindex $viewdata($curview) 0] ne {}} { - set viewdata($curview) \ - [list $phase $rowidlist $rowisopt $rowfinal] - } - } catch {unset treediffs} clear_display if {[info exists hlview] && $hlview == $n} { unset hlview - set selectedhlview None + set selectedhlview [mc "None"] } catch {unset commitinterest} + catch {unset cached_commitrow} + catch {unset ordertok} set curview $n set selectedview $n - .bar.view entryconf Edit* -state [expr {$n == 0? "disabled": "normal"}] - .bar.view entryconf Delete* -state [expr {$n == 0? "disabled": "normal"}] + .bar.view entryconf [mc "Edit view..."] -state [expr {$n == 0? "disabled": "normal"}] + .bar.view entryconf [mc "Delete view"] -state [expr {$n == 0? "disabled": "normal"}] run refill_reflist - if {![info exists viewdata($n)]} { + if {![info exists viewcomplete($n)]} { if {$selid ne {}} { set pending_select $selid } @@ -2088,14 +2796,11 @@ proc showview {n} { return } - set v $viewdata($n) - set phase [lindex $v 0] - set displayorder $vdisporder($n) - set parentlist $vparentlist($n) - set commitlisted $vcmitlisted($n) - set rowidlist [lindex $v 1] - set rowisopt [lindex $v 2] - set rowfinal [lindex $v 3] + set displayorder {} + set parentlist {} + set rowidlist {} + set rowisopt {} + set rowfinal {} set numcommits $commitidx($n) catch {unset colormap} @@ -2108,8 +2813,8 @@ proc showview {n} { set yf 0 set row {} set selectfirst 0 - if {$selid ne {} && [info exists commitrow($n,$selid)]} { - set row $commitrow($n,$selid) + if {$selid ne {} && [commitinview $selid $n]} { + set row [rowofcommit $selid] # try to get the selected row in the same position on the screen set ymax [lindex [$canv cget -scrollregion] 3] set ytop [expr {[yc $row] - $yscreen}] @@ -2132,32 +2837,31 @@ proc showview {n} { set selectfirst 1 } } - if {$phase ne {}} { - if {$phase eq "getcommits"} { - show_status "Reading commits..." + if {!$viewcomplete($n)} { + if {$numcommits == 0} { + show_status [mc "Reading commits..."] } - run chewcommits $n } elseif {$numcommits == 0} { - show_status "No commits selected" + show_status [mc "No commits selected"] } } # Stuff relating to the highlighting facility -proc ishighlighted {row} { +proc ishighlighted {id} { global vhighlights fhighlights nhighlights rhighlights - if {[info exists nhighlights($row)] && $nhighlights($row) > 0} { - return $nhighlights($row) + if {[info exists nhighlights($id)] && $nhighlights($id) > 0} { + return $nhighlights($id) } - if {[info exists vhighlights($row)] && $vhighlights($row) > 0} { - return $vhighlights($row) + if {[info exists vhighlights($id)] && $vhighlights($id) > 0} { + return $vhighlights($id) } - if {[info exists fhighlights($row)] && $fhighlights($row) > 0} { - return $fhighlights($row) + if {[info exists fhighlights($id)] && $fhighlights($id) > 0} { + return $fhighlights($id) } - if {[info exists rhighlights($row)] && $rhighlights($row) > 0} { - return $rhighlights($row) + if {[info exists rhighlights($id)] && $rhighlights($id) > 0} { + return $rhighlights($id) } return 0 } @@ -2195,7 +2899,7 @@ proc unbolden {} { set stillbold {} foreach row $boldrows { - if {![ishighlighted $row]} { + if {![ishighlighted [commitonrow $row]]} { bolden $row mainfont } else { lappend stillbold $row @@ -2205,17 +2909,13 @@ proc unbolden {} { } proc addvhighlight {n} { - global hlview curview viewdata vhl_done vhighlights commitidx + global hlview viewcomplete curview vhl_done commitidx if {[info exists hlview]} { delvhighlight } set hlview $n - if {$n != $curview && ![info exists viewdata($n)]} { - set viewdata($n) [list getcommits {{}} 0 0 0] - set vparentlist($n) {} - set vdisporder($n) {} - set vcmitlisted($n) {} + if {$n != $curview && ![info exists viewcomplete($n)]} { start_rev_list $n } set vhl_done $commitidx($hlview) @@ -2234,27 +2934,21 @@ proc delvhighlight {} { } proc vhighlightmore {} { - global hlview vhl_done commitidx vhighlights - global displayorder vdisporder curview + global hlview vhl_done commitidx vhighlights curview set max $commitidx($hlview) - if {$hlview == $curview} { - set disp $displayorder - } else { - set disp $vdisporder($hlview) - } set vr [visiblerows] set r0 [lindex $vr 0] set r1 [lindex $vr 1] for {set i $vhl_done} {$i < $max} {incr i} { - set id [lindex $disp $i] - if {[info exists commitrow($curview,$id)]} { - set row $commitrow($curview,$id) + set id [commitonrow $i $hlview] + if {[commitinview $id $curview]} { + set row [rowofcommit $id] if {$r0 <= $row && $row <= $r1} { if {![highlighted $row]} { bolden $row mainfontbold } - set vhighlights($row) 1 + set vhighlights($id) 1 } } } @@ -2262,15 +2956,15 @@ proc vhighlightmore {} { } proc askvhighlight {row id} { - global hlview vhighlights commitrow iddrawn + global hlview vhighlights iddrawn - if {[info exists commitrow($hlview,$id)]} { - if {[info exists iddrawn($id)] && ![ishighlighted $row]} { + if {[commitinview $id $hlview]} { + if {[info exists iddrawn($id)] && ![ishighlighted $id]} { bolden $row mainfontbold } - set vhighlights($row) 1 + set vhighlights($id) 1 } else { - set vhighlights($row) 0 + set vhighlights($id) 0 } } @@ -2299,7 +2993,7 @@ proc gdttype_change {name ix op} { stopfinding if {$findstring ne {}} { - if {$gdttype eq "containing:"} { + if {$gdttype eq [mc "containing:"]} { if {$highlight_files ne {}} { set highlight_files {} hfiles_change @@ -2322,7 +3016,7 @@ proc find_change {name ix op} { global gdttype findstring highlight_files stopfinding - if {$gdttype eq "containing:"} { + if {$gdttype eq [mc "containing:"]} { findcom_change } else { if {$highlight_files ne $findstring} { @@ -2346,9 +3040,9 @@ proc findcom_change args { catch {unset nhighlights} unbolden unmarkmatches - if {$gdttype ne "containing:" || $findstring eq {}} { + if {$gdttype ne [mc "containing:"] || $findstring eq {}} { set findpattern {} - } elseif {$findtype eq "Regexp"} { + } elseif {$findtype eq [mc "Regexp"]} { set findpattern $findstring } else { set e [string map {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \ @@ -2374,12 +3068,12 @@ proc makepatterns {l} { proc do_file_hl {serial} { global highlight_files filehighlight highlight_paths gdttype fhl_list - if {$gdttype eq "touching paths:"} { + if {$gdttype eq [mc "touching paths:"]} { if {[catch {set paths [shellsplit $highlight_files]}]} return set highlight_paths [makepatterns $paths] highlight_filelist set gdtargs [concat -- $paths] - } elseif {$gdttype eq "adding/removing string:"} { + } elseif {$gdttype eq [mc "adding/removing string:"]} { set gdtargs [list "-S$highlight_files"] } else { # must be "containing:", i.e. we're searching commit info @@ -2408,12 +3102,12 @@ proc askfilehighlight {row id} { global filehighlight fhighlights fhl_list lappend fhl_list $id - set fhighlights($row) -1 + set fhighlights($id) -1 puts $filehighlight $id } proc readfhighlight {} { - global filehighlight fhighlights commitrow curview iddrawn + global filehighlight fhighlights curview iddrawn global fhl_list find_dirn if {![info exists filehighlight]} { @@ -2426,18 +3120,16 @@ proc readfhighlight {} { if {$i < 0} continue for {set j 0} {$j < $i} {incr j} { set id [lindex $fhl_list $j] - if {[info exists commitrow($curview,$id)]} { - set fhighlights($commitrow($curview,$id)) 0 - } + set fhighlights($id) 0 } set fhl_list [lrange $fhl_list [expr {$i+1}] end] if {$line eq {}} continue - if {![info exists commitrow($curview,$line)]} continue - set row $commitrow($curview,$line) - if {[info exists iddrawn($line)] && ![ishighlighted $row]} { + if {![commitinview $line $curview]} continue + set row [rowofcommit $line] + if {[info exists iddrawn($line)] && ![ishighlighted $line]} { bolden $row mainfontbold } - set fhighlights($row) 1 + set fhighlights($line) 1 } if {[eof $filehighlight]} { # strange... @@ -2447,11 +3139,7 @@ proc readfhighlight {} { return 0 } if {[info exists find_dirn]} { - if {$find_dirn > 0} { - run findmore - } else { - run findmorerev - } + run findmore } return 1 } @@ -2459,9 +3147,9 @@ proc readfhighlight {} { proc doesmatch {f} { global findtype findpattern - if {$findtype eq "Regexp"} { + if {$findtype eq [mc "Regexp"]} { return [regexp $findpattern $f] - } elseif {$findtype eq "IgnCase"} { + } elseif {$findtype eq [mc "IgnCase"]} { return [string match -nocase $findpattern $f] } else { return [string match $findpattern $f] @@ -2478,11 +3166,11 @@ proc askfindhighlight {row id} { } set info $commitinfo($id) set isbold 0 - set fldtypes {Headline Author Date Committer CDate Comments} + set fldtypes [list [mc Headline] [mc Author] [mc Date] [mc Committer] [mc CDate] [mc Comments]] foreach f $info ty $fldtypes { - if {($findloc eq "All fields" || $findloc eq $ty) && + if {($findloc eq [mc "All fields"] || $findloc eq $ty) && [doesmatch $f]} { - if {$ty eq "Author"} { + if {$ty eq [mc "Author"]} { set isbold 2 break } @@ -2490,7 +3178,7 @@ proc askfindhighlight {row id} { } } if {$isbold && [info exists iddrawn($id)]} { - if {![ishighlighted $row]} { + if {![ishighlighted $id]} { bolden $row mainfontbold if {$isbold > 1} { bolden_name $row mainfontbold @@ -2500,7 +3188,7 @@ proc askfindhighlight {row id} { markrowmatches $row $id } } - set nhighlights($row) $isbold + set nhighlights($id) $isbold } proc markrowmatches {row id} { @@ -2510,14 +3198,14 @@ proc markrowmatches {row id} { set author [lindex $commitinfo($id) 1] $canv delete match$row $canv2 delete match$row - if {$findloc eq "All fields" || $findloc eq "Headline"} { + if {$findloc eq [mc "All fields"] || $findloc eq [mc "Headline"]} { set m [findmatches $headline] if {$m ne {}} { markmatches $canv $row $headline $linehtag($row) $m \ [$canv itemcget $linehtag($row) -font] $row } } - if {$findloc eq "All fields" || $findloc eq "Author"} { + if {$findloc eq [mc "All fields"] || $findloc eq [mc "Author"]} { set m [findmatches $author] if {$m ne {}} { markmatches $canv2 $row $author $linentag($row) $m \ @@ -2530,7 +3218,7 @@ proc vrel_change {name ix op} { global highlight_related rhighlight_none - if {$highlight_related ne "None"} { + if {$highlight_related ne [mc "None"]} { run drawvisible } } @@ -2538,13 +3226,13 @@ proc vrel_change {name ix op} { # prepare for testing whether commits are descendents or ancestors of a proc rhighlight_sel {a} { global descendent desc_todo ancestor anc_todo - global highlight_related rhighlights + global highlight_related catch {unset descendent} set desc_todo [list $a] catch {unset ancestor} set anc_todo [list $a] - if {$highlight_related ne "None"} { + if {$highlight_related ne [mc "None"]} { rhighlight_none run drawvisible } @@ -2558,16 +3246,16 @@ proc rhighlight_none {} { } proc is_descendent {a} { - global curview children commitrow descendent desc_todo + global curview children descendent desc_todo set v $curview - set la $commitrow($v,$a) + set la [rowofcommit $a] set todo $desc_todo set leftover {} set done 0 for {set i 0} {$i < [llength $todo]} {incr i} { set do [lindex $todo $i] - if {$commitrow($v,$do) < $la} { + if {[rowofcommit $do] < $la} { lappend leftover $do continue } @@ -2590,20 +3278,20 @@ proc is_descendent {a} { } proc is_ancestor {a} { - global curview parentlist commitrow ancestor anc_todo + global curview parents ancestor anc_todo set v $curview - set la $commitrow($v,$a) + set la [rowofcommit $a] set todo $anc_todo set leftover {} set done 0 for {set i 0} {$i < [llength $todo]} {incr i} { set do [lindex $todo $i] - if {![info exists commitrow($v,$do)] || $commitrow($v,$do) > $la} { + if {![commitinview $do $v] || [rowofcommit $do] > $la} { lappend leftover $do continue } - foreach np [lindex $parentlist $commitrow($v,$do)] { + foreach np $parents($v,$do) { if {![info exists ancestor($np)]} { set ancestor($np) 1 lappend todo $np @@ -2627,29 +3315,29 @@ proc askrelhighlight {row id} { if {![info exists selectedline]} return set isbold 0 - if {$highlight_related eq "Descendent" || - $highlight_related eq "Not descendent"} { + if {$highlight_related eq [mc "Descendent"] || + $highlight_related eq [mc "Not descendent"]} { if {![info exists descendent($id)]} { is_descendent $id } - if {$descendent($id) == ($highlight_related eq "Descendent")} { + if {$descendent($id) == ($highlight_related eq [mc "Descendent"])} { set isbold 1 } - } elseif {$highlight_related eq "Ancestor" || - $highlight_related eq "Not ancestor"} { + } elseif {$highlight_related eq [mc "Ancestor"] || + $highlight_related eq [mc "Not ancestor"]} { if {![info exists ancestor($id)]} { is_ancestor $id } - if {$ancestor($id) == ($highlight_related eq "Ancestor")} { + if {$ancestor($id) == ($highlight_related eq [mc "Ancestor"])} { set isbold 1 } } if {[info exists iddrawn($id)]} { - if {$isbold && ![ishighlighted $row]} { + if {$isbold && ![ishighlighted $id]} { bolden $row mainfontbold } } - set rhighlights($row) $isbold + set rhighlights($id) $isbold } # Graph layout functions @@ -2665,55 +3353,97 @@ proc shortids {ids} { lappend res $id } } - return $res -} - -proc ntimes {n o} { - set ret {} - set o [list $o] - for {set mask 1} {$mask <= $n} {incr mask $mask} { - if {($n & $mask) != 0} { - set ret [concat $ret $o] - } - set o [concat $o $o] + return $res +} + +proc ntimes {n o} { + set ret {} + set o [list $o] + for {set mask 1} {$mask <= $n} {incr mask $mask} { + if {($n & $mask) != 0} { + set ret [concat $ret $o] + } + set o [concat $o $o] + } + return $ret +} + +proc ordertoken {id} { + global ordertok curview varcid varcstart varctok curview parents children + global nullid nullid2 + + if {[info exists ordertok($id)]} { + return $ordertok($id) + } + set origid $id + set todo {} + while {1} { + if {[info exists varcid($curview,$id)]} { + set a $varcid($curview,$id) + set p [lindex $varcstart($curview) $a] + } else { + set p [lindex $children($curview,$id) 0] + } + if {[info exists ordertok($p)]} { + set tok $ordertok($p) + break + } + set id [first_real_child $curview,$p] + if {$id eq {}} { + # it's a root + set tok [lindex $varctok($curview) $a] + break + } + if {[llength $parents($curview,$id)] == 1} { + lappend todo [list $p {}] + } else { + set j [lsearch -exact $parents($curview,$id) $p] + if {$j < 0} { + puts "oops didn't find [shortids $p] in parents of [shortids $id]" + } + lappend todo [list $p [strrep $j]] + } + } + for {set i [llength $todo]} {[incr i -1] >= 0} {} { + set p [lindex $todo $i 0] + append tok [lindex $todo $i 1] + set ordertok($p) $tok } - return $ret + set ordertok($origid) $tok + return $tok } # Work out where id should go in idlist so that order-token # values increase from left to right proc idcol {idlist id {i 0}} { - global ordertok curview - - set t $ordertok($curview,$id) - if {$i >= [llength $idlist] || - $t < $ordertok($curview,[lindex $idlist $i])} { + set t [ordertoken $id] + if {$i < 0} { + set i 0 + } + if {$i >= [llength $idlist] || $t < [ordertoken [lindex $idlist $i]]} { if {$i > [llength $idlist]} { set i [llength $idlist] } - while {[incr i -1] >= 0 && - $t < $ordertok($curview,[lindex $idlist $i])} {} + while {[incr i -1] >= 0 && $t < [ordertoken [lindex $idlist $i]]} {} incr i } else { - if {$t > $ordertok($curview,[lindex $idlist $i])} { + if {$t > [ordertoken [lindex $idlist $i]]} { while {[incr i] < [llength $idlist] && - $t >= $ordertok($curview,[lindex $idlist $i])} {} + $t >= [ordertoken [lindex $idlist $i]]} {} } } return $i } proc initlayout {} { - global rowidlist rowisopt rowfinal displayorder commitlisted + global rowidlist rowisopt rowfinal displayorder parentlist global numcommits canvxmax canv global nextcolor - global parentlist global colormap rowtextx global selectfirst set numcommits 0 set displayorder {} - set commitlisted {} set parentlist {} set nextcolor 0 set rowidlist {} @@ -2754,30 +3484,20 @@ proc visiblerows {} { } proc layoutmore {} { - global commitidx viewcomplete numcommits - global uparrowlen downarrowlen mingaplen curview - - set show $commitidx($curview) - if {$show > $numcommits || $viewcomplete($curview)} { - showstuff $show $viewcomplete($curview) - } -} - -proc showstuff {canshow last} { - global numcommits commitrow pending_select selectedline curview - global mainheadid displayorder selectfirst - global lastscrollset commitinterest + global commitidx viewcomplete curview + global numcommits pending_select selectedline curview + global selectfirst lastscrollset commitinterest + set canshow $commitidx($curview) + if {$canshow <= $numcommits && !$viewcomplete($curview)} return if {$numcommits == 0} { - global phase - set phase "incrdraw" allcanvs delete all } set r0 $numcommits set prev $numcommits set numcommits $canshow set t [clock clicks -milliseconds] - if {$prev < 100 || $last || $t - $lastscrollset > 500} { + if {$prev < 100 || $viewcomplete($curview) || $t - $lastscrollset > 500} { set lastscrollset $t setcanvscroll } @@ -2790,9 +3510,8 @@ proc showstuff {canshow last} { drawcommits $r0 $r1 } if {[info exists pending_select] && - [info exists commitrow($curview,$pending_select)] && - $commitrow($curview,$pending_select) < $numcommits} { - selectline $commitrow($curview,$pending_select) 1 + [commitinview $pending_select $curview]} { + selectline [rowofcommit $pending_select] 1 } if {$selectfirst} { if {[info exists selectedline] || [info exists pending_select]} { @@ -2806,49 +3525,40 @@ proc showstuff {canshow last} { } proc doshowlocalchanges {} { - global curview mainheadid phase commitrow + global curview mainheadid - if {[info exists commitrow($curview,$mainheadid)] && - ($phase eq {} || $commitrow($curview,$mainheadid) < $numcommits - 1)} { + if {[commitinview $mainheadid $curview]} { dodiffindex - } elseif {$phase ne {}} { - lappend commitinterest($mainheadid) {} + } else { + lappend commitinterest($mainheadid) {dodiffindex} } } proc dohidelocalchanges {} { - global localfrow localirow lserial + global nullid nullid2 lserial curview - if {$localfrow >= 0} { - removerow $localfrow - set localfrow -1 - if {$localirow > 0} { - incr localirow -1 - } + if {[commitinview $nullid $curview]} { + removerow $nullid $curview } - if {$localirow >= 0} { - removerow $localirow - set localirow -1 + if {[commitinview $nullid2 $curview]} { + removerow $nullid2 $curview } incr lserial } # spawn off a process to do git diff-index --cached HEAD proc dodiffindex {} { - global localirow localfrow lserial showlocalchanges + global lserial showlocalchanges if {!$showlocalchanges} return incr lserial - set localfrow -1 - set localirow -1 set fd [open "|git diff-index --cached HEAD" r] fconfigure $fd -blocking 0 filerun $fd [list readdiffindex $fd $lserial] } proc readdiffindex {fd serial} { - global localirow commitrow mainheadid nullid2 curview - global commitinfo commitdata lserial + global mainheadid nullid nullid2 curview commitinfo commitdata lserial set isdiff 1 if {[gets $fd line] < 0} { @@ -2860,26 +3570,32 @@ proc readdiffindex {fd serial} { # we only need to see one line and we don't really care what it says... close $fd - # now see if there are any local changes not checked in to the index - if {$serial == $lserial} { - set fd [open "|git diff-files" r] - fconfigure $fd -blocking 0 - filerun $fd [list readdifffiles $fd $serial] + if {$serial != $lserial} { + return 0 } - if {$isdiff && $serial == $lserial && $localirow == -1} { + # now see if there are any local changes not checked in to the index + set fd [open "|git diff-files" r] + fconfigure $fd -blocking 0 + filerun $fd [list readdifffiles $fd $serial] + + if {$isdiff && ![commitinview $nullid2 $curview]} { # add the line for the changes in the index to the graph - set localirow $commitrow($curview,$mainheadid) - set hl "Local changes checked in to index but not committed" + set hl [mc "Local changes checked in to index but not committed"] set commitinfo($nullid2) [list $hl {} {} {} {} " $hl\n"] set commitdata($nullid2) "\n $hl\n" - insertrow $localirow $nullid2 + if {[commitinview $nullid $curview]} { + removerow $nullid $curview + } + insertrow $nullid2 $mainheadid $curview + } elseif {!$isdiff && [commitinview $nullid2 $curview]} { + removerow $nullid2 $curview } return 0 } proc readdifffiles {fd serial} { - global localirow localfrow commitrow mainheadid nullid curview + global mainheadid nullid nullid2 curview global commitinfo commitdata lserial set isdiff 1 @@ -2892,50 +3608,55 @@ proc readdifffiles {fd serial} { # we only need to see one line and we don't really care what it says... close $fd - if {$isdiff && $serial == $lserial && $localfrow == -1} { + if {$serial != $lserial} { + return 0 + } + + if {$isdiff && ![commitinview $nullid $curview]} { # add the line for the local diff to the graph - if {$localirow >= 0} { - set localfrow $localirow - incr localirow - } else { - set localfrow $commitrow($curview,$mainheadid) - } - set hl "Local uncommitted changes, not checked in to index" + set hl [mc "Local uncommitted changes, not checked in to index"] set commitinfo($nullid) [list $hl {} {} {} {} " $hl\n"] set commitdata($nullid) "\n $hl\n" - insertrow $localfrow $nullid + if {[commitinview $nullid2 $curview]} { + set p $nullid2 + } else { + set p $mainheadid + } + insertrow $nullid $p $curview + } elseif {!$isdiff && [commitinview $nullid $curview]} { + removerow $nullid $curview } return 0 } proc nextuse {id row} { - global commitrow curview children + global curview children if {[info exists children($curview,$id)]} { foreach kid $children($curview,$id) { - if {![info exists commitrow($curview,$kid)]} { + if {![commitinview $kid $curview]} { return -1 } - if {$commitrow($curview,$kid) > $row} { - return $commitrow($curview,$kid) + if {[rowofcommit $kid] > $row} { + return [rowofcommit $kid] } } } - if {[info exists commitrow($curview,$id)]} { - return $commitrow($curview,$id) + if {[commitinview $id $curview]} { + return [rowofcommit $id] } return -1 } proc prevuse {id row} { - global commitrow curview children + global curview children set ret -1 if {[info exists children($curview,$id)]} { foreach kid $children($curview,$id) { - if {![info exists commitrow($curview,$kid)]} break - if {$commitrow($curview,$kid) < $row} { - set ret $commitrow($curview,$kid) + if {![commitinview $kid $curview]} break + if {[rowofcommit $kid] < $row} { + set ret [rowofcommit $kid] } } } @@ -2944,7 +3665,7 @@ proc prevuse {id row} { proc make_idlist {row} { global displayorder parentlist uparrowlen downarrowlen mingaplen - global commitidx curview ordertok children commitrow + global commitidx curview children set r [expr {$row - $mingaplen - $downarrowlen - 1}] if {$r < 0} { @@ -2958,6 +3679,7 @@ proc make_idlist {row} { if {$rb > $commitidx($curview)} { set rb $commitidx($curview) } + make_disporder $r [expr {$rb + 1}] set ids {} for {} {$r < $ra} {incr r} { set nextid [lindex $displayorder [expr {$r + 1}]] @@ -2966,7 +3688,7 @@ proc make_idlist {row} { set rn [nextuse $p $r] if {$rn >= $row && $rn <= $r + $downarrowlen + $mingaplen + $uparrowlen} { - lappend ids [list $ordertok($curview,$p) $p] + lappend ids [list [ordertoken $p] $p] } } } @@ -2976,25 +3698,25 @@ proc make_idlist {row} { if {$p eq $nextid} continue set rn [nextuse $p $r] if {$rn < 0 || $rn >= $row} { - lappend ids [list $ordertok($curview,$p) $p] + lappend ids [list [ordertoken $p] $p] } } } set id [lindex $displayorder $row] - lappend ids [list $ordertok($curview,$id) $id] + lappend ids [list [ordertoken $id] $id] while {$r < $rb} { foreach p [lindex $parentlist $r] { set firstkid [lindex $children($curview,$p) 0] - if {$commitrow($curview,$firstkid) < $row} { - lappend ids [list $ordertok($curview,$p) $p] + if {[rowofcommit $firstkid] < $row} { + lappend ids [list [ordertoken $p] $p] } } incr r set id [lindex $displayorder $r] if {$id ne {}} { set firstkid [lindex $children($curview,$id) 0] - if {$firstkid ne {} && $commitrow($curview,$firstkid) < $row} { - lappend ids [list $ordertok($curview,$id) $id] + if {$firstkid ne {} && [rowofcommit $firstkid] < $row} { + lappend ids [list [ordertoken $id] $id] } } } @@ -3040,8 +3762,9 @@ proc layoutrows {row endrow} { global rowidlist rowisopt rowfinal displayorder global uparrowlen downarrowlen maxwidth mingaplen global children parentlist - global commitidx viewcomplete curview commitrow + global commitidx viewcomplete curview + make_disporder [expr {$row - 1}] [expr {$endrow + $uparrowlen}] set idlist {} if {$row > 0} { set rm1 [expr {$row - 1}] @@ -3097,7 +3820,7 @@ proc layoutrows {row endrow} { foreach p [lindex $parentlist $r] { if {[lsearch -exact $idlist $p] >= 0} continue set fk [lindex $children($curview,$p) 0] - if {$commitrow($curview,$fk) < $row} { + if {[rowofcommit $fk] < $row} { set x [idcol $idlist $p $x] set idlist [linsert $idlist $x $p] } @@ -3106,7 +3829,7 @@ proc layoutrows {row endrow} { set p [lindex $displayorder $r] if {[lsearch -exact $idlist $p] < 0} { set fk [lindex $children($curview,$p) 0] - if {$fk ne {} && $commitrow($curview,$fk) < $row} { + if {$fk ne {} && [rowofcommit $fk] < $row} { set x [idcol $idlist $p $x] set idlist [linsert $idlist $x $p] } @@ -3321,7 +4044,7 @@ proc linewidth {id} { } proc rowranges {id} { - global commitrow curview children uparrowlen downarrowlen + global curview children uparrowlen downarrowlen global rowidlist set kids $children($curview,$id) @@ -3331,13 +4054,13 @@ proc rowranges {id} { set ret {} lappend kids $id foreach child $kids { - if {![info exists commitrow($curview,$child)]} break - set row $commitrow($curview,$child) + if {![commitinview $child $curview]} break + set row [rowofcommit $child] if {![info exists prev]} { lappend ret [expr {$row + 1}] } else { if {$row <= $prevrow} { - puts "oops children out of order [shortids $id] $row < [shortids $prev] $prevrow" + puts "oops children of [shortids $id] out of order [shortids $child] $row <= [shortids $prev] $prevrow" } # see if the line extends the whole way from prevrow to row if {$row > $prevrow + $uparrowlen + $downarrowlen && @@ -3370,7 +4093,7 @@ proc rowranges {id} { if {$child eq $id} { lappend ret $row } - set prev $id + set prev $child set prevrow $row } return $ret @@ -3618,14 +4341,14 @@ proc drawlines {id} { } proc drawcmittext {id row col} { - global linespc canv canv2 canv3 canvy0 fgcolor curview - global commitlisted commitinfo rowidlist parentlist + global linespc canv canv2 canv3 fgcolor curview + global cmitlisted commitinfo rowidlist parentlist global rowtextx idpos idtags idheads idotherrefs global linehtag linentag linedtag selectedline global canvxmax boldrows boldnamerows fgcolor nullid nullid2 # listed is 0 for boundary, 1 for normal, 2 for left, 3 for right - set listed [lindex $commitlisted $row] + set listed $cmitlisted($curview,$id) if {$id eq $nullid} { set ofill red } elseif {$id eq $nullid2} { @@ -3681,7 +4404,7 @@ proc drawcmittext {id row col} { set date [formatdate $date] set font mainfont set nfont mainfont - set isbold [ishighlighted $row] + set isbold [ishighlighted $id] if {$isbold > 0} { lappend boldrows $row set font mainfontbold @@ -3710,7 +4433,7 @@ proc drawcmittext {id row col} { proc drawcmitrow {row} { global displayorder rowidlist nrows_drawn global iddrawn markingmatches - global commitinfo parentlist numcommits + global commitinfo numcommits global filehighlight fhighlights findpattern nhighlights global hlview vhighlights global highlight_related rhighlights @@ -3718,16 +4441,16 @@ proc drawcmitrow {row} { if {$row >= $numcommits} return set id [lindex $displayorder $row] - if {[info exists hlview] && ![info exists vhighlights($row)]} { + if {[info exists hlview] && ![info exists vhighlights($id)]} { askvhighlight $row $id } - if {[info exists filehighlight] && ![info exists fhighlights($row)]} { + if {[info exists filehighlight] && ![info exists fhighlights($id)]} { askfilehighlight $row $id } - if {$findpattern ne {} && ![info exists nhighlights($row)]} { + if {$findpattern ne {} && ![info exists nhighlights($id)]} { askfindhighlight $row $id } - if {$highlight_related ne "None" && ![info exists rhighlights($row)]} { + if {$highlight_related ne [mc "None"] && ![info exists rhighlights($id)]} { askrelhighlight $row $id } if {![info exists iddrawn($id)]} { @@ -3808,56 +4531,99 @@ proc drawcommits {row {endrow {}}} { drawcmitrow $r if {$r == $er} break set nextid [lindex $displayorder [expr {$r + 1}]] - if {$wasdrawn && [info exists iddrawn($nextid)]} { - catch {unset prevlines} - continue - } + if {$wasdrawn && [info exists iddrawn($nextid)]} continue drawparentlinks $id $r - if {[info exists lineends($r)]} { - foreach lid $lineends($r) { - unset prevlines($lid) - } - } set rowids [lindex $rowidlist $r] foreach lid $rowids { if {$lid eq {}} continue + if {[info exists lineend($lid)] && $lineend($lid) > $r} continue if {$lid eq $id} { # see if this is the first child of any of its parents foreach p [lindex $parentlist $r] { if {[lsearch -exact $rowids $p] < 0} { # make this line extend up to the child - set le [drawlineseg $p $r $er 0] - lappend lineends($le) $p - set prevlines($p) 1 + set lineend($p) [drawlineseg $p $r $er 0] } } - } elseif {![info exists prevlines($lid)]} { - set le [drawlineseg $lid $r $er 1] - lappend lineends($le) $lid - set prevlines($lid) 1 + } else { + set lineend($lid) [drawlineseg $lid $r $er 1] } } } } -proc drawfrac {f0 f1} { - global canv linespc +proc undolayout {row} { + global uparrowlen mingaplen downarrowlen + global rowidlist rowisopt rowfinal need_redisplay + + set r [expr {$row - ($uparrowlen + $mingaplen + $downarrowlen)}] + if {$r < 0} { + set r 0 + } + if {[llength $rowidlist] > $r} { + incr r -1 + set rowidlist [lrange $rowidlist 0 $r] + set rowfinal [lrange $rowfinal 0 $r] + set rowisopt [lrange $rowisopt 0 $r] + set need_redisplay 1 + run drawvisible + } +} +proc drawvisible {} { + global canv linespc curview vrowmod selectedline targetrow targetid + global need_redisplay cscroll numcommits + + set fs [$canv yview] set ymax [lindex [$canv cget -scrollregion] 3] if {$ymax eq {} || $ymax == 0} return + set f0 [lindex $fs 0] + set f1 [lindex $fs 1] set y0 [expr {int($f0 * $ymax)}] - set row [expr {int(($y0 - 3) / $linespc) - 1}] set y1 [expr {int($f1 * $ymax)}] + + if {[info exists targetid]} { + if {[commitinview $targetid $curview]} { + set r [rowofcommit $targetid] + if {$r != $targetrow} { + # Fix up the scrollregion and change the scrolling position + # now that our target row has moved. + set diff [expr {($r - $targetrow) * $linespc}] + set targetrow $r + setcanvscroll + set ymax [lindex [$canv cget -scrollregion] 3] + incr y0 $diff + incr y1 $diff + set f0 [expr {$y0 / $ymax}] + set f1 [expr {$y1 / $ymax}] + allcanvs yview moveto $f0 + $cscroll set $f0 $f1 + set need_redisplay 1 + } + } else { + unset targetid + } + } + + set row [expr {int(($y0 - 3) / $linespc) - 1}] set endrow [expr {int(($y1 - 3) / $linespc) + 1}] + if {$endrow >= $vrowmod($curview)} { + update_arcrows $curview + } + if {[info exists selectedline] && + $row <= $selectedline && $selectedline <= $endrow} { + set targetrow $selectedline + } else { + set targetrow [expr {int(($row + $endrow) / 2)}] + } + if {$targetrow >= $numcommits} { + set targetrow [expr {$numcommits - 1}] + } + set targetid [commitonrow $targetrow] drawcommits $row $endrow } -proc drawvisible {} { - global canv - eval drawfrac [$canv yview] -} - proc clear_display {} { global iddrawn linesegs need_redisplay nrows_drawn global vhighlights fhighlights nhighlights rhighlights @@ -3910,7 +4676,7 @@ proc findcrossings {id} { proc assigncolor {id} { global colormap colors nextcolor - global commitrow parentlist children children curview + global parents children children curview if {[info exists colormap($id)]} return set ncolors [llength $colors] @@ -3922,7 +4688,7 @@ proc assigncolor {id} { if {[llength $kids] == 1} { set child [lindex $kids 0] if {[info exists colormap($child)] - && [llength [lindex $parentlist $commitrow($curview,$child)]] == 1} { + && [llength $parents($curview,$child)] == 1} { set colormap($id) $colormap($child) return } @@ -3950,7 +4716,7 @@ proc assigncolor {id} { && [lsearch -exact $badcolors $colormap($child)] < 0} { lappend badcolors $colormap($child) } - foreach p [lindex $parentlist $commitrow($curview,$child)] { + foreach p $parents($curview,$child) { if {[info exists colormap($p)] && [lsearch -exact $badcolors $colormap($p)] < 0} { lappend badcolors $colormap($p) @@ -3983,7 +4749,7 @@ proc bindline {t id} { proc drawtags {id x xt y1} { global idtags idheads idotherrefs mainhead global linespc lthickness - global canv commitrow rowtextx curview fgcolor bgcolor + global canv rowtextx curview fgcolor bgcolor set marks {} set ntags 0 @@ -4033,7 +4799,7 @@ proc drawtags {id x xt y1} { $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \ -width 1 -outline black -fill yellow -tags tag.$id] $canv bind $t <1> [list showtag $tag 1] - set rowtextx($commitrow($curview,$id)) [expr {$xr + $linespc}] + set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}] } else { # draw a head or other ref if {[incr nheads -1] >= 0} { @@ -4087,103 +4853,6 @@ proc show_status {msg} { -tags text -fill $fgcolor } -# 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 -# on that row and below will move down one row. -proc insertrow {row newcmit} { - global displayorder parentlist commitlisted children - global commitrow curview rowidlist rowisopt rowfinal numcommits - global numcommits - global selectedline commitidx ordertok - - if {$row >= $numcommits} { - puts "oops, inserting new row $row but only have $numcommits rows" - return - } - set p [lindex $displayorder $row] - set displayorder [linsert $displayorder $row $newcmit] - set parentlist [linsert $parentlist $row $p] - set kids $children($curview,$p) - lappend kids $newcmit - set children($curview,$p) $kids - set children($curview,$newcmit) {} - set commitlisted [linsert $commitlisted $row 1] - set l [llength $displayorder] - for {set r $row} {$r < $l} {incr r} { - set id [lindex $displayorder $r] - set commitrow($curview,$id) $r - } - incr commitidx($curview) - set ordertok($curview,$newcmit) $ordertok($curview,$p) - - if {$row < [llength $rowidlist]} { - set idlist [lindex $rowidlist $row] - if {$idlist ne {}} { - if {[llength $kids] == 1} { - set col [lsearch -exact $idlist $p] - lset idlist $col $newcmit - } else { - set col [llength $idlist] - lappend idlist $newcmit - } - } - set rowidlist [linsert $rowidlist $row $idlist] - set rowisopt [linsert $rowisopt $row 0] - set rowfinal [linsert $rowfinal $row [lindex $rowfinal $row]] - } - - incr numcommits - - if {[info exists selectedline] && $selectedline >= $row} { - incr selectedline - } - redisplay -} - -# Remove a commit that was inserted with insertrow on row $row. -proc removerow {row} { - global displayorder parentlist commitlisted children - global commitrow curview rowidlist rowisopt rowfinal numcommits - global numcommits - global linesegends selectedline commitidx - - if {$row >= $numcommits} { - puts "oops, removing row $row but only have $numcommits rows" - return - } - set rp1 [expr {$row + 1}] - set id [lindex $displayorder $row] - set p [lindex $parentlist $row] - set displayorder [lreplace $displayorder $row $row] - set parentlist [lreplace $parentlist $row $row] - set commitlisted [lreplace $commitlisted $row $row] - set kids $children($curview,$p) - set i [lsearch -exact $kids $id] - if {$i >= 0} { - set kids [lreplace $kids $i $i] - set children($curview,$p) $kids - } - set l [llength $displayorder] - for {set r $row} {$r < $l} {incr r} { - set id [lindex $displayorder $r] - set commitrow($curview,$id) $r - } - incr commitidx($curview) -1 - - if {$row < [llength $rowidlist]} { - set rowidlist [lreplace $rowidlist $row $row] - set rowisopt [lreplace $rowisopt $row $row] - set rowfinal [lreplace $rowfinal $row $row] - } - - incr numcommits -1 - - if {[info exists selectedline] && $selectedline > $row} { - incr selectedline -1 - } - redisplay -} - # Don't change the text pane cursor if it is currently the hand cursor, # showing that we are over a sha1 ID link. proc settextcursor {c} { @@ -4195,20 +4864,30 @@ proc settextcursor {c} { set curtextcursor $c } -proc nowbusy {what} { - global isbusy +proc nowbusy {what {name {}}} { + global isbusy busyname statusw if {[array names isbusy] eq {}} { . config -cursor watch settextcursor watch } set isbusy($what) 1 + set busyname($what) $name + if {$name ne {}} { + $statusw conf -text $name + } } proc notbusy {what} { - global isbusy maincursor textcursor + global isbusy maincursor textcursor busyname statusw - catch {unset isbusy($what)} + catch { + unset isbusy($what) + if {$busyname($what) ne {} && + [$statusw cget -text] eq $busyname($what)} { + $statusw conf -text {} + } + } if {[array names isbusy] eq {}} { . config -cursor $maincursor settextcursor $textcursor @@ -4217,11 +4896,11 @@ proc notbusy {what} { proc findmatches {f} { global findtype findstring - if {$findtype == "Regexp"} { + if {$findtype == [mc "Regexp"]} { set matches [regexp -indices -all -inline $findstring $f] } else { set fs $findstring - if {$findtype == "IgnCase"} { + if {$findtype == [mc "IgnCase"]} { set f [string tolower $f] set fs [string tolower $fs] } @@ -4236,31 +4915,30 @@ proc findmatches {f} { return $matches } -proc dofind {{rev 0}} { +proc dofind {{dirn 1} {wrap 1}} { global findstring findstartline findcurline selectedline numcommits - global gdttype filehighlight fh_serial find_dirn + global gdttype filehighlight fh_serial find_dirn findallowwrap - unmarkmatches + if {[info exists find_dirn]} { + if {$find_dirn == $dirn} return + stopfinding + } focus . if {$findstring eq {} || $numcommits == 0} return if {![info exists selectedline]} { - set findstartline [lindex [visiblerows] $rev] + set findstartline [lindex [visiblerows] [expr {$dirn < 0}]] } else { set findstartline $selectedline } set findcurline $findstartline - nowbusy finding - if {$gdttype ne "containing:" && ![info exists filehighlight]} { + nowbusy finding [mc "Searching"] + if {$gdttype ne [mc "containing:"] && ![info exists filehighlight]} { after cancel do_file_hl $fh_serial do_file_hl $fh_serial } - if {!$rev} { - set find_dirn 1 - run findmore - } else { - set find_dirn -1 - run findmorerev - } + set find_dirn $dirn + set findallowwrap $wrap + run findmore } proc stopfinding {} { @@ -4275,155 +4953,77 @@ proc stopfinding {} { } } -proc findnext {restart} { - global findcurline find_dirn - - if {[info exists find_dirn]} return - set find_dirn 1 - if {![info exists findcurline]} { - if {$restart} { - dofind - } else { - bell - } - } else { - run findmore - nowbusy finding - } -} - -proc findprev {} { - global findcurline find_dirn - - if {[info exists find_dirn]} return - set find_dirn -1 - if {![info exists findcurline]} { - dofind 1 - } else { - run findmorerev - nowbusy finding - } -} - proc findmore {} { global commitdata commitinfo numcommits findpattern findloc - global findstartline findcurline displayorder + global findstartline findcurline findallowwrap global find_dirn gdttype fhighlights fprogcoord + global curview varcorder vrownum varccommits vrowmod if {![info exists find_dirn]} { return 0 } - set fldtypes {Headline Author Date Committer CDate Comments} - set l [expr {$findcurline + 1}] - if {$l >= $numcommits} { - set l 0 - } - if {$l <= $findstartline} { - set lim [expr {$findstartline + 1}] - } else { - set lim $numcommits - } - if {$lim - $l > 500} { - set lim [expr {$l + 500}] - } - set found 0 - set domore 1 - if {$gdttype eq "containing:"} { - for {} {$l < $lim} {incr l} { - set id [lindex $displayorder $l] - # shouldn't happen unless git log doesn't give all the commits... - if {![info exists commitdata($id)]} continue - if {![doesmatch $commitdata($id)]} continue - if {![info exists commitinfo($id)]} { - getcommit $id - } - set info $commitinfo($id) - foreach f $info ty $fldtypes { - if {($findloc eq "All fields" || $findloc eq $ty) && - [doesmatch $f]} { - set found 1 - break - } - } - if {$found} break + set fldtypes [list [mc "Headline"] [mc "Author"] [mc "Date"] [mc "Committer"] [mc "CDate"] [mc "Comments"]] + set l $findcurline + set moretodo 0 + if {$find_dirn > 0} { + incr l + if {$l >= $numcommits} { + set l 0 + } + if {$l <= $findstartline} { + set lim [expr {$findstartline + 1}] + } else { + set lim $numcommits + set moretodo $findallowwrap } } else { - for {} {$l < $lim} {incr l} { - set id [lindex $displayorder $l] - if {![info exists fhighlights($l)]} { - askfilehighlight $l $id - if {$domore} { - set domore 0 - set findcurline [expr {$l - 1}] - } - } elseif {$fhighlights($l)} { - set found $domore - break - } + if {$l == 0} { + set l $numcommits } - } - if {$found || ($domore && $l == $findstartline + 1)} { - unset findcurline - unset find_dirn - notbusy finding - set fprogcoord 0 - adjustprogress - if {$found} { - findselectline $l + incr l -1 + if {$l >= $findstartline} { + set lim [expr {$findstartline - 1}] } else { - bell + set lim -1 + set moretodo $findallowwrap } - return 0 - } - if {!$domore} { - flushhighlights - } else { - set findcurline [expr {$l - 1}] - } - set n [expr {$findcurline - ($findstartline + 1)}] - if {$n < 0} { - incr n $numcommits - } - set fprogcoord [expr {$n * 1.0 / $numcommits}] - adjustprogress - return $domore -} - -proc findmorerev {} { - global commitdata commitinfo numcommits findpattern findloc - global findstartline findcurline displayorder - global find_dirn gdttype fhighlights fprogcoord - - if {![info exists find_dirn]} { - return 0 - } - set fldtypes {Headline Author Date Committer CDate Comments} - set l $findcurline - if {$l == 0} { - set l $numcommits } - incr l -1 - if {$l >= $findstartline} { - set lim [expr {$findstartline - 1}] - } else { - set lim -1 + set n [expr {($lim - $l) * $find_dirn}] + if {$n > 500} { + set n 500 + set moretodo 1 } - if {$l - $lim > 500} { - set lim [expr {$l - 500}] + if {$l + ($find_dirn > 0? $n: 1) > $vrowmod($curview)} { + update_arcrows $curview } set found 0 set domore 1 - if {$gdttype eq "containing:"} { - for {} {$l > $lim} {incr l -1} { - set id [lindex $displayorder $l] - if {![info exists commitdata($id)]} continue - if {![doesmatch $commitdata($id)]} continue + set ai [bsearch $vrownum($curview) $l] + set a [lindex $varcorder($curview) $ai] + set arow [lindex $vrownum($curview) $ai] + set ids [lindex $varccommits($curview,$a)] + set arowend [expr {$arow + [llength $ids]}] + if {$gdttype eq [mc "containing:"]} { + for {} {$n > 0} {incr n -1; incr l $find_dirn} { + if {$l < $arow || $l >= $arowend} { + incr ai $find_dirn + set a [lindex $varcorder($curview) $ai] + set arow [lindex $vrownum($curview) $ai] + set ids [lindex $varccommits($curview,$a)] + set arowend [expr {$arow + [llength $ids]}] + } + set id [lindex $ids [expr {$l - $arow}]] + # shouldn't happen unless git log doesn't give all the commits... + if {![info exists commitdata($id)] || + ![doesmatch $commitdata($id)]} { + continue + } if {![info exists commitinfo($id)]} { getcommit $id } set info $commitinfo($id) foreach f $info ty $fldtypes { - if {($findloc eq "All fields" || $findloc eq $ty) && + if {($findloc eq [mc "All fields"] || $findloc eq $ty) && [doesmatch $f]} { set found 1 break @@ -4432,21 +5032,32 @@ proc findmorerev {} { if {$found} break } } else { - for {} {$l > $lim} {incr l -1} { - set id [lindex $displayorder $l] - if {![info exists fhighlights($l)]} { + for {} {$n > 0} {incr n -1; incr l $find_dirn} { + if {$l < $arow || $l >= $arowend} { + incr ai $find_dirn + set a [lindex $varcorder($curview) $ai] + set arow [lindex $vrownum($curview) $ai] + set ids [lindex $varccommits($curview,$a)] + set arowend [expr {$arow + [llength $ids]}] + } + set id [lindex $ids [expr {$l - $arow}]] + if {![info exists fhighlights($id)]} { + # this sets fhighlights($id) to -1 askfilehighlight $l $id + } + if {$fhighlights($id) > 0} { + set found $domore + break + } + if {$fhighlights($id) < 0} { if {$domore} { set domore 0 - set findcurline [expr {$l + 1}] + set findcurline [expr {$l - $find_dirn}] } - } elseif {$fhighlights($l)} { - set found $domore - break } } } - if {$found || ($domore && $l == $findstartline - 1)} { + if {$found || ($domore && !$moretodo)} { unset findcurline unset find_dirn notbusy finding @@ -4462,9 +5073,9 @@ proc findmorerev {} { if {!$domore} { flushhighlights } else { - set findcurline [expr {$l + 1}] + set findcurline [expr {$l - $find_dirn}] } - set n [expr {($findstartline - 1) - $findcurline}] + set n [expr {($findcurline - $findstartline) * $find_dirn - 1}] if {$n < 0} { incr n $numcommits } @@ -4479,7 +5090,7 @@ proc findselectline {l} { set markingmatches 1 set findcurline $l selectline $l 1 - if {$findloc == "All fields" || $findloc == "Comments"} { + if {$findloc == [mc "All fields"] || $findloc == [mc "Comments"]} { # highlight the matches in the comments set f [$ctext get 1.0 $commentend] set matches [findmatches $f] @@ -4536,7 +5147,9 @@ proc selcanvline {w x y} { set l 0 } if {$w eq $canv} { - if {![info exists rowtextx($l)] || $x < $rowtextx($l)} return + set xmax [lindex [$canv cget -scrollregion] 2] + set xleft [expr {[lindex [$canv xview] 0] * $xmax}] + if {![info exists rowtextx($l)] || $xleft + $x < $rowtextx($l)} return } unmarkmatches selectline $l 1 @@ -4557,7 +5170,7 @@ proc commit_descriptor {p} { # append some text to the ctext widget, and make any SHA1 ID # that we know about be a clickable link. proc appendwithlinks {text tags} { - global ctext commitrow linknum curview pendinglinks + global ctext linknum curview pendinglinks set start [$ctext index "end - 1c"] $ctext insert end $text $tags @@ -4575,11 +5188,11 @@ proc appendwithlinks {text tags} { } proc setlink {id lk} { - global curview commitrow ctext pendinglinks commitinterest + global curview ctext pendinglinks commitinterest - if {[info exists commitrow($curview,$id)]} { + if {[commitinview $id $curview]} { $ctext tag conf $lk -foreground blue -underline 1 - $ctext tag bind $lk <1> [list selectline $commitrow($curview,$id) 1] + $ctext tag bind $lk <1> [list selectline [rowofcommit $id] 1] $ctext tag bind $lk {linkcursor %W 1} $ctext tag bind $lk {linkcursor %W -1} } else { @@ -4630,7 +5243,7 @@ proc viewnextline {dir} { # add a list of tag or branch names at position pos # returns the number of names inserted proc appendrefs {pos ids var} { - global ctext commitrow linknum curview $var maxrefs + global ctext linknum curview $var maxrefs if {[catch {$ctext index $pos}]} { return 0 @@ -4733,8 +5346,7 @@ proc make_secsel {l} { proc selectline {l isnew} { global canv ctext commitinfo selectedline - global displayorder - global canvy0 linespc parentlist children curview + global canvy0 linespc parents children curview global currentid sha1entry global commentend idtags linknum global mergemax numcommits pending_select @@ -4784,13 +5396,12 @@ proc selectline {l isnew} { make_secsel $l + set id [commitonrow $l] if {$isnew} { - addtohistory [list selectline $l 0] + addtohistory [list selbyid $id] } set selectedline $l - - set id [lindex $displayorder $l] set currentid $id $sha1entry delete 0 end $sha1entry insert 0 $id @@ -4803,11 +5414,11 @@ proc selectline {l isnew} { set linknum 0 set info $commitinfo($id) set date [formatdate [lindex $info 2]] - $ctext insert end "Author: [lindex $info 1] $date\n" + $ctext insert end "[mc "Author"]: [lindex $info 1] $date\n" set date [formatdate [lindex $info 4]] - $ctext insert end "Committer: [lindex $info 3] $date\n" + $ctext insert end "[mc "Committer"]: [lindex $info 3] $date\n" if {[info exists idtags($id)]} { - $ctext insert end "Tags:" + $ctext insert end [mc "Tags:"] foreach tag $idtags($id) { $ctext insert end " $tag" } @@ -4815,7 +5426,7 @@ proc selectline {l isnew} { } set headers {} - set olds [lindex $parentlist $l] + set olds $parents($curview,$id) if {[llength $olds] > 1} { set np 0 foreach p $olds { @@ -4824,18 +5435,18 @@ proc selectline {l isnew} { } else { set tag m$np } - $ctext insert end "Parent: " $tag + $ctext insert end "[mc "Parent"]: " $tag appendwithlinks [commit_descriptor $p] {} incr np } } else { foreach p $olds { - append headers "Parent: [commit_descriptor $p]" + append headers "[mc "Parent"]: [commit_descriptor $p]" } } foreach c $children($curview,$id) { - append headers "Child: [commit_descriptor $c]" + append headers "[mc "Child"]: [commit_descriptor $c]" } # make anything that looks like a SHA1 ID be a clickable link @@ -4844,13 +5455,13 @@ proc selectline {l isnew} { if {![info exists allcommits]} { getallcommits } - $ctext insert end "Branch: " + $ctext insert end "[mc "Branch"]: " $ctext mark set branch "end -1c" $ctext mark gravity branch left - $ctext insert end "\nFollows: " + $ctext insert end "\n[mc "Follows"]: " $ctext mark set follows "end -1c" $ctext mark gravity follows left - $ctext insert end "\nPrecedes: " + $ctext insert end "\n[mc "Precedes"]: " $ctext mark set precedes "end -1c" $ctext mark gravity precedes left $ctext insert end "\n" @@ -4867,13 +5478,13 @@ proc selectline {l isnew} { $ctext conf -state disabled set commentend [$ctext index "end - 1c"] - init_flist "Comments" + init_flist [mc "Comments"] if {$cmitmode eq "tree"} { gettree $id } elseif {[llength $olds] <= 1} { startdiff $id } else { - mergediff $id $l + mergediff $id } } @@ -5118,22 +5729,26 @@ proc getblobline {bf id} { return [expr {$nl >= 1000? 2: 1}] } -proc mergediff {id l} { +proc mergediff {id} { global diffmergeid mdifffd global diffids - global parentlist + global parents + global limitdiffs viewfiles curview set diffmergeid $id set diffids $id # this doesn't seem to actually affect anything... set cmd [concat | git diff-tree --no-commit-id --cc $id] + if {$limitdiffs && $viewfiles($curview) ne {}} { + set cmd [concat $cmd -- $viewfiles($curview)] + } if {[catch {set mdf [open $cmd r]} err]} { - error_popup "Error getting merge diffs: $err" + error_popup "[mc "Error getting merge diffs:"] $err" return } fconfigure $mdf -blocking 0 set mdifffd($id) $mdf - set np [llength [lindex $parentlist $l]] + set np [llength $parents($curview,$id)] settabs $np filerun $mdf [list getmergediffline $mdf $id $np] } @@ -5226,8 +5841,27 @@ proc startdiff {ids} { } } +proc path_filter {filter name} { + foreach p $filter { + set l [string length $p] + if {[string index $p end] eq "/"} { + if {[string compare -length $l $p $name] == 0} { + return 1 + } + } else { + if {[string compare -length $l $p $name] == 0 && + ([string length $name] == $l || + [string index $name $l] eq "/")} { + return 1 + } + } + } + return 0 +} + proc addtocflist {ids} { - global treediffs cflist + global treediffs + add_flist $treediffs($ids) getblobdiffs $ids } @@ -5284,7 +5918,7 @@ proc gettreediffs {ids} { proc gettreediffline {gdtf ids} { global treediff treediffs treepending diffids diffmergeid - global cmitmode + global cmitmode viewfiles curview limitdiffs set nr 0 while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} { @@ -5301,7 +5935,17 @@ proc gettreediffline {gdtf ids} { return [expr {$nr >= 1000? 2: 1}] } close $gdtf - set treediffs($ids) $treediff + if {$limitdiffs && $viewfiles($curview) ne {}} { + set flist {} + foreach f $treediff { + if {[path_filter $viewfiles($curview) $f]} { + lappend flist $f + } + } + set treediffs($ids) $flist + } else { + set treediffs($ids) $treediff + } unset treepending if {$cmitmode eq "tree"} { gettree $diffids @@ -5335,8 +5979,13 @@ proc getblobdiffs {ids} { global blobdifffd diffids env global diffinhdr treediffs global diffcontext + global limitdiffs viewfiles curview - if {[catch {set bdf [open [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] r]} err]} { + set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] + if {$limitdiffs && $viewfiles($curview) ne {}} { + set cmd [concat $cmd -- $viewfiles($curview)] + } + if {[catch {set bdf [open $cmd r]} err]} { puts "error getting diffs: $err" return } @@ -5420,8 +6069,7 @@ proc getblobdiffline {bdf ids} { set diffinhdr 0 } elseif {$diffinhdr} { - if {![string compare -length 12 "rename from " $line] || - ![string compare -length 10 "copy from " $line]} { + if {![string compare -length 12 "rename from " $line]} { set fname [string range $line [expr 6 + [string first " from " $line] ] end] if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] @@ -5728,7 +6376,7 @@ proc fontname {f} { } proc incrfont {inc} { - global mainfont textfont ctext canv phase cflist showrefstop + global mainfont textfont ctext canv cflist showrefstop global stopped entries fontattr unmarkmatches @@ -5772,15 +6420,14 @@ proc sha1change {n1 n2 op} { } if {[$sha1but cget -state] == $state} return if {$state == "normal"} { - $sha1but conf -state normal -relief raised -text "Goto: " + $sha1but conf -state normal -relief raised -text "[mc "Goto:"] " } else { - $sha1but conf -state disabled -relief flat -text "SHA1 ID: " + $sha1but conf -state disabled -relief flat -text "[mc "SHA1 ID:"] " } } proc gotocommit {} { - global sha1string currentid commitrow tagids headids - global displayorder numcommits curview + global sha1string tagids headids curview varcid if {$sha1string == {} || ([info exists currentid] && $sha1string == $currentid)} return @@ -5791,31 +6438,26 @@ proc gotocommit {} { } else { set id [string tolower $sha1string] if {[regexp {^[0-9a-f]{4,39}$} $id]} { - set matches {} - foreach i $displayorder { - if {[string match $id* $i]} { - lappend matches $i - } - } + set matches [array names varcid "$curview,$id*"] if {$matches ne {}} { if {[llength $matches] > 1} { - error_popup "Short SHA1 id $id is ambiguous" + error_popup [mc "Short SHA1 id %s is ambiguous" $id] return } - set id [lindex $matches 0] + set id [lindex [split [lindex $matches 0] ","] 1] } } } - if {[info exists commitrow($curview,$id)]} { - selectline $commitrow($curview,$id) 1 + if {[commitinview $id $curview]} { + selectline [rowofcommit $id] 1 return } if {[regexp {^[0-9a-fA-F]{4,}$} $sha1string]} { - set type "SHA1 id" + set msg [mc "SHA1 id %s is not known" $sha1string] } else { - set type "Tag/Head" + set msg [mc "Tag/Head %s is not known" $sha1string] } - error_popup "$type $sha1string is not known" + error_popup $msg } proc lineenter {x y id} { @@ -5916,7 +6558,7 @@ proc arrowjump {id n y} { } proc lineclick {x y id isnew} { - global ctext commitinfo children canv thickerline curview commitrow + global ctext commitinfo children canv thickerline curview if {![info exists commitinfo($id)] && ![getcommit $id]} return unmarkmatches @@ -5945,17 +6587,17 @@ proc lineclick {x y id isnew} { $ctext conf -state normal clear_ctext settabs 0 - $ctext insert end "Parent:\t" + $ctext insert end "[mc "Parent"]:\t" $ctext insert end $id link0 setlink $id link0 set info $commitinfo($id) $ctext insert end "\n\t[lindex $info 0]\n" - $ctext insert end "\tAuthor:\t[lindex $info 1]\n" + $ctext insert end "\t[mc "Author"]:\t[lindex $info 1]\n" set date [formatdate [lindex $info 2]] - $ctext insert end "\tDate:\t$date\n" + $ctext insert end "\t[mc "Date"]:\t$date\n" set kids $children($curview,$id) if {$kids ne {}} { - $ctext insert end "\nChildren:" + $ctext insert end "\n[mc "Children"]:" set i 0 foreach child $kids { incr i @@ -5965,9 +6607,9 @@ proc lineclick {x y id isnew} { $ctext insert end $child link$i setlink $child link$i $ctext insert end "\n\t[lindex $info 0]" - $ctext insert end "\n\tAuthor:\t[lindex $info 1]" + $ctext insert end "\n\t[mc "Author"]:\t[lindex $info 1]" set date [formatdate [lindex $info 2]] - $ctext insert end "\n\tDate:\t$date\n" + $ctext insert end "\n\t[mc "Date"]:\t$date\n" } } $ctext conf -state disabled @@ -5984,9 +6626,9 @@ proc normalline {} { } proc selbyid {id} { - global commitrow curview - if {[info exists commitrow($curview,$id)]} { - selectline $commitrow($curview,$id) 1 + global curview + if {[commitinview $id $curview]} { + selectline [rowofcommit $id] 1 } } @@ -5999,39 +6641,39 @@ proc mstime {} { } proc rowmenu {x y id} { - global rowctxmenu commitrow selectedline rowmenuid curview + global rowctxmenu selectedline rowmenuid curview global nullid nullid2 fakerowmenu mainhead stopfinding set rowmenuid $id if {![info exists selectedline] - || $commitrow($curview,$id) eq $selectedline} { + || [rowofcommit $id] eq $selectedline} { set state disabled } else { set state normal } if {$id ne $nullid && $id ne $nullid2} { set menu $rowctxmenu - $menu entryconfigure 7 -label "Reset $mainhead branch to here" + $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead] } else { set menu $fakerowmenu } - $menu entryconfigure "Diff this*" -state $state - $menu entryconfigure "Diff selected*" -state $state - $menu entryconfigure "Make patch" -state $state + $menu entryconfigure [mc "Diff this -> selected"] -state $state + $menu entryconfigure [mc "Diff selected -> this"] -state $state + $menu entryconfigure [mc "Make patch"] -state $state tk_popup $menu $x $y } proc diffvssel {dirn} { - global rowmenuid selectedline displayorder + global rowmenuid selectedline if {![info exists selectedline]} return if {$dirn} { - set oldid [lindex $displayorder $selectedline] + set oldid [commitonrow $selectedline] set newid $rowmenuid } else { set oldid $rowmenuid - set newid [lindex $displayorder $selectedline] + set newid [commitonrow $selectedline] } addtohistory [list doseldiff $oldid $newid] doseldiff $oldid $newid @@ -6043,13 +6685,13 @@ proc doseldiff {oldid newid} { $ctext conf -state normal clear_ctext - init_flist "Top" - $ctext insert end "From " + init_flist [mc "Top"] + $ctext insert end "[mc "From"] " $ctext insert end $oldid link0 setlink $oldid link0 $ctext insert end "\n " $ctext insert end [lindex $commitinfo($oldid) 0] - $ctext insert end "\n\nTo " + $ctext insert end "\n\n[mc "To"] " $ctext insert end $newid link1 setlink $newid link1 $ctext insert end "\n " @@ -6072,9 +6714,9 @@ proc mkpatch {} { set patchtop $top catch {destroy $top} toplevel $top - label $top.title -text "Generate patch" + label $top.title -text [mc "Generate patch"] grid $top.title - -pady 10 - label $top.from -text "From:" + label $top.from -text [mc "From:"] entry $top.fromsha1 -width 40 -relief flat $top.fromsha1 insert 0 $oldid $top.fromsha1 conf -state readonly @@ -6083,7 +6725,7 @@ proc mkpatch {} { $top.fromhead insert 0 $oldhead $top.fromhead conf -state readonly grid x $top.fromhead -sticky w - label $top.to -text "To:" + label $top.to -text [mc "To:"] entry $top.tosha1 -width 40 -relief flat $top.tosha1 insert 0 $newid $top.tosha1 conf -state readonly @@ -6092,16 +6734,16 @@ proc mkpatch {} { $top.tohead insert 0 $newhead $top.tohead conf -state readonly grid x $top.tohead -sticky w - button $top.rev -text "Reverse" -command mkpatchrev -padx 5 + button $top.rev -text [mc "Reverse"] -command mkpatchrev -padx 5 grid $top.rev x -pady 10 - label $top.flab -text "Output file:" + label $top.flab -text [mc "Output file:"] entry $top.fname -width 60 $top.fname insert 0 [file normalize "patch$patchnum.patch"] incr patchnum grid $top.flab $top.fname -sticky w frame $top.buts - button $top.buts.gen -text "Generate" -command mkpatchgo - button $top.buts.can -text "Cancel" -command mkpatchcan + button $top.buts.gen -text [mc "Generate"] -command mkpatchgo + button $top.buts.can -text [mc "Cancel"] -command mkpatchcan grid $top.buts.gen $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -6136,7 +6778,7 @@ proc mkpatchgo {} { set cmd [lrange $cmd 1 end] lappend cmd >$fname & if {[catch {eval exec $cmd} err]} { - error_popup "Error creating patch: $err" + error_popup "[mc "Error creating patch:"] $err" } catch {destroy $patchtop} unset patchtop @@ -6156,9 +6798,9 @@ proc mktag {} { set mktagtop $top catch {destroy $top} toplevel $top - label $top.title -text "Create tag" + label $top.title -text [mc "Create tag"] grid $top.title - -pady 10 - label $top.id -text "ID:" + label $top.id -text [mc "ID:"] entry $top.sha1 -width 40 -relief flat $top.sha1 insert 0 $rowmenuid $top.sha1 conf -state readonly @@ -6167,12 +6809,12 @@ proc mktag {} { $top.head insert 0 [lindex $commitinfo($rowmenuid) 0] $top.head conf -state readonly grid x $top.head -sticky w - label $top.tlab -text "Tag name:" + label $top.tlab -text [mc "Tag name:"] entry $top.tag -width 60 grid $top.tlab $top.tag -sticky w frame $top.buts - button $top.buts.gen -text "Create" -command mktaggo - button $top.buts.can -text "Cancel" -command mktagcan + button $top.buts.gen -text [mc "Create"] -command mktaggo + button $top.buts.can -text [mc "Cancel"] -command mktagcan grid $top.buts.gen $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -6186,11 +6828,11 @@ proc domktag {} { set id [$mktagtop.sha1 get] set tag [$mktagtop.tag get] if {$tag == {}} { - error_popup "No tag name specified" + error_popup [mc "No tag name specified"] return } if {[info exists tagids($tag)]} { - error_popup "Tag \"$tag\" already exists" + error_popup [mc "Tag \"%s\" already exists" $tag] return } if {[catch { @@ -6200,7 +6842,7 @@ proc domktag {} { puts $f $id close $f } err]} { - error_popup "Error creating tag: $err" + error_popup "[mc "Error creating tag:"] $err" return } @@ -6213,24 +6855,24 @@ proc domktag {} { } proc redrawtags {id} { - global canv linehtag commitrow idpos selectedline curview + global canv linehtag idpos currentid curview global canvxmax iddrawn - if {![info exists commitrow($curview,$id)]} return + if {![commitinview $id $curview]} return if {![info exists iddrawn($id)]} return - drawcommits $commitrow($curview,$id) + set row [rowofcommit $id] $canv delete tag.$id set xt [eval drawtags $id $idpos($id)] - $canv coords $linehtag($commitrow($curview,$id)) $xt [lindex $idpos($id) 2] - set text [$canv itemcget $linehtag($commitrow($curview,$id)) -text] - set xr [expr {$xt + [font measure mainfont $text]}] + $canv coords $linehtag($row) $xt [lindex $idpos($id) 2] + set text [$canv itemcget $linehtag($row) -text] + set font [$canv itemcget $linehtag($row) -font] + set xr [expr {$xt + [font measure $font $text]}] if {$xr > $canvxmax} { set canvxmax $xr setcanvscroll } - if {[info exists selectedline] - && $selectedline == $commitrow($curview,$id)} { - selectline $selectedline 0 + if {[info exists currentid] && $currentid == $id} { + make_secsel $row } } @@ -6253,9 +6895,9 @@ proc writecommit {} { set wrcomtop $top catch {destroy $top} toplevel $top - label $top.title -text "Write commit to file" + label $top.title -text [mc "Write commit to file"] grid $top.title - -pady 10 - label $top.id -text "ID:" + label $top.id -text [mc "ID:"] entry $top.sha1 -width 40 -relief flat $top.sha1 insert 0 $rowmenuid $top.sha1 conf -state readonly @@ -6264,16 +6906,16 @@ proc writecommit {} { $top.head insert 0 [lindex $commitinfo($rowmenuid) 0] $top.head conf -state readonly grid x $top.head -sticky w - label $top.clab -text "Command:" + label $top.clab -text [mc "Command:"] entry $top.cmd -width 60 -textvariable wrcomcmd grid $top.clab $top.cmd -sticky w -pady 10 - label $top.flab -text "Output file:" + label $top.flab -text [mc "Output file:"] entry $top.fname -width 60 $top.fname insert 0 [file normalize "commit-[string range $rowmenuid 0 6]"] grid $top.flab $top.fname -sticky w frame $top.buts - button $top.buts.gen -text "Write" -command wrcomgo - button $top.buts.can -text "Cancel" -command wrcomcan + button $top.buts.gen -text [mc "Write"] -command wrcomgo + button $top.buts.can -text [mc "Cancel"] -command wrcomcan grid $top.buts.gen $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -6288,7 +6930,7 @@ proc wrcomgo {} { set cmd "echo $id | [$wrcomtop.cmd get]" set fname [$wrcomtop.fname get] if {[catch {exec sh -c $cmd >$fname &} err]} { - error_popup "Error writing commit: $err" + error_popup "[mc "Error writing commit:"] $err" } catch {destroy $wrcomtop} unset wrcomtop @@ -6307,19 +6949,19 @@ proc mkbranch {} { set top .makebranch catch {destroy $top} toplevel $top - label $top.title -text "Create new branch" + label $top.title -text [mc "Create new branch"] grid $top.title - -pady 10 - label $top.id -text "ID:" + label $top.id -text [mc "ID:"] entry $top.sha1 -width 40 -relief flat $top.sha1 insert 0 $rowmenuid $top.sha1 conf -state readonly grid $top.id $top.sha1 -sticky w - label $top.nlab -text "Name:" + label $top.nlab -text [mc "Name:"] entry $top.name -width 40 grid $top.nlab $top.name -sticky w frame $top.buts - button $top.buts.go -text "Create" -command [list mkbrgo $top] - button $top.buts.can -text "Cancel" -command "catch {destroy $top}" + button $top.buts.go -text [mc "Create"] -command [list mkbrgo $top] + button $top.buts.can -text [mc "Cancel"] -command "catch {destroy $top}" grid $top.buts.go $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -6333,7 +6975,7 @@ proc mkbrgo {top} { set name [$top.name get] set id [$top.sha1 get] if {$name eq {}} { - error_popup "Please specify a name for the new branch" + error_popup [mc "Please specify a name for the new branch"] return } catch {destroy $top} @@ -6356,17 +6998,18 @@ proc mkbrgo {top} { } proc cherrypick {} { - global rowmenuid curview commitrow + global rowmenuid curview global mainhead set oldhead [exec git rev-parse HEAD] set dheads [descheads $rowmenuid] if {$dheads ne {} && [lsearch -exact $dheads $oldhead] >= 0} { - set ok [confirm_popup "Commit [string range $rowmenuid 0 7] is already\ - included in branch $mainhead -- really re-apply it?"] + set ok [confirm_popup [mc "Commit %s is already\ + included in branch %s -- really re-apply it?" \ + [string range $rowmenuid 0 7] $mainhead]] if {!$ok} return } - nowbusy cherrypick + nowbusy cherrypick [mc "Cherry-picking"] update # Unfortunately git-cherry-pick writes stuff to stderr even when # no error occurs, and exec takes that as an indication of error... @@ -6378,12 +7021,12 @@ proc cherrypick {} { set newhead [exec git rev-parse HEAD] if {$newhead eq $oldhead} { notbusy cherrypick - error_popup "No changes committed" + error_popup [mc "No changes committed"] return } addnewchild $newhead $oldhead - if {[info exists commitrow($curview,$oldhead)]} { - insertrow $commitrow($curview,$oldhead) $newhead + if {[commitinview $oldhead $curview]} { + insertrow $newhead $oldhead $curview if {$mainhead ne {}} { movehead $newhead $mainhead movedhead $newhead $mainhead @@ -6401,28 +7044,28 @@ proc resethead {} { set w ".confirmreset" toplevel $w wm transient $w . - wm title $w "Confirm reset" + wm title $w [mc "Confirm reset"] message $w.m -text \ - "Reset branch $mainhead to [string range $rowmenuid 0 7]?" \ + [mc "Reset branch %s to %s?" $mainhead [string range $rowmenuid 0 7]] \ -justify center -aspect 1000 pack $w.m -side top -fill x -padx 20 -pady 20 frame $w.f -relief sunken -border 2 - message $w.f.rt -text "Reset type:" -aspect 1000 + message $w.f.rt -text [mc "Reset type:"] -aspect 1000 grid $w.f.rt -sticky w set resettype mixed radiobutton $w.f.soft -value soft -variable resettype -justify left \ - -text "Soft: Leave working tree and index untouched" + -text [mc "Soft: Leave working tree and index untouched"] grid $w.f.soft -sticky w radiobutton $w.f.mixed -value mixed -variable resettype -justify left \ - -text "Mixed: Leave working tree untouched, reset index" + -text [mc "Mixed: Leave working tree untouched, reset index"] grid $w.f.mixed -sticky w radiobutton $w.f.hard -value hard -variable resettype -justify left \ - -text "Hard: Reset working tree and index\n(discard ALL local changes)" + -text [mc "Hard: Reset working tree and index\n(discard ALL local changes)"] grid $w.f.hard -sticky w pack $w.f -side top -fill x - button $w.ok -text OK -command "set confirm_ok 1; destroy $w" + button $w.ok -text [mc OK] -command "set confirm_ok 1; destroy $w" pack $w.ok -side left -fill x -padx 20 -pady 20 - button $w.cancel -text Cancel -command "destroy $w" + button $w.cancel -text [mc Cancel] -command "destroy $w" pack $w.cancel -side right -fill x -padx 20 -pady 20 bind $w "grab $w; focus $w" tkwait window $w @@ -6432,32 +7075,23 @@ proc resethead {} { error_popup $err } else { dohidelocalchanges - set w ".resetprogress" - filerun $fd [list readresetstat $fd $w] - toplevel $w - wm transient $w - wm title $w "Reset progress" - message $w.m -text "Reset in progress, please wait..." \ - -justify center -aspect 1000 - pack $w.m -side top -fill x -padx 20 -pady 5 - canvas $w.c -width 150 -height 20 -bg white - $w.c create rect 0 0 0 20 -fill green -tags rect - pack $w.c -side top -fill x -padx 20 -pady 5 -expand 1 - nowbusy reset + filerun $fd [list readresetstat $fd] + nowbusy reset [mc "Resetting"] } } -proc readresetstat {fd w} { - global mainhead mainheadid showlocalchanges +proc readresetstat {fd} { + global mainhead mainheadid showlocalchanges rprogcoord if {[gets $fd line] >= 0} { if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} { - set x [expr {($m * 150) / $n}] - $w.c coords rect 0 0 $x 20 + set rprogcoord [expr {1.0 * $m / $n}] + adjustprogress } return 1 } - destroy $w + set rprogcoord 0 + adjustprogress notbusy reset if {[catch {close $fd} err]} { error_popup $err @@ -6499,7 +7133,7 @@ proc cobranch {} { # check the tree is clean first?? set oldmainhead $mainhead - nowbusy checkout + nowbusy checkout [mc "Checking out"] update dohidelocalchanges if {[catch { @@ -6529,14 +7163,14 @@ proc rmbranch {} { set id $headmenuid # this check shouldn't be needed any more... if {$head eq $mainhead} { - error_popup "Cannot delete the currently checked-out branch" + error_popup [mc "Cannot delete the currently checked-out branch"] return } set dheads [descheads $id] if {[llength $dheads] == 1 && $idheads($dheads) eq $head} { # the stuff on this branch isn't on any other branch - if {![confirm_popup "The commits on branch $head aren't on any other\ - branch.\nReally delete branch $head?"]} return + if {![confirm_popup [mc "The commits on branch %s aren't on any other\ + branch.\nReally delete branch %s?" $head $head]]} return } nowbusy rmbranch update @@ -6566,7 +7200,7 @@ proc showrefs {} { return } toplevel $top - wm title $top "Tags and heads: [file tail [pwd]]" + wm title $top [mc "Tags and heads: %s" [file tail [pwd]]] text $top.list -background $bgcolor -foreground $fgcolor \ -selectbackground $selectbgcolor -font mainfont \ -xscrollcommand "$top.xsb set" -yscrollcommand "$top.ysb set" \ @@ -6580,15 +7214,14 @@ proc showrefs {} { grid $top.list $top.ysb -sticky nsew grid $top.xsb x -sticky ew frame $top.f - label $top.f.l -text "Filter: " -font uifont - entry $top.f.e -width 20 -textvariable reflistfilter -font uifont + label $top.f.l -text "[mc "Filter"]: " + entry $top.f.e -width 20 -textvariable reflistfilter set reflistfilter "*" trace add variable reflistfilter write reflistfilter_change pack $top.f.e -side right -fill x -expand 1 pack $top.f.l -side left grid $top.f - -sticky ew -pady 2 - button $top.close -command [list destroy $top] -text "Close" \ - -font uifont + button $top.close -command [list destroy $top] -text [mc "Close"] grid $top.close - grid columnconfigure $top 0 -weight 1 grid rowconfigure $top 0 -weight 1 @@ -6630,13 +7263,13 @@ proc reflistfilter_change {n1 n2 op} { proc refill_reflist {} { global reflist reflistfilter showrefstop headids tagids otherrefids - global commitrow curview commitinterest + global curview commitinterest if {![info exists showrefstop] || ![winfo exists $showrefstop]} return set refs {} foreach n [array names headids] { if {[string match $reflistfilter $n]} { - if {[info exists commitrow($curview,$headids($n))]} { + if {[commitinview $headids($n) $curview]} { lappend refs [list $n H] } else { set commitinterest($headids($n)) {run refill_reflist} @@ -6645,7 +7278,7 @@ proc refill_reflist {} { } foreach n [array names tagids] { if {[string match $reflistfilter $n]} { - if {[info exists commitrow($curview,$tagids($n))]} { + if {[commitinview $tagids($n) $curview]} { lappend refs [list $n T] } else { set commitinterest($tagids($n)) {run refill_reflist} @@ -6654,7 +7287,7 @@ proc refill_reflist {} { } foreach n [array names otherrefids] { if {[string match $reflistfilter $n]} { - if {[info exists commitrow($curview,$otherrefids($n))]} { + if {[commitinview $otherrefids($n) $curview]} { lappend refs [list $n o] } else { set commitinterest($otherrefids($n)) {run refill_reflist} @@ -6875,9 +7508,9 @@ proc getallclines {fd} { dropcache $err return } - error_popup "Error reading commit topology information;\ + error_popup "[mc "Error reading commit topology information;\ branch and preceding/following tag information\ - will be incomplete.\n($err)" + will be incomplete."]\n($err)" set cacheok 0 } if {[incr allcommits -1] == 0} { @@ -6967,7 +7600,7 @@ proc addnewchild {id p} { global arcnos arcids arctags arcout arcend arcstart archeads growing global seeds allcommits - if {![info exists allcommits]} return + if {![info exists allcommits] || ![info exists arcnos($p)]} return set allparents($id) [list $p] set allchildren($id) {} set arcnos($id) {} @@ -7798,7 +8431,7 @@ proc changedrefs {} { } proc rereadrefs {} { - global idtags idheads idotherrefs mainhead + global idtags idheads idotherrefs mainheadid set refids [concat [array names idtags] \ [array names idheads] [array names idotherrefs]] @@ -7807,7 +8440,7 @@ proc rereadrefs {} { set ref($id) [listrefs $id] } } - set oldmainhead $mainhead + set oldmainhead $mainheadid readrefs changedrefs set refids [lsort -unique [concat $refids [array names idtags] \ @@ -7815,8 +8448,8 @@ proc rereadrefs {} { foreach id $refids { set v [listrefs $id] if {![info exists ref($id)] || $ref($id) != $v || - ($id eq $oldmainhead && $id ne $mainhead) || - ($id eq $mainhead && $id ne $oldmainhead)} { + ($id eq $oldmainhead && $id ne $mainheadid) || + ($id eq $mainheadid && $id ne $oldmainhead)} { redrawtags $id } } @@ -7859,7 +8492,7 @@ proc showtag {tag isnew} { if {[info exists tagcontents($tag)]} { set text $tagcontents($tag) } else { - set text "Tag: $tag\nId: $tagids($tag)" + set text "[mc "Tag"]: $tag\n[mc "Id"]: $tagids($tag)" } appendwithlinks $text {} $ctext conf -state disabled @@ -7899,8 +8532,8 @@ proc choosefont {font which} { font create sample eval font config sample [font actual $font] toplevel $top - wm title $top "Gitk font chooser" - label $top.l -textvariable fontparam(which) -font uifont + wm title $top [mc "Gitk font chooser"] + label $top.l -textvariable fontparam(which) pack $top.l -side top set fontlist [lsort [font families]] frame $top.f @@ -7916,10 +8549,10 @@ proc choosefont {font which} { -textvariable fontparam(size) \ -validatecommand {string is integer -strict %s} checkbutton $top.g.bold -padx 5 \ - -font {{Times New Roman} 12 bold} -text "B" -indicatoron 0 \ + -font {{Times New Roman} 12 bold} -text [mc "B"] -indicatoron 0 \ -variable fontparam(weight) -onvalue bold -offvalue normal checkbutton $top.g.ital -padx 5 \ - -font {{Times New Roman} 12 italic} -text "I" -indicatoron 0 \ + -font {{Times New Roman} 12 italic} -text [mc "I"] -indicatoron 0 \ -variable fontparam(slant) -onvalue italic -offvalue roman pack $top.g.size $top.g.bold $top.g.ital -side left pack $top.g -side top @@ -7930,10 +8563,8 @@ proc choosefont {font which} { bind $top.c [list centertext $top.c] pack $top.c -side top -fill x frame $top.buts - button $top.buts.ok -text "OK" -command fontok -default active \ - -font uifont - button $top.buts.can -text "Cancel" -command fontcan -default normal \ - -font uifont + button $top.buts.ok -text [mc "OK"] -command fontok -default active + button $top.buts.can -text [mc "Cancel"] -command fontcan -default normal grid $top.buts.ok $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -8001,7 +8632,7 @@ proc doprefs {} { global maxwidth maxgraphpct global oldprefs prefstop showneartags showlocalchanges global bgcolor fgcolor ctext diffcolors selectbgcolor - global uifont tabstop + global tabstop limitdiffs set top .gitkprefs set prefstop $top @@ -8009,85 +8640,85 @@ proc doprefs {} { raise $top return } - foreach v {maxwidth maxgraphpct showneartags showlocalchanges} { + foreach v {maxwidth maxgraphpct showneartags showlocalchanges \ + limitdiffs tabstop} { set oldprefs($v) [set $v] } toplevel $top - wm title $top "Gitk preferences" - label $top.ldisp -text "Commit list display options" - $top.ldisp configure -font uifont + wm title $top [mc "Gitk preferences"] + label $top.ldisp -text [mc "Commit list display options"] grid $top.ldisp - -sticky w -pady 10 label $top.spacer -text " " - label $top.maxwidthl -text "Maximum graph width (lines)" \ + label $top.maxwidthl -text [mc "Maximum graph width (lines)"] \ -font optionfont spinbox $top.maxwidth -from 0 -to 100 -width 4 -textvariable maxwidth grid $top.spacer $top.maxwidthl $top.maxwidth -sticky w - label $top.maxpctl -text "Maximum graph width (% of pane)" \ + label $top.maxpctl -text [mc "Maximum graph width (% of pane)"] \ -font optionfont spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct grid x $top.maxpctl $top.maxpct -sticky w frame $top.showlocal - label $top.showlocal.l -text "Show local changes" -font optionfont + label $top.showlocal.l -text [mc "Show local changes"] -font optionfont checkbutton $top.showlocal.b -variable showlocalchanges pack $top.showlocal.b $top.showlocal.l -side left grid x $top.showlocal -sticky w - label $top.ddisp -text "Diff display options" - $top.ddisp configure -font uifont + label $top.ddisp -text [mc "Diff display options"] grid $top.ddisp - -sticky w -pady 10 + label $top.tabstopl -text [mc "Tab spacing"] -font optionfont + spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop + grid x $top.tabstopl $top.tabstop -sticky w frame $top.ntag - label $top.ntag.l -text "Display nearby tags" -font optionfont + label $top.ntag.l -text [mc "Display nearby tags"] -font optionfont checkbutton $top.ntag.b -variable showneartags pack $top.ntag.b $top.ntag.l -side left grid x $top.ntag -sticky w - label $top.tabstopl -text "tabstop" -font optionfont - spinbox $top.tabstop -from 1 -to 20 -width 4 -textvariable tabstop - grid x $top.tabstopl $top.tabstop -sticky w + frame $top.ldiff + label $top.ldiff.l -text [mc "Limit diffs to listed paths"] -font optionfont + checkbutton $top.ldiff.b -variable limitdiffs + pack $top.ldiff.b $top.ldiff.l -side left + grid x $top.ldiff -sticky w - label $top.cdisp -text "Colors: press to choose" - $top.cdisp configure -font uifont + label $top.cdisp -text [mc "Colors: press to choose"] grid $top.cdisp - -sticky w -pady 10 label $top.bg -padx 40 -relief sunk -background $bgcolor - button $top.bgbut -text "Background" -font optionfont \ + button $top.bgbut -text [mc "Background"] -font optionfont \ -command [list choosecolor bgcolor 0 $top.bg background setbg] grid x $top.bgbut $top.bg -sticky w label $top.fg -padx 40 -relief sunk -background $fgcolor - button $top.fgbut -text "Foreground" -font optionfont \ + button $top.fgbut -text [mc "Foreground"] -font optionfont \ -command [list choosecolor fgcolor 0 $top.fg foreground setfg] grid x $top.fgbut $top.fg -sticky w label $top.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0] - button $top.diffoldbut -text "Diff: old lines" -font optionfont \ + button $top.diffoldbut -text [mc "Diff: old lines"] -font optionfont \ -command [list choosecolor diffcolors 0 $top.diffold "diff old lines" \ [list $ctext tag conf d0 -foreground]] grid x $top.diffoldbut $top.diffold -sticky w label $top.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1] - button $top.diffnewbut -text "Diff: new lines" -font optionfont \ + button $top.diffnewbut -text [mc "Diff: new lines"] -font optionfont \ -command [list choosecolor diffcolors 1 $top.diffnew "diff new lines" \ [list $ctext tag conf d1 -foreground]] grid x $top.diffnewbut $top.diffnew -sticky w label $top.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2] - button $top.hunksepbut -text "Diff: hunk header" -font optionfont \ + button $top.hunksepbut -text [mc "Diff: hunk header"] -font optionfont \ -command [list choosecolor diffcolors 2 $top.hunksep \ "diff hunk header" \ [list $ctext tag conf hunksep -foreground]] grid x $top.hunksepbut $top.hunksep -sticky w label $top.selbgsep -padx 40 -relief sunk -background $selectbgcolor - button $top.selbgbut -text "Select bg" -font optionfont \ + button $top.selbgbut -text [mc "Select bg"] -font optionfont \ -command [list choosecolor selectbgcolor 0 $top.selbgsep background setselbg] grid x $top.selbgbut $top.selbgsep -sticky w - label $top.cfont -text "Fonts: press to choose" - $top.cfont configure -font uifont + label $top.cfont -text [mc "Fonts: press to choose"] grid $top.cfont - -sticky w -pady 10 - mkfontdisp mainfont $top "Main font" - mkfontdisp textfont $top "Diff display font" - mkfontdisp uifont $top "User interface font" + mkfontdisp mainfont $top [mc "Main font"] + mkfontdisp textfont $top [mc "Diff display font"] + mkfontdisp uifont $top [mc "User interface font"] frame $top.buts - button $top.buts.ok -text "OK" -command prefsok -default active - $top.buts.ok configure -font uifont - button $top.buts.can -text "Cancel" -command prefscan -default normal - $top.buts.can configure -font uifont + button $top.buts.ok -text [mc "OK"] -command prefsok -default active + button $top.buts.can -text [mc "Cancel"] -command prefscan -default normal grid $top.buts.ok $top.buts.can grid columnconfigure $top.buts 0 -weight 1 -uniform a grid columnconfigure $top.buts 1 -weight 1 -uniform a @@ -8099,7 +8730,7 @@ proc choosecolor {v vi w x cmd} { global $v set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \ - -title "Gitk: choose color for $x"] + -title [mc "Gitk: choose color for %s" $x]] if {$c eq {}} return $w conf -background $c lset $v $vi $c @@ -8135,10 +8766,11 @@ proc setfg {c} { } proc prefscan {} { - global maxwidth maxgraphpct - global oldprefs prefstop showneartags showlocalchanges + global oldprefs prefstop - foreach v {maxwidth maxgraphpct showneartags showlocalchanges} { + foreach v {maxwidth maxgraphpct showneartags showlocalchanges \ + limitdiffs tabstop} { + global $v set $v $oldprefs($v) } catch {destroy $prefstop} @@ -8150,6 +8782,7 @@ proc prefsok {} { global maxwidth maxgraphpct global oldprefs prefstop showneartags showlocalchanges global fontpref mainfont textfont uifont + global limitdiffs treediffs catch {destroy $prefstop} unset prefstop @@ -8182,10 +8815,15 @@ proc prefsok {} { dohidelocalchanges } } + if {$limitdiffs != $oldprefs(limitdiffs)} { + # treediffs elements are limited by path + catch {unset treediffs} + } if {$fontchanged || $maxwidth != $oldprefs(maxwidth) || $maxgraphpct != $oldprefs(maxgraphpct)} { redisplay - } elseif {$showneartags != $oldprefs(showneartags)} { + } elseif {$showneartags != $oldprefs(showneartags) || + $limitdiffs != $oldprefs(limitdiffs)} { reselectline } } @@ -8471,6 +9109,13 @@ proc tcl_encoding {enc} { return {} } +# First check that Tcl/Tk is recent enough +if {[catch {package require Tk 8.4} err]} { + show_error {} . [mc "Sorry, gitk cannot run with this version of Tcl/Tk.\n\ + Gitk requires at least Tcl/Tk 8.4."] + exit 1 +} + # defaults... set datemode 0 set wrcomcmd "git diff-tree --stdin -p --pretty" @@ -8505,6 +9150,7 @@ set showneartags 1 set maxrefs 20 set maxlinelen 200 set showlocalchanges 1 +set limitdiffs 1 set datetimeformat "%Y-%m-%d %H:%M:%S" set colors {green red blue magenta darkgrey brown orange} @@ -8514,6 +9160,25 @@ set diffcolors {red "#00a000" blue} set diffcontext 3 set selectbgcolor gray85 +## For msgcat loading, first locate the installation location. +if { [info exists ::env(GITK_MSGSDIR)] } { + ## Msgsdir was manually set in the environment. + set gitk_msgsdir $::env(GITK_MSGSDIR) +} else { + ## Let's guess the prefix from argv0. + set gitk_prefix [file dirname [file dirname [file normalize $argv0]]] + set gitk_libdir [file join $gitk_prefix share gitk lib] + set gitk_msgsdir [file join $gitk_libdir msgs] + unset gitk_prefix +} + +## Internationalization (i18n) through msgcat and gettext. See +## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html +package require msgcat +namespace import ::msgcat::mc +## And eventually load the actual message catalog +::msgcat::mcload $gitk_msgsdir + catch {source ~/.gitk} font create optionfont -family sans-serif -size -12 @@ -8529,16 +9194,19 @@ eval font create textfontbold [fontflags textfont 1] parsefont uifont $uifont eval font create uifont [fontflags uifont] +setoptions + # check that we can find a .git directory somewhere... if {[catch {set gitdir [gitdir]}]} { - show_error {} . "Cannot find a git repository here." + show_error {} . [mc "Cannot find a git repository here."] exit 1 } if {![file isdirectory $gitdir]} { - show_error {} . "Cannot find the git directory \"$gitdir\"." + show_error {} . [mc "Cannot find the git directory \"%s\"." $gitdir] exit 1 } +set mergeonly 0 set revtreeargs {} set cmdline_files {} set i 0 @@ -8546,6 +9214,10 @@ foreach arg $argv { switch -- $arg { "" { } "-d" { set datemode 1 } + "--merge" { + set mergeonly 1 + lappend revtreeargs $arg + } "--" { set cmdline_files [lrange $argv [expr {$i + 1}] end] break @@ -8569,8 +9241,8 @@ if {$i >= [llength $argv] && $revtreeargs ne {}} { # with git log and git rev-list, check revtreeargs for filenames. foreach arg $revtreeargs { if {[file exists $arg]} { - show_error {} . "Ambiguous argument '$arg': both revision\ - and filename" + show_error {} . [mc "Ambiguous argument '%s': both revision\ + and filename" $arg] exit 1 } } @@ -8581,9 +9253,43 @@ if {$i >= [llength $argv] && $revtreeargs ne {}} { if {$i > 0} { set err [string range $err [expr {$i + 6}] end] } - show_error {} . "Bad arguments to gitk:\n$err" + show_error {} . "[mc "Bad arguments to gitk:"]\n$err" + exit 1 + } +} + +if {$mergeonly} { + # find the list of unmerged files + set mlist {} + set nr_unmerged 0 + if {[catch { + set fd [open "| git ls-files -u" r] + } err]} { + show_error {} . "[mc "Couldn't get list of unmerged files:"] $err" + exit 1 + } + while {[gets $fd line] >= 0} { + set i [string first "\t" $line] + if {$i < 0} continue + set fname [string range $line [expr {$i+1}] end] + if {[lsearch -exact $mlist $fname] >= 0} continue + incr nr_unmerged + if {$cmdline_files eq {} || [path_filter $cmdline_files $fname]} { + lappend mlist $fname + } + } + catch {close $fd} + if {$mlist eq {}} { + if {$nr_unmerged == 0} { + show_error {} . [mc "No files selected: --merge specified but\ + no files are unmerged."] + } else { + show_error {} . [mc "No files selected: --merge specified but\ + no unmerged files are within file limit."] + } exit 1 } + set cmdline_files $mlist } set nullid "0000000000000000000000000000000000000000" @@ -8611,19 +9317,18 @@ set firsttabstop 0 set nextviewnum 1 set curview 0 set selectedview 0 -set selectedhlview None -set highlight_related None +set selectedhlview [mc "None"] +set highlight_related [mc "None"] set highlight_files {} set viewfiles(0) {} set viewperm(0) 0 set viewargs(0) {} +set loginstance 0 set cmdlineok 0 set stopped 0 set stuffsaved 0 set patchnum 0 -set localirow -1 -set localfrow -1 set lserial 0 setcoords makewindow @@ -8637,13 +9342,13 @@ if {$cmdline_files ne {} || $revtreeargs ne {}} { set curview 1 set selectedview 1 set nextviewnum 2 - set viewname(1) "Command line" + set viewname(1) [mc "Command line"] set viewfiles(1) $cmdline_files set viewargs(1) $revtreeargs set viewperm(1) 0 addviewmenu 1 - .bar.view entryconf Edit* -state normal - .bar.view entryconf Delete* -state normal + .bar.view entryconf [mc "Edit view..."] -state normal + .bar.view entryconf [mc "Delete view"] -state normal } if {[info exists permviews]} {