# Tcl ignores the next line -*- tcl -*- \
exec wish "$0" -- "$@"
-# Copyright (C) 2005-2006 Paul Mackerras. All rights reserved.
+# Copyright © 2005-2008 Paul Mackerras. All rights reserved.
# This program is free software; it may be used, copied, modified
# and distributed under the terms of the GNU General Public Licence,
# either version 2, or (at your option) any later version.
# run before X event handlers, so reading from a fast source can
# make the GUI completely unresponsive.
proc run args {
- global isonrunq runq
+ global isonrunq runq currunq
set script $args
if {[info exists isonrunq($script)]} return
- if {$runq eq {}} {
+ if {$runq eq {} && ![info exists currunq]} {
after idle dorunq
}
lappend runq [list {} $script]
}
proc filereadable {fd script} {
- global runq
+ global runq currunq
fileevent $fd readable {}
- if {$runq eq {}} {
+ if {$runq eq {} && ![info exists currunq]} {
after idle dorunq
}
lappend runq [list $fd $script]
}
proc dorunq {} {
- global isonrunq runq
+ global isonrunq runq currunq
set tstart [clock clicks -milliseconds]
set t0 $tstart
while {[llength $runq] > 0} {
set fd [lindex $runq 0 0]
set script [lindex $runq 0 1]
+ set currunq [lindex $runq 0]
+ set runq [lrange $runq 1 end]
set repeat [eval $script]
+ unset currunq
set t1 [clock clicks -milliseconds]
set t [expr {$t1 - $t0}]
- set runq [lrange $runq 1 end]
if {$repeat ne {} && $repeat} {
if {$fd eq {} || $repeat == 2} {
# script returns 1 if it wants to be readded
}
}
-# Start off a git rev-list process and arrange to read its output
+proc reg_instance {fd} {
+ global commfd leftover loginstance
+
+ set i [incr loginstance]
+ set commfd($i) $fd
+ set leftover($i) {}
+ return $i
+}
+
+proc unmerged_files {files} {
+ global nr_unmerged
+
+ # 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 {$files eq {} || [path_filter $files $fname]} {
+ lappend mlist $fname
+ }
+ }
+ catch {close $fd}
+ return $mlist
+}
+
+proc parseviewargs {n arglist} {
+ global vdatemode vmergeonly vflags vdflags vrevs vfiltered vorigargs
+
+ set vdatemode($n) 0
+ set vmergeonly($n) 0
+ set glflags {}
+ set diffargs {}
+ set nextisval 0
+ set revargs {}
+ set origargs $arglist
+ set allknown 1
+ set filtered 0
+ set i -1
+ foreach arg $arglist {
+ incr i
+ if {$nextisval} {
+ lappend glflags $arg
+ set nextisval 0
+ continue
+ }
+ switch -glob -- $arg {
+ "-d" -
+ "--date-order" {
+ set vdatemode($n) 1
+ # remove from origargs in case we hit an unknown option
+ set origargs [lreplace $origargs $i $i]
+ incr i -1
+ }
+ # These request or affect diff output, which we don't want.
+ # Some could be used to set our defaults for diff display.
+ "-[puabwcrRBMC]" -
+ "--no-renames" - "--full-index" - "--binary" - "--abbrev=*" -
+ "--find-copies-harder" - "-l*" - "--ext-diff" - "--no-ext-diff" -
+ "--src-prefix=*" - "--dst-prefix=*" - "--no-prefix" -
+ "-O*" - "--text" - "--full-diff" - "--ignore-space-at-eol" -
+ "--ignore-space-change" - "-U*" - "--unified=*" {
+ lappend diffargs $arg
+ }
+ # These cause our parsing of git log's output to fail, or else
+ # they're options we want to set ourselves, so ignore them.
+ "--raw" - "--patch-with-raw" - "--patch-with-stat" -
+ "--name-only" - "--name-status" - "--color" - "--color-words" -
+ "--log-size" - "--pretty=*" - "--decorate" - "--abbrev-commit" -
+ "--cc" - "-z" - "--header" - "--parents" - "--boundary" -
+ "--no-color" - "-g" - "--walk-reflogs" - "--no-walk" -
+ "--timestamp" - "relative-date" - "--date=*" - "--stdin" -
+ "--objects" - "--objects-edge" - "--reverse" {
+ }
+ # These are harmless, and some are even useful
+ "--stat=*" - "--numstat" - "--shortstat" - "--summary" -
+ "--check" - "--exit-code" - "--quiet" - "--topo-order" -
+ "--full-history" - "--dense" - "--sparse" -
+ "--follow" - "--left-right" - "--encoding=*" {
+ lappend glflags $arg
+ }
+ # These mean that we get a subset of the commits
+ "--diff-filter=*" - "--no-merges" - "--unpacked" -
+ "--max-count=*" - "--skip=*" - "--since=*" - "--after=*" -
+ "--until=*" - "--before=*" - "--max-age=*" - "--min-age=*" -
+ "--author=*" - "--committer=*" - "--grep=*" - "-[iE]" -
+ "--remove-empty" - "--first-parent" - "--cherry-pick" -
+ "-S*" - "--pickaxe-all" - "--pickaxe-regex" - {
+ set filtered 1
+ lappend glflags $arg
+ }
+ # This appears to be the only one that has a value as a
+ # separate word following it
+ "-n" {
+ set filtered 1
+ set nextisval 1
+ lappend glflags $arg
+ }
+ "--not" {
+ set notflag [expr {!$notflag}]
+ lappend revargs $arg
+ }
+ "--all" {
+ lappend revargs $arg
+ }
+ "--merge" {
+ set vmergeonly($n) 1
+ # git rev-parse doesn't understand --merge
+ lappend revargs --gitk-symmetric-diff-marker MERGE_HEAD...HEAD
+ }
+ # Other flag arguments including -<n>
+ "-*" {
+ if {[string is digit -strict [string range $arg 1 end]]} {
+ set filtered 1
+ } else {
+ # a flag argument that we don't recognize;
+ # that means we can't optimize
+ set allknown 0
+ }
+ lappend glflags $arg
+ }
+ # Non-flag arguments specify commits or ranges of commits
+ default {
+ if {[string match "*...*" $arg]} {
+ lappend revargs --gitk-symmetric-diff-marker
+ }
+ lappend revargs $arg
+ }
+ }
+ }
+ set vdflags($n) $diffargs
+ set vflags($n) $glflags
+ set vrevs($n) $revargs
+ set vfiltered($n) $filtered
+ set vorigargs($n) $origargs
+ return $allknown
+}
+
+proc parseviewrevs {view revs} {
+ global vposids vnegids
+
+ if {$revs eq {}} {
+ set revs HEAD
+ }
+ if {[catch {set ids [eval exec git rev-parse $revs]} err]} {
+ # we get stdout followed by stderr in $err
+ # for an unknown rev, git rev-parse echoes it and then errors out
+ set errlines [split $err "\n"]
+ set badrev {}
+ for {set l 0} {$l < [llength $errlines]} {incr l} {
+ set line [lindex $errlines $l]
+ if {!([string length $line] == 40 && [string is xdigit $line])} {
+ if {[string match "fatal:*" $line]} {
+ if {[string match "fatal: ambiguous argument*" $line]
+ && $badrev ne {}} {
+ if {[llength $badrev] == 1} {
+ set err "unknown revision $badrev"
+ } else {
+ set err "unknown revisions: [join $badrev ", "]"
+ }
+ } else {
+ set err [join [lrange $errlines $l end] "\n"]
+ }
+ break
+ }
+ lappend badrev $line
+ }
+ }
+ error_popup "Error parsing revisions: $err"
+ return {}
+ }
+ set ret {}
+ set pos {}
+ set neg {}
+ set sdm 0
+ foreach id [split $ids "\n"] {
+ if {$id eq "--gitk-symmetric-diff-marker"} {
+ set sdm 4
+ } elseif {[string match "^*" $id]} {
+ if {$sdm != 1} {
+ lappend ret $id
+ if {$sdm == 3} {
+ set sdm 0
+ }
+ }
+ lappend neg [string range $id 1 end]
+ } else {
+ if {$sdm != 2} {
+ lappend ret $id
+ } else {
+ lset ret end [lindex $ret end]...$id
+ }
+ lappend pos $id
+ }
+ incr sdm -1
+ }
+ set vposids($view) $pos
+ set vnegids($view) $neg
+ return $ret
+}
+
+# Start off a git log process and arrange to read its output
proc start_rev_list {view} {
- global startmsecs
- global commfd leftover tclencoding datemode
- global viewargs viewfiles commitidx viewcomplete vnextroot
- global showlocalchanges commitinterest mainheadid
- global progressdirn progresscoords proglastnc curview
- global viewincl viewactive loginstance viewinstances
+ global startmsecs commitidx viewcomplete curview
+ global tclencoding
+ global viewargs viewargscmd viewfiles vfilelimit
+ global showlocalchanges commitinterest
+ global viewactive viewinstances vmergeonly
+ global mainheadid
+ global vcanopt vflags vrevs vorigargs
set startmsecs [clock clicks -milliseconds]
set commitidx($view) 0
- set viewcomplete($view) 0
- set viewactive($view) 1
- set vnextroot($view) 0
+ # these are set this way for the error exits
+ set viewcomplete($view) 1
+ set viewactive($view) 0
varcinit $view
- set commits [eval exec git rev-parse --default HEAD --revs-only \
- $viewargs($view)]
- set viewincl($view) {}
- foreach c $commits {
- if {![string match "^*" $c]} {
- lappend viewincl($view) $c
+ set args $viewargs($view)
+ if {$viewargscmd($view) ne {}} {
+ if {[catch {
+ set str [exec sh -c $viewargscmd($view)]
+ } err]} {
+ error_popup "Error executing --argscmd command: $err"
+ return 0
}
+ set args [concat $args [split $str "\n"]]
}
+ set vcanopt($view) [parseviewargs $view $args]
+
+ set files $viewfiles($view)
+ if {$vmergeonly($view)} {
+ set files [unmerged_files $files]
+ if {$files eq {}} {
+ global nr_unmerged
+ if {$nr_unmerged == 0} {
+ error_popup [mc "No files selected: --merge specified but\
+ no files are unmerged."]
+ } else {
+ error_popup [mc "No files selected: --merge specified but\
+ no unmerged files are within file limit."]
+ }
+ return 0
+ }
+ }
+ set vfilelimit($view) $files
+
+ if {$vcanopt($view)} {
+ set revs [parseviewrevs $view $vrevs($view)]
+ if {$revs eq {}} {
+ return 0
+ }
+ set args [concat $vflags($view) $revs]
+ } else {
+ set args $vorigargs($view)
+ }
+
if {[catch {
set fd [open [concat | git log --no-color -z --pretty=raw --parents \
- --boundary $commits "--" $viewfiles($view)] r]
+ --boundary $args "--" $files] r]
} err]} {
- error_popup "Error executing git log: $err"
- exit 1
+ error_popup "[mc "Error executing git log:"] $err"
+ return 0
}
- set i [incr loginstance]
+ set i [reg_instance $fd]
set viewinstances($view) [list $i]
- set commfd($i) $fd
- set leftover($i) {}
- if {$showlocalchanges} {
+ if {$showlocalchanges && $mainheadid ne {}} {
lappend commitinterest($mainheadid) {dodiffindex}
}
fconfigure $fd -blocking 0 -translation lf -eofchar {}
if {$tclencoding != {}} {
fconfigure $fd -encoding $tclencoding
}
- filerun $fd [list getcommitlines $fd $i $view]
- nowbusy $view "Reading"
- if {$view == $curview} {
- set progressdirn 1
- set progresscoords {0 0}
- set proglastnc 0
+ filerun $fd [list getcommitlines $fd $i $view 0]
+ nowbusy $view [mc "Reading"]
+ set viewcomplete($view) 0
+ set viewactive($view) 1
+ return 1
+}
+
+proc stop_instance {inst} {
+ global commfd leftover
+
+ set fd $commfd($inst)
+ catch {
+ set pid [pid $fd]
+
+ if {$::tcl_platform(platform) eq {windows}} {
+ exec kill -f $pid
+ } else {
+ exec kill $pid
+ }
+ }
+ catch {close $fd}
+ nukefile $fd
+ unset commfd($inst)
+ unset leftover($inst)
+}
+
+proc stop_backends {} {
+ global commfd
+
+ foreach inst [array names commfd] {
+ stop_instance $inst
}
}
proc stop_rev_list {view} {
- global commfd viewinstances leftover
+ global viewinstances
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)
+ stop_instance $inst
}
set viewinstances($view) {}
}
-proc getcommits {} {
- global canv curview
+proc reset_pending_select {selid} {
+ global pending_select mainheadid selectheadid
+
+ if {$selid ne {}} {
+ set pending_select $selid
+ } elseif {$selectheadid ne {}} {
+ set pending_select $selectheadid
+ } else {
+ set pending_select $mainheadid
+ }
+}
+
+proc getcommits {selid} {
+ global canv curview need_redisplay viewactive
initlayout
- start_rev_list $curview
- show_status "Reading commits..."
+ if {[start_rev_list $curview]} {
+ reset_pending_select $selid
+ show_status [mc "Reading commits..."]
+ set need_redisplay 1
+ } else {
+ show_status [mc "No commits selected"]
+ }
}
proc updatecommits {} {
- global curview viewargs viewfiles viewincl viewinstances
- global viewactive viewcomplete loginstance tclencoding
- global varcid startmsecs commfd getdbg showneartags leftover
-
- set getdbg 1
+ global curview vcanopt vorigargs vfilelimit viewinstances
+ global viewactive viewcomplete tclencoding
+ global startmsecs showneartags showlocalchanges
+ global mainheadid pending_select
+ global isworktree
+ global varcid vposids vnegids vflags vrevs
+
+ set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
+ 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 {}
- foreach c $commits {
- if {[string match "^*" $c]} {
- lappend neg $c
- } else {
- if {!([info exists varcid($view,$c)] ||
- [lsearch -exact $viewincl($view) $c] >= 0)} {
- lappend pos $c
+ if {$vcanopt($view)} {
+ set oldpos $vposids($view)
+ set oldneg $vnegids($view)
+ set revs [parseviewrevs $view $vrevs($view)]
+ if {$revs eq {}} {
+ return
+ }
+ # note: getting the delta when negative refs change is hard,
+ # and could require multiple git log invocations, so in that
+ # case we ask git log for all the commits (not just the delta)
+ if {$oldneg eq $vnegids($view)} {
+ set newrevs {}
+ set npos 0
+ # take out positive refs that we asked for before or
+ # that we have already seen
+ foreach rev $revs {
+ if {[string length $rev] == 40} {
+ if {[lsearch -exact $oldpos $rev] < 0
+ && ![info exists varcid($view,$rev)]} {
+ lappend newrevs $rev
+ incr npos
+ }
+ } else {
+ lappend $newrevs $rev
+ }
}
+ if {$npos == 0} return
+ set revs $newrevs
+ set vposids($view) [lsort -unique [concat $oldpos $vposids($view)]]
}
+ set args [concat $vflags($view) $revs --not $oldpos]
+ } else {
+ set args $vorigargs($view)
}
- 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 "--" $viewfiles($view)] r]
+ --boundary $args "--" $vfilelimit($view)] r]
} err]} {
error_popup "Error executing git log: $err"
- exit 1
+ return
}
if {$viewactive($view) == 0} {
set startmsecs [clock clicks -milliseconds]
}
- set i [incr loginstance]
+ set i [reg_instance $fd]
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]
+ filerun $fd [list getcommitlines $fd $i $view 1]
incr viewactive($view)
set viewcomplete($view) 0
+ reset_pending_select {}
nowbusy $view "Reading"
- readrefs
- changedrefs
if {$showneartags} {
getallcommits
}
proc reloadcommits {} {
global curview viewcomplete selectedline currentid thickerline
global showneartags treediffs commitinterest cached_commitrow
- global progresscoords
+ global targetid
+
+ set selid {}
+ if {$selectedline ne {}} {
+ set selid $currentid
+ }
if {!$viewcomplete($curview)} {
stop_rev_list $curview
- set progresscoords {0 0}
- adjustprogress
}
resetvarcs $curview
- catch {unset selectedline}
+ set selectedline {}
catch {unset currentid}
catch {unset thickerline}
catch {unset treediffs}
clear_display
catch {unset commitinterest}
catch {unset cached_commitrow}
+ catch {unset targetid}
setcanvscroll
- getcommits
+ getcommits $selid
+ return 0
}
# This makes a string representation of a positive integer which
# --topo-order) into the order for display.
proc varcinit {view} {
- global vseeds varcstart vupptr vdownptr vleftptr varctok varcrow
- global vtokmod varcmod varcix uat
+ global varcstart vupptr vdownptr vleftptr vbackptr varctok varcrow
+ global vtokmod varcmod vrowmod varcix vlastins
- set vseeds($view) {}
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 uat 0
+ set vlastins($view) {0}
}
proc resetvarcs {view} {
catch {unset ordertok}
}
+# returns a list of the commits with no children
+proc seeds {v} {
+ global vdownptr vleftptr varcstart
+
+ set ret {}
+ set a [lindex $vdownptr($v) 0]
+ while {$a != 0} {
+ lappend ret [lindex $varcstart($v) $a]
+ set a [lindex $vleftptr($v) $a]
+ }
+ return $ret
+}
+
proc newvarc {view id} {
- global varcid varctok parents children vseeds
- global vupptr vdownptr vleftptr varcrow varcix varcstart
- global commitdata commitinfo vseedcount
+ global varcid varctok parents children vdatemode
+ 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} {
+ if {[llength $children($vid)] == 0 || $vdatemode($view)} {
if {![info exists commitinfo($id)]} {
parsecommit $id $commitdata($id) 1
}
set c [incr vseedcount($view,$cdate)]
set cdate [expr {$cdate ^ 0xffffffff}]
set tok "s[strrep $cdate][strrep $c]"
- lappend vseeds($view) $id
- lappend vupptr($view) 0
- set ka [lindex $vdownptr($view) 0]
- if {$ka == 0 ||
- [string compare $tok [lindex $varctok($view) $ka]] < 0} {
- lset vdownptr($view) 0 $a
- lappend vleftptr($view) $ka
- } else {
- while {[set b [lindex $vleftptr($view) $ka]] != 0 &&
- [string compare $tok [lindex $varctok($view) $b]] >= 0} {
- set ka $b
- }
- lset vleftptr($view) $ka $a
- lappend vleftptr($view) $b
- }
} else {
set tok {}
- foreach k $children($vid) {
- set ka $varcid($view,$k)
- if {[string compare [lindex $varctok($view) $ka] $tok] > 0} {
- set ki $k
- set tok [lindex $varctok($view) $ka]
- }
+ }
+ 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]
}
- set ka $varcid($view,$ki)
- lappend vupptr($view) $ka
+ }
+ if {$ka != 0} {
set i [lsearch -exact $parents($view,$ki) $id]
set j [expr {[llength $parents($view,$ki)] - 1 - $i}]
- set rsib 0
- while {[incr i] < [llength $parents($view,$ki)]} {
- set bi [lindex $parents($view,$ki) $i]
- if {[info exists varcid($view,$bi)]} {
- set b $varcid($view,$bi)
- if {[lindex $vupptr($view) $b] == $ka} {
- set rsib $b
- lappend vleftptr($view) [lindex $vleftptr($view) $b]
- lset vleftptr($view) $b $a
- break
- }
- }
- }
- if {$rsib == 0} {
- lappend vleftptr($view) [lindex $vdownptr($view) $ka]
- lset vdownptr($view) $ka $a
- }
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 varcix varcrow
+ global vupptr vdownptr vleftptr vbackptr varcix varcrow vlastins
set oa $varcid($v,$p)
set ac $varccommits($v,$oa)
set varcid($v,$id) $na
}
lappend vdownptr($v) [lindex $vdownptr($v) $oa]
+ lappend vlastins($v) [lindex $vlastins($v) $oa]
lset vdownptr($v) $oa $na
+ lset vlastins($v) $oa 0
lappend vupptr($v) $oa
lappend vleftptr($v) 0
+ lappend vbackptr($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 varcid vtokmod
+ global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod vdatemode
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)]} {
set a $b
}
foreach a $todo {
+ if {![info exists kidchanged($a)]} continue
set id [lindex $varcstart($v) $a]
- set tok {}
- foreach k $children($v,$id) {
- set ka $varcid($v,$k)
- if {[string compare [lindex $varctok($v) $ka] $tok] > 0} {
- set ki $k
- set tok [lindex $varctok($v) $ka]
+ 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 {!$vdatemode($v)} {
+ 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 {$tok ne {}} {
- set ka $varcid($v,$ki)
+ if {$ka != 0} {
set i [lsearch -exact $parents($v,$ki) $id]
set j [expr {[llength $parents($v,$ki)] - 1 - $i}]
append tok [strrep $j]
- set oldtok [lindex $varctok($v) $a]
- if {$tok eq $oldtok} continue
- lset varctok($v) $a $tok
- } else {
- set ka 0
}
+ 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} {
if {[string compare [lindex $varctok($v) $b] $vtokmod($v)] < 0} {
modify_arc $v $b
}
- set c [lindex $vdownptr($v) $b]
- if {$c == $a} {
- lset vdownptr($v) $b [lindex $vleftptr($v) $a]
+ set c [lindex $vbackptr($v) $a]
+ set d [lindex $vleftptr($v) $a]
+ if {$c == 0} {
+ lset vdownptr($v) $b $d
} else {
- set b $c
- while {$b != 0 && [lindex $vleftptr($v) $b] != $a} {
- set b [lindex $vleftptr($v) $b]
- }
- if {$b != 0} {
- lset vleftptr($v) $b [lindex $vleftptr($v) $a]
- } else {
- puts "oops couldn't find $a in chain for [lindex $vupptr($v) $a]"
- }
+ lset vleftptr($v) $c $d
+ }
+ if {$d != 0} {
+ lset vbackptr($v) $d $c
+ }
+ if {[lindex $vlastins($v) $b] == $a} {
+ lset vlastins($v) $b $c
}
lset vupptr($v) $a $ka
- set rsib 0
- while {[incr i] < [llength $parents($v,$ki)]} {
- set bi [lindex $parents($v,$ki) $i]
- if {[info exists varcid($v,$bi)]} {
- set b $varcid($v,$bi)
- if {[lindex $vupptr($v) $b] == $ka} {
- set rsib $b
- lset vleftptr($v) $a [lindex $vleftptr($v) $b]
- lset vleftptr($v) $b $a
- break
- }
- }
+ 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]
}
- if {$rsib == 0} {
- lset vleftptr($v) $a [lindex $vdownptr($v) $ka]
- lset vdownptr($v) $ka $a
+ 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"
}
+# Fix up the graph after we have found out that in view $v,
+# $p (a commit that we have already seen) is actually the parent
+# of the last commit in arc $a.
proc fix_reversal {p a v} {
- global varcid varcstart varctok vupptr vseeds
+ 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 (and taken out of the seeds list)
- if {[lindex $vupptr($v) $pa] == 0} {
- set i [lsearch -exact $vseeds($v) $p]
- if {$i >= 0} {
- set vseeds($v) [lreplace $vseeds($v) $i $i]
- } else {
- puts "oops couldn't find [shortids $p] in seeds"
- }
- renumbervarc $pa $v
- } elseif {[string compare [lindex $varctok($v) $a] \
- [lindex $varctok($v) $pa]] > 0} {
+ # 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 cmitlisted children parents varcid varctok vtokmod
+ global varccommits ordertok commitidx numcommits curview
+ global targetid targetrow
+
+ readcommit $id
+ set vid $v,$id
+ set cmitlisted($vid) 1
+ set children($vid) {}
+ set parents($vid) [list $p]
+ set a [newvarc $v $id]
+ set varcid($vid) $a
+ if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
+ modify_arc $v $a
+ }
+ lappend varccommits($v,$a) $id
+ set vp $v,$p
+ if {[llength [lappend children($vp) $id]] > 1} {
+ set children($vp) [lsort -command [list vtokcmp $v] $children($vp)]
+ catch {unset ordertok}
+ }
+ fix_reversal $p $a $v
+ incr commitidx($v)
+ if {$v == $curview} {
+ set numcommits $commitidx($v)
+ setcanvscroll
+ if {[info exists targetid]} {
+ if {![comes_before $targetid $p]} {
+ incr targetrow
+ }
+ }
+ }
+}
+
+proc insertfakerow {id p} {
global varcid varccommits parents children cmitlisted
- global commitidx varctok vtokmod
+ global commitidx varctok vtokmod targetid targetrow curview numcommits
+ set v $curview
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"
+ puts "oops: insertfakerow can't find [shortids $p] on arc $a"
return
}
set children($v,$id) {}
set varcid($v,$id) $a
lappend children($v,$p) $id
set cmitlisted($v,$id) 1
- incr commitidx($v)
+ set numcommits [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
+ modify_arc $v $a $i
+ if {[info exists targetid]} {
+ if {![comes_before $targetid $p]} {
+ incr targetrow
+ }
}
+ setcanvscroll
drawvisible
}
-proc removerow {id v} {
+proc removefakerow {id} {
global varcid varccommits parents children commitidx
- global varctok vtokmod
+ global varctok vtokmod cmitlisted currentid selectedline
+ global targetid curview numcommits
+ set v $curview
if {[llength $parents($v,$id)] != 1} {
- puts "oops: removerow [shortids $id] has [llength $parents($v,$id)] parents"
+ puts "oops: removefakerow [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"
+ puts "oops: removefakerow can't find [shortids $id] on arc $a"
return
}
unset varcid($v,$id)
unset parents($v,$id)
unset children($v,$id)
unset cmitlisted($v,$id)
- incr commitidx($v) -1
+ set numcommits [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]
}
- set tok [lindex $varctok($v) $a]
- if {[string compare [lindex $varctok($v) $a] $vtokmod($v)] < 0} {
- modify_arc $v $a
+ modify_arc $v $a $i
+ if {[info exist currentid] && $id eq $currentid} {
+ unset currentid
+ set selectedline {}
+ }
+ if {[info exists targetid] && $targetid eq $id} {
+ set targetid $p
}
+ setcanvscroll
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
[lindex $varctok($v) $varcid($v,$b)]]
}
-proc modify_arc {v a} {
- global varctok vtokmod varcmod varcrow vupptr curview
+# This assumes that if lim is not given, the caller has checked that
+# arc a's token is less than $vtokmod($v)
+proc modify_arc {v a {lim {}}} {
+ global varctok vtokmod varcmod varcrow vupptr curview vrowmod varccommits
+ if {$lim ne {}} {
+ set c [string compare [lindex $varctok($v) $a] $vtokmod($v)]
+ if {$c > 0} return
+ if {$c == 0} {
+ set r [lindex $varcrow($v) $a]
+ if {$r ne {} && $vrowmod($v) <= $r + $lim} return
+ }
+ }
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 {}
}
- undolayout [lindex $varcrow($v) $a]
+ 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 varcrow commitidx currentid selectedline
- global varcid vseeds vrownum varcorder varcix varccommits
+ global vtokmod varcmod vrowmod varcrow commitidx currentid selectedline
+ global varcid vrownum varcorder varcix varccommits
global vupptr vdownptr vleftptr varctok
- global uat displayorder parentlist curview cached_commitrow
+ global displayorder parentlist curview cached_commitrow
- set t1 [clock clicks -milliseconds]
+ if {$vrowmod($v) == $commitidx($v)} return
+ 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}
+ }
set narctot [expr {[llength $varctok($v)] - 1}]
set a $varcmod($v)
while {$a != 0 && [lindex $varcix($v) $a] eq {}} {
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 {[llength $displayorder] > $row} {
- set displayorder [lrange $displayorder 0 [expr {$row - 1}]]
- set parentlist [lrange $parentlist 0 [expr {$row - 1}]]
- }
- if {$v == $curview} {
- catch {unset cached_commitrow}
- }
while {1} {
set p $a
incr row [llength $varccommits($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]
}
- set vtokmod($v) [lindex $varctok($v) $p]
- set varcmod($v) $p
- set t2 [clock clicks -milliseconds]
- incr uat [expr {$t2-$t1}]
}
# Test whether view $v contains commit $id
global varcid varccommits varcrow curview cached_commitrow
global varctok vtokmod
- if {[info exists cached_commitrow($id)]} {
- return $cached_commitrow($id)
- }
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} {
+ 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 $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
# 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 varcmod varcrow
+ global varccommits varcorder parents vrowmod varcrow
global d_valid_start d_valid_end
- set la $varcmod($curview)
- set lrow [lindex $varcrow($curview) $la]
- if {$la == 0 || $lrow eq {} || \
- $end < $lrow + [llength $varccommits($curview,$la)]} {
+ if {$end > $vrowmod($curview)} {
update_arcrows $curview
}
set ai [bsearch $vrownum($curview) $start]
lappend displayorder $id
lappend parentlist $parents($curview,$id)
}
- } elseif {[lindex $displayorder $r] eq {}} {
+ } elseif {[lindex $displayorder [expr {$r + $al - 1}]] eq {}} {
set i $r
foreach id $varccommits($curview,$a) {
lset displayorder $i $id
set b [newvarc $v $p]
}
set varcid($v,$p) $b
- lappend varccommits($v,$b) $p
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) {
}
}
-proc getcommitlines {fd inst view} {
- global cmitlisted commitinterest leftover getdbg
- global commitidx commitdata
+# Use $rwid as a substitute for $id, i.e. reparent $id's children to $rwid
+# Assumes we already have an arc for $rwid.
+proc rewrite_commit {v id rwid} {
+ global children parents varcid varctok vtokmod varccommits
+
+ foreach ch $children($v,$id) {
+ # make $rwid be $ch's parent in place of $id
+ set i [lsearch -exact $parents($v,$ch) $id]
+ if {$i < 0} {
+ puts "oops rewrite_commit didn't find $id in parent list for $ch"
+ }
+ set parents($v,$ch) [lreplace $parents($v,$ch) $i $i $rwid]
+ # add $ch to $rwid's children and sort the list if necessary
+ if {[llength [lappend children($v,$rwid) $ch]] > 1} {
+ set children($v,$rwid) [lsort -command [list vtokcmp $v] \
+ $children($v,$rwid)]
+ }
+ # fix the graph after joining $id to $rwid
+ set a $varcid($v,$ch)
+ fix_reversal $rwid $a $v
+ # parentlist is wrong for the last element of arc $a
+ # even if displayorder is right, hence the 3rd arg here
+ modify_arc $v $a [expr {[llength $varccommits($v,$a)] - 1}]
+ }
+}
+
+proc getcommitlines {fd inst view updating} {
+ global cmitlisted commitinterest leftover
+ global commitidx commitdata vdatemode
global parents children curview hlview
- global vnextroot idpending ordertok
- global varccommits varcid varctok vtokmod
+ global idpending ordertok
+ global varccommits varcid varctok vtokmod vfilelimit
set stuff [read $fd 500000]
# git log doesn't terminate the last commit with a null...
if {![eof $fd]} {
return 1
}
- global commfd viewcomplete viewactive viewname progresscoords
+ global commfd viewcomplete viewactive viewname
global viewinstances
unset commfd($inst)
set i [lsearch -exact $viewinstances($view) $inst]
}
if {[string range $err 0 4] == "usage"} {
set err "Gitk: error reading commits$fv:\
- bad arguments to git rev-list."
+ bad arguments to git log."
if {$viewname($view) eq "Command line"} {
append err \
- " (Note: arguments to gitk are passed to git rev-list\
+ " (Note: arguments to gitk are passed to git log\
to allow selection of commits to be displayed.)"
}
} else {
# appeared in the list
closevarcs $view
notbusy $view
- set progresscoords {0 0}
- adjustprogress
}
if {$view == $curview} {
- run chewcommits $view
+ run chewcommits
}
return 0
}
set listed 1
if {$j >= 0 && [string match "commit *" $cmit]} {
set ids [string range $cmit 7 [expr {$j - 1}]]
- if {[string match {[-<>]*} $ids]} {
+ if {[string match {[-^<>]*} $ids]} {
switch -- [string index $ids 0] {
"-" {set listed 0}
- "<" {set listed 2}
- ">" {set listed 3}
+ "^" {set listed 2}
+ "<" {set listed 3}
+ ">" {set listed 4}
}
set ids [string range $ids 1 end]
}
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]
set vid $view,$id
- if {!$listed && [info exists parents($vid)]} continue
+
+ if {!$listed && $updating && ![info exists varcid($vid)] &&
+ $vfilelimit($view) ne {}} {
+ # git log doesn't rewrite parents for unlisted commits
+ # when doing path limiting, so work around that here
+ # by working out the rewritten parent with git rev-list
+ # and if we already know about it, using the rewritten
+ # parent as a substitute parent for $id's children.
+ if {![catch {
+ set rwid [exec git rev-list --first-parent --max-count=1 \
+ $id -- $vfilelimit($view)]
+ }]} {
+ if {$rwid ne {} && [info exists varcid($view,$rwid)]} {
+ # use $rwid in place of $id
+ rewrite_commit $view $id $rwid
+ continue
+ }
+ }
+ }
+
+ set a 0
+ if {[info exists varcid($vid)]} {
+ if {$cmitlisted($vid) || !$listed} continue
+ set a $varcid($vid)
+ }
if {$listed} {
set olds [lrange $ids 1 end]
} else {
set commitdata($id) [string range $cmit [expr {$j + 1}] end]
set cmitlisted($vid) $listed
set parents($vid) $olds
- set a 0
if {![info exists children($vid)]} {
set children($vid) {}
- } else {
- if {[llength $children($vid)] == 1} {
- set k [lindex $children($vid) 0]
- if {[llength $parents($view,$k)] == 1} {
- set a $varcid($view,$k)
- }
+ } elseif {$a == 0 && [llength $children($vid)] == 1} {
+ set k [lindex $children($vid) 0]
+ if {[llength $parents($view,$k)] == 1 &&
+ (!$vdatemode($view) ||
+ $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
- lappend varccommits($view,$a) $id
- set tok [lindex $varctok($view) $a]
+ if {[string compare [lindex $varctok($view) $a] $vtokmod($view)] < 0} {
+ modify_arc $view $a
+ }
+ if {![info exists varcid($vid)]} {
+ set varcid($vid) $a
+ lappend varccommits($view,$a) $id
+ incr commitidx($view)
+ }
+
set i 0
foreach p $olds {
if {$i == 0 || [lsearch -exact $olds $p] >= $i} {
$children($vp)]
catch {unset ordertok}
}
- }
- if {[info exists varcid($view,$p)]} {
- fix_reversal $p $a $view
+ if {[info exists varcid($view,$p)]} {
+ fix_reversal $p $a $view
+ }
}
incr i
}
- if {[string compare $tok $vtokmod($view)] < 0} {
- modify_arc $view $a
- }
- incr commitidx($view)
if {[info exists commitinterest($id)]} {
foreach script $commitinterest($id) {
lappend scripts [string map [list "%I" $id] $script]
set gotsome 1
}
if {$gotsome} {
- run chewcommits $view
+ global numcommits hlview
+
+ if {$view == $curview} {
+ set numcommits $commitidx($view)
+ run chewcommits
+ }
+ if {[info exists hlview] && $view == $hlview} {
+ # we never actually get here...
+ run vhighlightmore
+ }
foreach s $scripts {
eval $s
}
- if {$view == $curview} {
- # update progress bar
- global progressdirn progresscoords proglastnc
- set inc [expr {($commitidx($view) - $proglastnc) * 0.0002}]
- set proglastnc $commitidx($view)
- set l [lindex $progresscoords 0]
- set r [lindex $progresscoords 1]
- if {$progressdirn} {
- set r [expr {$r + $inc}]
- if {$r >= 1.0} {
- set r 1.0
- set progressdirn 0
- }
- if {$r > 0.2} {
- set l [expr {$r - 0.2}]
- }
- } else {
- set l [expr {$l - $inc}]
- if {$l <= 0.0} {
- set l 0.0
- set progressdirn 1
- }
- set r [expr {$l + 0.2}]
- }
- set progresscoords [list $l $r]
- adjustprogress
- }
}
return 2
}
-proc chewcommits {view} {
+proc chewcommits {} {
global curview hlview viewcomplete
global pending_select
- if {$view == $curview} {
- layoutmore
- if {$viewcomplete($view)} {
- global commitidx
- global numcommits startmsecs
- global mainheadid commitinfo nullid
+ layoutmore
+ if {$viewcomplete($curview)} {
+ global commitidx varctok
+ global numcommits startmsecs
+
+ if {[info exists pending_select]} {
+ update
+ reset_pending_select {}
- if {[info exists pending_select]} {
+ if {[commitinview $pending_select $curview]} {
+ selectline [rowofcommit $pending_select] 1
+ } else {
set row [first_real_row]
selectline $row 1
}
- if {$commitidx($curview) > 0} {
- #set ms [expr {[clock clicks -milliseconds] - $startmsecs}]
- #puts "overall $ms ms for $numcommits commits"
- #global uat
- #puts "${uat}ms in update_arcrows"
- } else {
- show_status "No commits selected"
- }
- notbusy layout
}
- }
- if {[info exists hlview] && $view == $hlview} {
- vhighlightmore
+ 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 [mc "No commits selected"]
+ }
+ notbusy layout
}
return 0
}
set headline [string trimright [string range $headline 0 $i]]
}
if {!$listed} {
- # git rev-list indents the comment by 4 spaces;
+ # git log indents the comment by 4 spaces;
# if we got this via git cat-file, add the indentation
set newcomment {}
foreach line [split $comment "\n"] {
} 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
proc readrefs {} {
global tagids idtags headids idheads tagobjid
global otherrefids idotherrefs mainhead mainheadid
+ global selecthead selectheadid
foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
catch {unset $v}
set mainhead {}
set mainheadid {}
catch {
+ set mainheadid [exec git rev-parse HEAD]
set thehead [exec git symbolic-ref HEAD]
if {[string match "refs/heads/*" $thehead]} {
set mainhead [string range $thehead 11 end]
- if {[info exists headids($mainhead)]} {
- set mainheadid $headids($mainhead)
- }
+ }
+ }
+ set selectheadid {}
+ if {$selecthead ne {}} {
+ catch {
+ set selectheadid [exec git rev-parse --verify $selecthead]
}
}
}
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 <Visibility> "grab $top; focus $top"
bind $top <Key-Return> "destroy $top"
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 <Visibility> "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
global diffcontextstring diffcontext
+ global ignorespace
global maincursor textcursor curtextcursor
global rowctxmenu fakerowmenu mergemax wrapcomment
global highlight_files gdttype
global bgcolor fgcolor bglist fglist diffcolors selectbgcolor
global headctxmenu progresscanv progressitem progresscoords statusw
global fprogitem fprogcoord lastprogupdate progupdatepending
- global rprogitem rprogcoord
+ global rprogitem rprogcoord rownumsel numcommits
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 "Reload" -command reloadcommits
- .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.
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
-state disabled -width 26
pack .tf.bar.rightbut -side left -fill y
+ label .tf.bar.rowlabel -text [mc "Row"]
+ set rownumsel {}
+ label .tf.bar.rownum -width 7 -font textfont -textvariable rownumsel \
+ -relief sunken -anchor e
+ label .tf.bar.rowlabel2 -text "/"
+ label .tf.bar.numcommits -width 7 -font textfont -textvariable numcommits \
+ -relief sunken -anchor e
+ pack .tf.bar.rowlabel .tf.bar.rownum .tf.bar.rowlabel2 .tf.bar.numcommits \
+ -side left
+ global selectedline
+ trace add variable selectedline write selectedline_change
+
# 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
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 1 1} -font uifont
- button .tf.lbar.fprev -text "prev" -command {dofind -1 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 {}
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
}
frame .bleft.top
frame .bleft.mid
+ frame .bleft.bottom
- 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" -font uifont \
+ radiobutton .bleft.mid.diff -text [mc "Diff"] \
-command changediffdisp -variable diffelide -value {0 0}
- radiobutton .bleft.mid.old -text "Old version" -font uifont \
+ radiobutton .bleft.mid.old -text [mc "Old version"] \
-command changediffdisp -variable diffelide -value {0 1}
- radiobutton .bleft.mid.new -text "New version" -font uifont \
+ 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 \
trace add variable diffcontextstring write diffcontextchange
lappend entries .bleft.mid.diffcontext
pack .bleft.mid.labeldiffcontext .bleft.mid.diffcontext -side left
- set ctext .bleft.ctext
+ checkbutton .bleft.mid.ignspace -text [mc "Ignore space change"] \
+ -command changeignorespace -variable ignorespace
+ pack .bleft.mid.ignspace -side left -padx 5
+ set ctext .bleft.bottom.ctext
text $ctext -background $bgcolor -foreground $fgcolor \
-state disabled -font textfont \
- -yscrollcommand scrolltext -wrap none
+ -yscrollcommand scrolltext -wrap none \
+ -xscrollcommand ".bleft.bottom.sbhorizontal set"
if {$have_tk85} {
$ctext conf -tabstyle wordprocessor
}
- scrollbar .bleft.sb -command "$ctext yview"
+ scrollbar .bleft.bottom.sb -command "$ctext yview"
+ scrollbar .bleft.bottom.sbhorizontal -command "$ctext xview" -orient h \
+ -width 10
pack .bleft.top -side top -fill x
pack .bleft.mid -side top -fill x
- pack .bleft.sb -side right -fill y
- pack $ctext -side left -fill both -expand 1
+ grid $ctext .bleft.bottom.sb -sticky nsew
+ grid .bleft.bottom.sbhorizontal -sticky ew
+ grid columnconfigure .bleft.bottom 0 -weight 1
+ grid rowconfigure .bleft.bottom 0 -weight 1
+ grid rowconfigure .bleft.bottom 1 -weight 0
+ pack .bleft.bottom -side top -fill both -expand 1
lappend bglist $ctext
lappend fglist $ctext
# 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
.pwbottom add .bright
.ctop add .pwbottom
- # restore window position if known
+ # restore window width & height if known
if {[info exists geometry(main)]} {
- wm geometry . "$geometry(main)"
+ if {[scan $geometry(main) "%dx%d" w h] >= 2} {
+ if {$w > [winfo screenwidth .]} {
+ set w [winfo screenwidth .]
+ }
+ if {$h > [winfo screenheight .]} {
+ set h [winfo screenheight .]
+ }
+ wm geometry . "${w}x$h"
+ }
}
if {[tk windowingsystem] eq {aqua}} {
bindkey k "selnextline 1"
bindkey j "goback"
bindkey l "goforw"
- bindkey b "$ctext yview scroll -1 pages"
+ bindkey b prevfile
bindkey d "$ctext yview scroll 18 units"
bindkey u "$ctext yview scroll -18 units"
bindkey / {dofind 1 1}
bind . <$M1B-r> dosearchback
bind . <$M1B-s> dosearch
bind . <$M1B-equal> {incrfont 1}
+ bind . <$M1B-plus> {incrfont 1}
bind . <$M1B-KP_Add> {incrfont 1}
bind . <$M1B-minus> {incrfont -1}
bind . <$M1B-KP_Subtract> {incrfont -1}
wm protocol . WM_DELETE_WINDOW doquit
+ bind . <Destroy> {stop_backends}
bind . <Button-1> "click %W"
bind $fstring <Key-Return> {dofind 1 1}
bind $sha1entry <Key-Return> gotocommit
bind $cflist <1> {sel_flist %W %x %y; break}
bind $cflist <B1-Motion> {sel_flist %W %x %y; break}
bind $cflist <ButtonRelease-1> {treeclick %W %x %y}
- bind $cflist <Button-3> {pop_flist_menu %W %X %Y %x %y}
+ global ctxbut
+ bind $cflist $ctxbut {pop_flist_menu %W %X %Y %x %y}
set maincursor [. cget -cursor]
set textcursor [$ctext cget -cursor]
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}
+ $flist_menu add command -label [mc "External diff"] \
+ -command {external_diff}
+ $flist_menu add command -label [mc "Blame parent commit"] \
+ -command {external_blame 1}
}
# Windows sends all mouse wheel events to the current focused window, not
}
}
+# Update row number label when selectedline changes
+proc selectedline_change {n1 n2 op} {
+ global selectedline rownumsel
+
+ if {$selectedline eq {}} {
+ set rownumsel {}
+ } else {
+ set rownumsel [expr {$selectedline + 1}]
+ }
+}
+
# mouse-2 makes all windows scan vertically, but only the one
# the cursor is in scans horizontally
proc canvscan {op w x y} {
proc scrollcanv {cscroll f0 f1} {
$cscroll set $f0 $f1
- drawfrac $f0 $f1
+ drawvisible
flushhighlights
}
global canv canv2 canv3 mainfont textfont uifont tabstop
global stuffsaved findmergefiles maxgraphpct
global maxwidth showneartags showlocalchanges
- global viewname viewfiles viewargs viewperm nextviewnum
+ global viewname viewfiles viewargs viewargscmd viewperm nextviewnum
global cmitmode wrapcomment datetimeformat limitdiffs
global colors bgcolor fgcolor diffcolors diffcontext selectbgcolor
+ global autoselect extdifftool
if {$stuffsaved} return
if {![winfo viewable .]} return
puts $f [list set maxwidth $maxwidth]
puts $f [list set cmitmode $cmitmode]
puts $f [list set wrapcomment $wrapcomment]
+ puts $f [list set autoselect $autoselect]
puts $f [list set showneartags $showneartags]
puts $f [list set showlocalchanges $showlocalchanges]
puts $f [list set datetimeformat $datetimeformat]
puts $f [list set diffcolors $diffcolors]
puts $f [list set diffcontext $diffcontext]
puts $f [list set selectbgcolor $selectbgcolor]
+ puts $f [list set extdifftool $extdifftool]
puts $f "set geometry(main) [wm geometry .]"
puts $f "set geometry(topwidth) [winfo width .tf]"
puts -nonewline $f "set permviews {"
for {set v 0} {$v < $nextviewnum} {incr v} {
if {$viewperm($v)} {
- puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v)]}"
+ puts $f "{[list $viewname($v) $viewfiles($v) $viewargs($v) $viewargscmd($v)]}"
}
}
puts $f "}"
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-2007 Paul Mackerras
+Copyright © 2005-2008 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 <Visibility> "focus $w.ok"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> "destroy $w"
}
proc keys {} {
- global uifont
set w .keys
if {[winfo exists $w]} {
raise $w
set M1T Ctrl
}
toplevel $w
- wm title $w "Gitk key bindings"
+ wm title $w [mc "Gitk key bindings"]
message $w.m -text "
-Gitk key bindings:
-
-<$M1T-Q> Quit
-<Home> Move to first commit
-<End> Move to last commit
-<Up>, p, i Move up one commit
-<Down>, n, k Move down one commit
-<Left>, z, j Go back in history list
-<Right>, x, l Go forward in history list
-<PageUp> Move up one page in commit list
-<PageDown> Move down one page in commit list
-<$M1T-Home> Scroll to top of commit list
-<$M1T-End> Scroll to bottom of commit list
-<$M1T-Up> Scroll commit list up one line
-<$M1T-Down> Scroll commit list down one line
-<$M1T-PageUp> Scroll commit list up one page
-<$M1T-PageDown> Scroll commit list down one page
-<Shift-Up> Find backwards (upwards, later commits)
-<Shift-Down> Find forwards (downwards, earlier commits)
-<Delete>, b Scroll diff view up one page
-<Backspace> Scroll diff view up one page
-<Space> Scroll diff view down one page
-u Scroll diff view up 18 lines
-d Scroll diff view down 18 lines
-<$M1T-F> Find
-<$M1T-G> Move to next find hit
-<Return> Move to next find hit
-/ Move to next find hit, or redo find
-? Move to previous find hit
-f Scroll diff view to next file
-<$M1T-S> Search for next hit in diff view
-<$M1T-R> Search for previous hit in diff view
-<$M1T-KP+> Increase font size
-<$M1T-plus> Increase font size
-<$M1T-KP-> Decrease font size
-<$M1T-minus> Decrease font size
-<F5> Update
+[mc "Gitk key bindings:"]
+
+[mc "<%s-Q> Quit" $M1T]
+[mc "<Home> Move to first commit"]
+[mc "<End> Move to last commit"]
+[mc "<Up>, p, i Move up one commit"]
+[mc "<Down>, n, k Move down one commit"]
+[mc "<Left>, z, j Go back in history list"]
+[mc "<Right>, x, l Go forward in history list"]
+[mc "<PageUp> Move up one page in commit list"]
+[mc "<PageDown> Move down one page in commit list"]
+[mc "<%s-Home> Scroll to top of commit list" $M1T]
+[mc "<%s-End> Scroll to bottom of commit list" $M1T]
+[mc "<%s-Up> Scroll commit list up one line" $M1T]
+[mc "<%s-Down> Scroll commit list down one line" $M1T]
+[mc "<%s-PageUp> Scroll commit list up one page" $M1T]
+[mc "<%s-PageDown> Scroll commit list down one page" $M1T]
+[mc "<Shift-Up> Find backwards (upwards, later commits)"]
+[mc "<Shift-Down> Find forwards (downwards, earlier commits)"]
+[mc "<Delete>, b Scroll diff view up one page"]
+[mc "<Backspace> Scroll diff view up one page"]
+[mc "<Space> Scroll diff view down one page"]
+[mc "u Scroll diff view up 18 lines"]
+[mc "d Scroll diff view down 18 lines"]
+[mc "<%s-F> Find" $M1T]
+[mc "<%s-G> Move to next find hit" $M1T]
+[mc "<Return> Move to next find hit"]
+[mc "/ Move to next find hit, or redo find"]
+[mc "? Move to previous find hit"]
+[mc "f Scroll diff view to next file"]
+[mc "<%s-S> Search for next hit in diff view" $M1T]
+[mc "<%s-R> Search for previous hit in diff view" $M1T]
+[mc "<%s-KP+> Increase font size" $M1T]
+[mc "<%s-plus> Increase font size" $M1T]
+[mc "<%s-KP-> Decrease font size" $M1T]
+[mc "<%s-minus> Decrease font size" $M1T]
+[mc "<F5> 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 <Visibility> "focus $w.ok"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> "destroy $w"
set e [lindex $treediffs($diffids) [expr {$l-2}]]
}
set flist_menu_file $e
+ set xdiffstate "normal"
+ if {$cmitmode eq "tree"} {
+ set xdiffstate "disabled"
+ }
+ # Disable "External diff" item in tree mode
+ $flist_menu entryconf 2 -state $xdiffstate
tk_popup $flist_menu $X $Y
}
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:"]
+}
+
+proc save_file_from_commit {filename output what} {
+ global nullfile
+
+ if {[catch {exec git show $filename -- > $output} err]} {
+ if {[string match "fatal: bad revision *" $err]} {
+ return $nullfile
+ }
+ error_popup "Error getting \"$filename\" from $what: $err"
+ return {}
+ }
+ return $output
+}
+
+proc external_diff_get_one_file {diffid filename diffdir} {
+ global nullid nullid2 nullfile
+ global gitdir
+
+ if {$diffid == $nullid} {
+ set difffile [file join [file dirname $gitdir] $filename]
+ if {[file exists $difffile]} {
+ return $difffile
+ }
+ return $nullfile
+ }
+ if {$diffid == $nullid2} {
+ set difffile [file join $diffdir "\[index\] [file tail $filename]"]
+ return [save_file_from_commit :$filename $difffile index]
+ }
+ set difffile [file join $diffdir "\[$diffid\] [file tail $filename]"]
+ return [save_file_from_commit $diffid:$filename $difffile \
+ "revision $diffid"]
+}
+
+proc external_diff {} {
+ global gitktmpdir nullid nullid2
+ global flist_menu_file
+ global diffids
+ global diffnum
+ global gitdir extdifftool
+
+ if {[llength $diffids] == 1} {
+ # no reference commit given
+ set diffidto [lindex $diffids 0]
+ if {$diffidto eq $nullid} {
+ # diffing working copy with index
+ set diffidfrom $nullid2
+ } elseif {$diffidto eq $nullid2} {
+ # diffing index with HEAD
+ set diffidfrom "HEAD"
+ } else {
+ # use first parent commit
+ global parentlist selectedline
+ set diffidfrom [lindex $parentlist $selectedline 0]
+ }
+ } else {
+ set diffidfrom [lindex $diffids 0]
+ set diffidto [lindex $diffids 1]
+ }
+
+ # make sure that several diffs wont collide
+ if {![info exists gitktmpdir]} {
+ set gitktmpdir [file join [file dirname $gitdir] \
+ [format ".gitk-tmp.%s" [pid]]]
+ if {[catch {file mkdir $gitktmpdir} err]} {
+ error_popup "Error creating temporary directory $gitktmpdir: $err"
+ unset gitktmpdir
+ return
+ }
+ set diffnum 0
+ }
+ incr diffnum
+ set diffdir [file join $gitktmpdir $diffnum]
+ if {[catch {file mkdir $diffdir} err]} {
+ error_popup "Error creating temporary directory $diffdir: $err"
+ return
+ }
+
+ # gather files to diff
+ set difffromfile [external_diff_get_one_file $diffidfrom $flist_menu_file $diffdir]
+ set difftofile [external_diff_get_one_file $diffidto $flist_menu_file $diffdir]
+
+ if {$difffromfile ne {} && $difftofile ne {}} {
+ set cmd [concat | [shellsplit $extdifftool] \
+ [list $difffromfile $difftofile]]
+ if {[catch {set fl [open $cmd r]} err]} {
+ file delete -force $diffdir
+ error_popup [mc "$extdifftool: command failed: $err"]
+ } else {
+ fconfigure $fl -blocking 0
+ filerun $fl [list delete_at_eof $fl $diffdir]
+ }
+ }
+}
+
+proc external_blame {parent_idx} {
+ global flist_menu_file
+ global nullid nullid2
+ global parentlist selectedline currentid
+
+ if {$parent_idx > 0} {
+ set base_commit [lindex $parentlist $selectedline [expr {$parent_idx-1}]]
+ } else {
+ set base_commit $currentid
+ }
+
+ if {$base_commit eq {} || $base_commit eq $nullid || $base_commit eq $nullid2} {
+ error_popup [mc "No such commit"]
+ return
+ }
+
+ if {[catch {exec git gui blame $base_commit $flist_menu_file &} err]} {
+ error_popup [mc "git gui blame: command failed: $err"]
+ }
+}
+
+# delete $dir when we see eof on $f (presumably because the child has exited)
+proc delete_at_eof {f dir} {
+ while {[gets $f line] >= 0} {}
+ if {[eof $f]} {
+ if {[catch {close $f} err]} {
+ error_popup "External diff viewer failed: $err"
+ }
+ file delete -force $dir
+ return 0
+ }
+ return 1
}
# Functions for adding and removing shell-type quoting
# Code to implement multiple views
proc newview {ishighlight} {
- global nextviewnum newviewname newviewperm uifont newishighlight
- global newviewargs revtreeargs
+ global nextviewnum newviewname newviewperm newishighlight
+ global newviewargs revtreeargs viewargscmd newviewargscmd curview
set newishighlight $ishighlight
set top .gitkview
raise $top
return
}
- set newviewname($nextviewnum) "View $nextviewnum"
+ set newviewname($nextviewnum) "[mc "View"] $nextviewnum"
set newviewperm($nextviewnum) 0
set newviewargs($nextviewnum) [shellarglist $revtreeargs]
- vieweditor $top $nextviewnum "Gitk view definition"
+ set newviewargscmd($nextviewnum) $viewargscmd($curview)
+ vieweditor $top $nextviewnum [mc "Gitk view definition"]
}
proc editview {} {
global curview
global viewname viewperm newviewname newviewperm
- global viewargs newviewargs
+ global viewargs newviewargs viewargscmd newviewargscmd
set top .gitkvedit-$curview
if {[winfo exists $top]} {
set newviewname($curview) $viewname($curview)
set newviewperm($curview) $viewperm($curview)
set newviewargs($curview) [shellarglist $viewargs($curview)]
+ set newviewargscmd($curview) $viewargscmd($curview)
vieweditor $top $curview "Gitk: edit view $viewname($curview)"
}
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 log):"]
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.ac -aspect 1000 \
+ -text [mc "Command to generate more commits to include:"]
+ grid $top.ac - -sticky w -pady 5
+ entry $top.argscmd -width 50 -textvariable newviewargscmd($n) \
+ -background white
+ grid $top.argscmd - -sticky ew -padx 5
+
+ 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
}
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
proc newviewok {top n} {
global nextviewnum newviewperm newviewname newishighlight
global viewname viewfiles viewperm selectedview curview
- global viewargs newviewargs viewhlmenu
+ global viewargs newviewargs viewargscmd newviewargscmd viewhlmenu
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
set viewperm($n) $newviewperm($n)
set viewfiles($n) $files
set viewargs($n) $newargs
+ set viewargscmd($n) $newviewargscmd($n)
addviewmenu $n
if {!$newishighlight} {
run showview $n
# doviewmenu $viewhlmenu 1 [list addvhighlight $n] \
# entryconf [list -label $viewname($n) -value $viewname($n)]
}
- if {$files ne $viewfiles($n) || $newargs ne $viewargs($n)} {
+ if {$files ne $viewfiles($n) || $newargs ne $viewargs($n) || \
+ $newviewargscmd($n) ne $viewargscmd($n)} {
set viewfiles($n) $files
set viewargs($n) $newargs
+ set viewargscmd($n) $newviewargscmd($n)
if {$curview == $n} {
run reloadcommits
}
if {$curview == 0} return
if {[info exists hlview] && $hlview == $curview} {
- set selectedhlview None
+ set selectedhlview [mc "None"]
unset hlview
}
allviewmenus $curview delete
}
proc showview {n} {
- global curview viewfiles cached_commitrow ordertok
+ global curview cached_commitrow ordertok
global displayorder parentlist rowidlist rowisopt rowfinal
global colormap rowtextx nextcolor canvxmax
global numcommits viewcomplete
global selectedline currentid canv canvy0
global treediffs
- global pending_select
+ global pending_select mainheadid
global commitidx
- global selectedview selectfirst
+ global selectedview
global hlview selectedhlview commitinterest
if {$n == $curview} return
set ytop [expr {[lindex $span 0] * $ymax}]
set ybot [expr {[lindex $span 1] * $ymax}]
set yscreen [expr {($ybot - $ytop) / 2}]
- if {[info exists selectedline]} {
+ if {$selectedline ne {}} {
set selid $currentid
set y [yc $selectedline]
if {$ytop < $y && $y < $ybot} {
clear_display
if {[info exists hlview] && $hlview == $n} {
unset hlview
- set selectedhlview None
+ set selectedhlview [mc "None"]
}
catch {unset commitinterest}
catch {unset cached_commitrow}
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 viewcomplete($n)]} {
- if {$selid ne {}} {
- set pending_select $selid
- }
- getcommits
+ getcommits $selid
return
}
setcanvscroll
set yf 0
set row {}
- set selectfirst 0
if {$selid ne {} && [commitinview $selid $n]} {
set row [rowofcommit $selid]
# try to get the selected row in the same position on the screen
drawvisible
if {$row ne {}} {
selectline $row 0
- } elseif {$selid ne {}} {
- set pending_select $selid
+ } elseif {!$viewcomplete($n)} {
+ reset_pending_select $selid
} else {
- set row [first_real_row]
- if {$row < $numcommits} {
- selectline $row 0
+ reset_pending_select {}
+
+ if {[commitinview $pending_select $curview]} {
+ selectline [rowofcommit $pending_select] 1
} else {
- set selectfirst 1
+ set row [first_real_row]
+ if {$row < $numcommits} {
+ selectline $row 0
+ }
}
}
if {!$viewcomplete($n)} {
if {$numcommits == 0} {
- show_status "Reading commits..."
- } else {
- run chewcommits $n
+ show_status [mc "Reading commits..."]
}
} 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
}
lappend boldrows $row
$canv itemconf $linehtag($row) -font $font
- if {[info exists selectedline] && $row == $selectedline} {
+ if {$row == $selectedline} {
$canv delete secsel
set t [eval $canv create rect [$canv bbox $linehtag($row)] \
-outline {{}} -tags secsel \
lappend boldnamerows $row
$canv2 itemconf $linentag($row) -font $font
- if {[info exists selectedline] && $row == $selectedline} {
+ if {$row == $selectedline} {
$canv2 delete secsel
set t [eval $canv2 create rect [$canv2 bbox $linentag($row)] \
-outline {{}} -tags secsel \
set stillbold {}
foreach row $boldrows {
- if {![ishighlighted $row]} {
+ if {![ishighlighted [commitonrow $row]]} {
bolden $row mainfont
} else {
lappend stillbold $row
}
proc addvhighlight {n} {
- global hlview viewcomplete curview vhl_done vhighlights commitidx
+ global hlview viewcomplete curview vhl_done commitidx
if {[info exists hlview]} {
delvhighlight
if {![highlighted $row]} {
bolden $row mainfontbold
}
- set vhighlights($row) 1
+ set vhighlights($id) 1
}
}
}
set vhl_done $max
+ return 0
}
proc askvhighlight {row id} {
global hlview vhighlights iddrawn
if {[commitinview $id $hlview]} {
- if {[info exists iddrawn($id)] && ![ishighlighted $row]} {
+ 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
}
}
stopfinding
if {$findstring ne {}} {
- if {$gdttype eq "containing:"} {
+ if {$gdttype eq [mc "containing:"]} {
if {$highlight_files ne {}} {
set highlight_files {}
hfiles_change
global gdttype findstring highlight_files
stopfinding
- if {$gdttype eq "containing:"} {
+ if {$gdttype eq [mc "containing:"]} {
findcom_change
} else {
if {$highlight_files ne $findstring} {
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 {"*" "\\*" "?" "\\?" "\[" "\\\[" "\\" "\\\\"} \
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
global filehighlight fhighlights fhl_list
lappend fhl_list $id
- set fhighlights($row) -1
+ set fhighlights($id) -1
puts $filehighlight $id
}
if {$i < 0} continue
for {set j 0} {$j < $i} {incr j} {
set id [lindex $fhl_list $j]
- if {[commitinview $id $curview]} {
- set fhighlights([rowofcommit $id]) 0
- }
+ set fhighlights($id) 0
}
set fhl_list [lrange $fhl_list [expr {$i+1}] end]
if {$line eq {}} continue
if {![commitinview $line $curview]} continue
set row [rowofcommit $line]
- if {[info exists iddrawn($line)] && ![ishighlighted $row]} {
+ if {[info exists iddrawn($line)] && ![ishighlighted $line]} {
bolden $row mainfontbold
}
- set fhighlights($row) 1
+ set fhighlights($line) 1
}
if {[eof $filehighlight]} {
# strange...
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]
}
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
}
}
}
if {$isbold && [info exists iddrawn($id)]} {
- if {![ishighlighted $row]} {
+ if {![ishighlighted $id]} {
bolden $row mainfontbold
if {$isbold > 1} {
bolden_name $row mainfontbold
markrowmatches $row $id
}
}
- set nhighlights($row) $isbold
+ set nhighlights($id) $isbold
}
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 \
global highlight_related
rhighlight_none
- if {$highlight_related ne "None"} {
+ if {$highlight_related ne [mc "None"]} {
run drawvisible
}
}
# 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
}
global descendent highlight_related iddrawn rhighlights
global selectedline ancestor
- if {![info exists selectedline]} return
+ if {$selectedline eq {}} return
set isbold 0
- if {$highlight_related eq "Descendent" ||
- $highlight_related eq "Not descendent"} {
+ if {$highlight_related eq [mc "Descendant"] ||
+ $highlight_related eq [mc "Not descendant"]} {
if {![info exists descendent($id)]} {
is_descendent $id
}
- if {$descendent($id) == ($highlight_related eq "Descendent")} {
+ if {$descendent($id) == ($highlight_related eq [mc "Descendant"])} {
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
set tok $ordertok($p)
break
}
- if {[llength $children($curview,$p)] == 0} {
+ set id [first_real_child $curview,$p]
+ if {$id eq {}} {
# it's a root
- set tok [lindex $varctok($curview) $a]
- break
- }
- set id [lindex $children($curview,$p) 0]
- if {$id eq $nullid || $id eq $nullid2} {
- # XXX treat it as a root
- set tok [lindex $varctok($curview) $a]
+ set tok [lindex $varctok($curview) $varcid($curview,$p)]
break
}
if {[llength $parents($curview,$id)] == 1} {
# values increase from left to right
proc idcol {idlist id {i 0}} {
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]
global numcommits canvxmax canv
global nextcolor
global colormap rowtextx
- global selectfirst
set numcommits 0
set displayorder {}
set canvxmax [$canv cget -width]
catch {unset colormap}
catch {unset rowtextx}
- set selectfirst 1
+ setcanvscroll
}
proc setcanvscroll {} {
global canv canv2 canv3 numcommits linespc canvxmax canvy0
+ global lastscrollset lastscrollrows
set ymax [expr {$canvy0 + ($numcommits - 0.5) * $linespc + 2}]
$canv conf -scrollregion [list 0 0 $canvxmax $ymax]
$canv2 conf -scrollregion [list 0 0 0 $ymax]
$canv3 conf -scrollregion [list 0 0 0 $ymax]
+ set lastscrollset [clock clicks -milliseconds]
+ set lastscrollrows $numcommits
}
proc visiblerows {} {
proc layoutmore {} {
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} {
- allcanvs delete all
- }
- set r0 $numcommits
- set prev $numcommits
- set numcommits $canshow
- set t [clock clicks -milliseconds]
- if {$prev < 100 || $viewcomplete($curview) || $t - $lastscrollset > 500} {
- set lastscrollset $t
+ global numcommits pending_select curview
+ global lastscrollset lastscrollrows commitinterest
+
+ if {$lastscrollrows < 100 || $viewcomplete($curview) ||
+ [clock clicks -milliseconds] - $lastscrollset > 500} {
setcanvscroll
}
- set rows [visiblerows]
- set r1 [lindex $rows 1]
- if {$r1 >= $canshow} {
- set r1 [expr {$canshow - 1}]
- }
- if {$r0 <= $r1} {
- drawcommits $r0 $r1
- }
if {[info exists pending_select] &&
[commitinview $pending_select $curview]} {
+ update
selectline [rowofcommit $pending_select] 1
}
- if {$selectfirst} {
- if {[info exists selectedline] || [info exists pending_select]} {
- set selectfirst 0
- } else {
- set l [first_real_row]
- selectline $l 1
- set selectfirst 0
- }
- }
+ drawvisible
}
proc doshowlocalchanges {} {
global curview mainheadid
+ if {$mainheadid eq {}} return
if {[commitinview $mainheadid $curview]} {
dodiffindex
} else {
global nullid nullid2 lserial curview
if {[commitinview $nullid $curview]} {
- removerow $nullid $curview
+ removefakerow $nullid
}
if {[commitinview $nullid2 $curview]} {
- removerow $nullid2 $curview
+ removefakerow $nullid2
}
incr lserial
}
# spawn off a process to do git diff-index --cached HEAD
proc dodiffindex {} {
global lserial showlocalchanges
+ global isworktree
- if {!$showlocalchanges} return
+ if {!$showlocalchanges || !$isworktree} return
incr lserial
set fd [open "|git diff-index --cached HEAD" r]
fconfigure $fd -blocking 0
- filerun $fd [list readdiffindex $fd $lserial]
+ set i [reg_instance $fd]
+ filerun $fd [list readdiffindex $fd $lserial $i]
}
-proc readdiffindex {fd serial} {
- global mainheadid nullid2 curview commitinfo commitdata lserial
+proc readdiffindex {fd serial inst} {
+ global mainheadid nullid nullid2 curview commitinfo commitdata lserial
set isdiff 1
if {[gets $fd line] < 0} {
set isdiff 0
}
# we only need to see one line and we don't really care what it says...
- close $fd
+ stop_instance $inst
- # 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 && ![commitinview $nullid2 $curview]} {
+ # 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
+ set i [reg_instance $fd]
+ filerun $fd [list readdifffiles $fd $serial $i]
+
+ if {$isdiff && ![commitinview $nullid2 $curview]} {
# add the line for the changes in the index to the graph
- 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 $nullid2 $mainheadid $curview
+ if {[commitinview $nullid $curview]} {
+ removefakerow $nullid
+ }
+ insertfakerow $nullid2 $mainheadid
+ } elseif {!$isdiff && [commitinview $nullid2 $curview]} {
+ removefakerow $nullid2
}
return 0
}
-proc readdifffiles {fd serial} {
+proc readdifffiles {fd serial inst} {
global mainheadid nullid nullid2 curview
global commitinfo commitdata lserial
set isdiff 0
}
# we only need to see one line and we don't really care what it says...
- close $fd
+ stop_instance $inst
+
+ if {$serial != $lserial} {
+ return 0
+ }
- if {$isdiff && $serial == $lserial && ![commitinview $nullid $curview]} {
+ if {$isdiff && ![commitinview $nullid $curview]} {
# add the line for the local diff to the graph
- 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"
if {[commitinview $nullid2 $curview]} {
} else {
set p $mainheadid
}
- insertrow $nullid $p $curview
+ insertfakerow $nullid $p
+ } elseif {!$isdiff && [commitinview $nullid $curview]} {
+ removefakerow $nullid
}
return 0
}
global cmitlisted commitinfo rowidlist parentlist
global rowtextx idpos idtags idheads idotherrefs
global linehtag linentag linedtag selectedline
- global canvxmax boldrows boldnamerows fgcolor nullid nullid2
+ global canvxmax boldrows boldnamerows fgcolor
+ global mainheadid nullid nullid2 circleitem circlecolors ctxbut
- # listed is 0 for boundary, 1 for normal, 2 for left, 3 for right
+ # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right
set listed $cmitlisted($curview,$id)
if {$id eq $nullid} {
set ofill red
} elseif {$id eq $nullid2} {
set ofill green
+ } elseif {$id eq $mainheadid} {
+ set ofill yellow
} else {
- set ofill [expr {$listed != 0? "blue": "white"}]
+ set ofill [lindex $circlecolors $listed]
}
set x [xc $row $col]
set y [yc $row]
set orad [expr {$linespc / 3}]
- if {$listed <= 1} {
+ if {$listed <= 2} {
set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \
[expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \
-fill $ofill -outline $fgcolor -width 1 -tags circle]
- } elseif {$listed == 2} {
+ } elseif {$listed == 3} {
# triangle pointing left for left-side commits
set t [$canv create polygon \
[expr {$x - $orad}] $y \
[expr {$x - $orad}] [expr {$y + $orad - 1}] \
-fill $ofill -outline $fgcolor -width 1 -tags circle]
}
+ set circleitem($row) $t
$canv raise $t
$canv bind $t <1> {selcanvline {} %x %y}
set rmx [llength [lindex $rowidlist $row]]
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
}
set linehtag($row) [$canv create text $xt $y -anchor w -fill $fgcolor \
-text $headline -font $font -tags text]
- $canv bind $linehtag($row) <Button-3> "rowmenu %X %Y $id"
+ $canv bind $linehtag($row) $ctxbut "rowmenu %X %Y $id"
set linentag($row) [$canv2 create text 3 $y -anchor w -fill $fgcolor \
-text $name -font $nfont -tags text]
set linedtag($row) [$canv3 create text 3 $y -anchor w -fill $fgcolor \
-text $date -font mainfont -tags text]
- if {[info exists selectedline] && $selectedline == $row} {
+ if {$selectedline == $row} {
make_secsel $row
}
set xr [expr {$xt + [font measure $font $headline]}]
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)]} {
}
}
-proc drawfrac {f0 f1} {
- global canv linespc
+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
+ if {$ymax eq {} || $ymax == 0 || $numcommits == 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 {$selectedline ne {} &&
+ $row <= $selectedline && $selectedline <= $endrow} {
+ set targetrow $selectedline
+ } elseif {[info exists targetid]} {
+ set targetrow [expr {int(($row + $endrow) / 2)}]
+ }
+ if {[info exists targetrow]} {
+ 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
+ global linehtag linentag linedtag boldrows boldnamerows
allcanvs delete all
catch {unset iddrawn}
catch {unset linesegs}
+ catch {unset linehtag}
+ catch {unset linentag}
+ catch {unset linedtag}
+ set boldrows {}
+ set boldnamerows {}
catch {unset vhighlights}
catch {unset fhighlights}
catch {unset nhighlights}
proc drawtags {id x xt y1} {
global idtags idheads idotherrefs mainhead
global linespc lthickness
- global canv rowtextx curview fgcolor bgcolor
+ global canv rowtextx curview fgcolor bgcolor ctxbut
set marks {}
set ntags 0
if {$ntags >= 0} {
$canv bind $t <1> [list showtag $tag 1]
} elseif {$nheads >= 0} {
- $canv bind $t <Button-3> [list headmenu %X %Y $id $tag]
+ $canv bind $t $ctxbut [list headmenu %X %Y $id $tag]
}
}
return $xt
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]
}
}
focus .
if {$findstring eq {} || $numcommits == 0} return
- if {![info exists selectedline]} {
+ if {$selectedline eq {}} {
set findstartline [lindex [visiblerows] [expr {$dirn < 0}]]
} else {
set findstartline $selectedline
}
set findcurline $findstartline
- nowbusy finding "Searching"
- 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
}
global commitdata commitinfo numcommits findpattern findloc
global findstartline findcurline findallowwrap
global find_dirn gdttype fhighlights fprogcoord
- global curview varcorder vrownum varccommits
+ global curview varcorder vrownum varccommits vrowmod
if {![info exists find_dirn]} {
return 0
}
- set fldtypes {Headline Author Date Committer CDate Comments}
+ 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} {
set n 500
set moretodo 1
}
+ if {$l + ($find_dirn > 0? $n: 1) > $vrowmod($curview)} {
+ update_arcrows $curview
+ }
set found 0
set domore 1
set ai [bsearch $vrownum($curview) $l]
set arow [lindex $vrownum($curview) $ai]
set ids [lindex $varccommits($curview,$a)]
set arowend [expr {$arow + [llength $ids]}]
- if {$gdttype eq "containing:"} {
+ 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 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
set arowend [expr {$arow + [llength $ids]}]
}
set id [lindex $ids [expr {$l - $arow}]]
- if {![info exists fhighlights($l)]} {
+ 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 - $find_dirn}]
}
- } elseif {$fhighlights($l)} {
- set found $domore
- break
}
}
}
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]
[expr {$x0+$xlen+2}] $y1 \
-outline {} -tags [list match$l matches] -fill yellow]
$canv lower $t
- if {[info exists selectedline] && $row == $selectedline} {
+ if {$row == $selectedline} {
$canv raise $t secsel
}
}
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
proc dispneartags {delay} {
global selectedline currentid showneartags tagphase
- if {![info exists selectedline] || !$showneartags} return
+ if {$selectedline eq {} || !$showneartags} return
after cancel dispnexttag
if {$delay} {
after 200 dispnexttag
proc dispnexttag {} {
global selectedline currentid showneartags tagphase ctext
- if {![info exists selectedline] || !$showneartags} return
+ if {$selectedline eq {} || !$showneartags} return
switch -- $tagphase {
0 {
set dtags [desctags $currentid]
global commentend idtags linknum
global mergemax numcommits pending_select
global cmitmode showneartags allcommits
+ global targetrow targetid lastscrollrows
+ global autoselect
catch {unset pending_select}
$canv delete hover
unsel_reflist
stopfinding
if {$l < 0 || $l >= $numcommits} return
+ set id [commitonrow $l]
+ set targetid $id
+ set targetrow $l
+ set selectedline $l
+ set currentid $id
+ if {$lastscrollrows < $numcommits} {
+ setcanvscroll
+ }
+
set y [expr {$canvy0 + $l * $linespc}]
set ymax [lindex [$canv cget -scrollregion] 3]
set ytop [expr {$y - $linespc - 1}]
make_secsel $l
if {$isnew} {
- addtohistory [list selectline $l 0]
+ addtohistory [list selbyid $id]
}
- set selectedline $l
-
- set id [commitonrow $l]
- set currentid $id
$sha1entry delete 0 end
$sha1entry insert 0 $id
- $sha1entry selection from 0
- $sha1entry selection to end
+ if {$autoselect} {
+ $sha1entry selection from 0
+ $sha1entry selection to end
+ }
rhighlight_sel $id
$ctext conf -state normal
clear_ctext
set linknum 0
+ if {![info exists commitinfo($id)]} {
+ getcommit $id
+ }
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"
}
} 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
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"
$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} {
proc selnextline {dir} {
global selectedline
focus .
- if {![info exists selectedline]} return
+ if {$selectedline eq {}} return
set l [expr {$selectedline + $dir}]
unmarkmatches
selectline $l 1
}
allcanvs yview scroll [expr {$dir * $lpp}] units
drawvisible
- if {![info exists selectedline]} return
+ if {$selectedline eq {}} return
set l [expr {$selectedline + $dir * $lpp}]
if {$l < 0} {
set l 0
proc unselectline {} {
global selectedline currentid
- catch {unset selectedline}
+ set selectedline {}
catch {unset currentid}
allcanvs delete secsel
rhighlight_none
proc reselectline {} {
global selectedline
- if {[info exists selectedline]} {
+ if {$selectedline ne {}} {
selectline $selectedline 0
}
}
if {$diffids eq $nullid} {
set fname $line
} else {
- if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
set i [string first "\t" $line]
if {$i < 0} continue
- set sha1 [lindex $line 2]
set fname [string range $line [expr {$i+1}] end]
+ set line [string range $line 0 [expr {$i-1}]]
+ if {$diffids ne $nullid2 && [lindex $line 1] ne "blob"} continue
+ set sha1 [lindex $line 2]
if {[string index $fname 0] eq "\""} {
set fname [lindex $fname 0]
}
global diffmergeid mdifffd
global diffids
global parents
- global limitdiffs viewfiles curview
+ global diffcontext
+ global limitdiffs vfilelimit 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)]
+ set cmd [concat | git diff-tree --no-commit-id --cc -U$diffcontext $id]
+ if {$limitdiffs && $vfilelimit($curview) ne {}} {
+ set cmd [concat $cmd -- $vfilelimit($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
proc gettreediffs {ids} {
global treediff treepending
+ if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return
+
set treepending $ids
set treediff {}
- if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return
fconfigure $gdtf -blocking 0
filerun $gdtf [list gettreediffline $gdtf $ids]
}
proc gettreediffline {gdtf ids} {
global treediff treediffs treepending diffids diffmergeid
- global cmitmode viewfiles curview limitdiffs
+ global cmitmode vfilelimit curview limitdiffs
set nr 0
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
return [expr {$nr >= 1000? 2: 1}]
}
close $gdtf
- if {$limitdiffs && $viewfiles($curview) ne {}} {
+ if {$limitdiffs && $vfilelimit($curview) ne {}} {
set flist {}
foreach f $treediff {
- if {[path_filter $viewfiles($curview) $f]} {
+ if {[path_filter $vfilelimit($curview) $f]} {
lappend flist $f
}
}
}
}
+proc changeignorespace {} {
+ reselectline
+}
+
proc getblobdiffs {ids} {
global blobdifffd diffids env
global diffinhdr treediffs
global diffcontext
- global limitdiffs viewfiles curview
+ global ignorespace
+ global limitdiffs vfilelimit curview
set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"]
- if {$limitdiffs && $viewfiles($curview) ne {}} {
- set cmd [concat $cmd -- $viewfiles($curview)]
+ if {$ignorespace} {
+ append cmd " -w"
+ }
+ if {$limitdiffs && $vfilelimit($curview) ne {}} {
+ set cmd [concat $cmd -- $vfilelimit($curview)]
}
if {[catch {set bdf [open $cmd r]} err]} {
puts "error getting diffs: $err"
$ctext tag conf d1 -elide [lindex $diffelide 1]
}
+proc highlightfile {loc cline} {
+ global ctext cflist cflist_top
+
+ $ctext yview $loc
+ $cflist tag remove highlight $cflist_top.0 "$cflist_top.0 lineend"
+ $cflist tag add highlight $cline.0 "$cline.0 lineend"
+ $cflist see $cline.0
+ set cflist_top $cline
+}
+
proc prevfile {} {
- global difffilestart ctext
- set prev [lindex $difffilestart 0]
+ global difffilestart ctext cmitmode
+
+ if {$cmitmode eq "tree"} return
+ set prev 0.0
+ set prevline 1
set here [$ctext index @0,0]
foreach loc $difffilestart {
if {[$ctext compare $loc >= $here]} {
- $ctext yview $prev
+ highlightfile $prev $prevline
return
}
set prev $loc
+ incr prevline
}
- $ctext yview $prev
+ highlightfile $prev $prevline
}
proc nextfile {} {
- global difffilestart ctext
+ global difffilestart ctext cmitmode
+
+ if {$cmitmode eq "tree"} return
set here [$ctext index @0,0]
+ set line 1
foreach loc $difffilestart {
+ incr line
if {[$ctext compare $loc > $here]} {
- $ctext yview $loc
+ highlightfile $loc $line
return
}
}
proc scrolltext {f0 f1} {
global searchstring
- .bleft.sb set $f0 $f1
+ .bleft.bottom.sb set $f0 $f1
if {$searchstring ne {}} {
searchmarkvisible 0
}
setcanvscroll
allcanvs yview moveto [lindex $span 0]
drawvisible
- if {[info exists selectedline]} {
+ if {$selectedline ne {}} {
selectline $selectedline 0
allcanvs yview moveto [lindex $span 0]
}
}
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:"] "
}
}
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 [split [lindex $matches 0] ","] 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} {
$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
$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
stopfinding
set rowmenuid $id
- if {![info exists selectedline]
- || [rowofcommit $id] eq $selectedline} {
+ if {$selectedline eq {} || [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"
+ if {$mainhead ne {}} {
+ $menu entryconfigure 7 -label [mc "Reset %s branch to here" $mainhead]
+ } else {
+ $menu entryconfigure 7 -label [mc "Detached head: can't reset" $mainhead] -state disabled
+ }
} 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
- if {![info exists selectedline]} return
+ if {$selectedline eq {}} return
if {$dirn} {
set oldid [commitonrow $selectedline]
set newid $rowmenuid
$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 "
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
$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
$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
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
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
$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
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 {
- set dir [gitdir]
- set fname [file join $dir "refs/tags" $tag]
- set f [open $fname w]
- puts $f $id
- close $f
+ exec git tag $tag $id
} err]} {
- error_popup "Error creating tag: $err"
+ error_popup "[mc "Error creating tag:"] $err"
return
}
}
proc redrawtags {id} {
- global canv linehtag idpos selectedline curview
- global canvxmax iddrawn
+ global canv linehtag idpos currentid curview cmitlisted
+ global canvxmax iddrawn circleitem mainheadid circlecolors
if {![commitinview $id $curview]} return
if {![info exists iddrawn($id)]} return
- drawcommits [rowofcommit $id]
+ set row [rowofcommit $id]
+ if {$id eq $mainheadid} {
+ set ofill yellow
+ } else {
+ set ofill [lindex $circlecolors $cmitlisted($curview,$id)]
+ }
+ $canv itemconf $circleitem($row) -fill $ofill
$canv delete tag.$id
set xt [eval drawtags $id $idpos($id)]
- $canv coords $linehtag([rowofcommit $id]) $xt [lindex $idpos($id) 2]
- set text [$canv itemcget $linehtag([rowofcommit $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 == [rowofcommit $id]} {
- selectline $selectedline 0
+ if {[info exists currentid] && $currentid == $id} {
+ make_secsel $row
}
}
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
$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
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
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
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}
proc cherrypick {} {
global rowmenuid curview
- global mainhead
+ global mainhead mainheadid
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 "Cherry-picking"
+ 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...
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
movehead $newhead $mainhead
movedhead $newhead $mainhead
}
+ set mainheadid $newhead
redrawtags $oldhead
redrawtags $newhead
+ selbyid $newhead
}
notbusy cherrypick
}
proc resethead {} {
- global mainheadid mainhead rowmenuid confirm_ok resettype
+ global mainhead rowmenuid confirm_ok resettype
set confirm_ok 0
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 <Visibility> "grab $w; focus $w"
tkwait window $w
if {!$confirm_ok} return
if {[catch {set fd [open \
- [list | sh -c "git reset --$resettype $rowmenuid 2>&1"] r]} err]} {
+ [list | git reset --$resettype $rowmenuid 2>@1] r]} err]} {
error_popup $err
} else {
dohidelocalchanges
filerun $fd [list readresetstat $fd]
- nowbusy reset "Resetting"
+ nowbusy reset [mc "Resetting"]
+ selbyid $rowmenuid
}
}
}
proc cobranch {} {
- global headmenuid headmenuhead mainhead headids
+ global headmenuid headmenuhead headids
global showlocalchanges mainheadid
# check the tree is clean first??
- set oldmainhead $mainhead
- nowbusy checkout "Checking out"
+ nowbusy checkout [mc "Checking out"]
update
dohidelocalchanges
if {[catch {
- exec git checkout -q $headmenuhead
+ set fd [open [list | git checkout $headmenuhead 2>@1] r]
} err]} {
notbusy checkout
error_popup $err
+ if {$showlocalchanges} {
+ dodiffindex
+ }
} else {
- notbusy checkout
- set mainhead $headmenuhead
- set mainheadid $headmenuid
- if {[info exists headids($oldmainhead)]} {
- redrawtags $headids($oldmainhead)
+ filerun $fd [list readcheckoutstat $fd $headmenuhead $headmenuid]
+ }
+}
+
+proc readcheckoutstat {fd newhead newheadid} {
+ global mainhead mainheadid headids showlocalchanges progresscoords
+
+ if {[gets $fd line] >= 0} {
+ if {[regexp {([0-9]+)% \(([0-9]+)/([0-9]+)\)} $line match p m n]} {
+ set progresscoords [list 0 [expr {1.0 * $m / $n}]]
+ adjustprogress
}
- redrawtags $headmenuid
+ return 1
+ }
+ set progresscoords {0 0}
+ adjustprogress
+ notbusy checkout
+ if {[catch {close $fd} err]} {
+ error_popup $err
}
+ set oldmainid $mainheadid
+ set mainhead $newhead
+ set mainheadid $newheadid
+ redrawtags $oldmainid
+ redrawtags $newheadid
+ selbyid $newheadid
if {$showlocalchanges} {
dodiffindex
}
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
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" \
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
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} {
}
proc rereadrefs {} {
- global idtags idheads idotherrefs mainhead
+ global idtags idheads idotherrefs mainheadid
set refids [concat [array names idtags] \
[array names idheads] [array names idotherrefs]]
set ref($id) [listrefs $id]
}
}
- set oldmainhead $mainhead
+ set oldmainhead $mainheadid
readrefs
changedrefs
set refids [lsort -unique [concat $refids [array names idtags] \
[array names idheads] [array names idotherrefs]]]
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)} {
+ if {![info exists ref($id)] || $ref($id) != $v} {
redrawtags $id
}
}
+ if {$oldmainhead ne $mainheadid} {
+ redrawtags $oldmainhead
+ redrawtags $mainheadid
+ }
run refill_reflist
}
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
proc doquit {} {
global stopped
+ global gitktmpdir
+
set stopped 100
savestuff .
destroy .
+
+ if {[info exists gitktmpdir]} {
+ catch {file delete -force $gitktmpdir}
+ }
}
proc mkfontdisp {font top 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
-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
bind $top.c <Configure> [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
global maxwidth maxgraphpct
global oldprefs prefstop showneartags showlocalchanges
global bgcolor fgcolor ctext diffcolors selectbgcolor
- global uifont tabstop limitdiffs
+ global tabstop limitdiffs autoselect extdifftool
set top .gitkprefs
set prefstop $top
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
+ frame $top.autoselect
+ label $top.autoselect.l -text [mc "Auto-select SHA1"] -font optionfont
+ checkbutton $top.autoselect.b -variable autoselect
+ pack $top.autoselect.b $top.autoselect.l -side left
+ grid x $top.autoselect -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 "Tab spacing" -font optionfont
+ 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
frame $top.ldiff
- label $top.ldiff.l -text "Limit diffs to listed paths" -font optionfont
+ 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
+ entry $top.extdifft -textvariable extdifftool
+ frame $top.extdifff
+ label $top.extdifff.l -text [mc "External diff tool" ] -font optionfont \
+ -padx 10
+ button $top.extdifff.b -text [mc "Choose..."] -font optionfont \
+ -command choose_extdiff
+ pack $top.extdifff.l $top.extdifff.b -side left
+ grid x $top.extdifff $top.extdifft -sticky w
+
+ 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 \
- -command [list choosecolor bgcolor 0 $top.bg background setbg]
+ button $top.bgbut -text [mc "Background"] -font optionfont \
+ -command [list choosecolor bgcolor {} $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 \
- -command [list choosecolor fgcolor 0 $top.fg foreground setfg]
+ button $top.fgbut -text [mc "Foreground"] -font optionfont \
+ -command [list choosecolor fgcolor {} $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 \
- -command [list choosecolor selectbgcolor 0 $top.selbgsep background setselbg]
+ button $top.selbgbut -text [mc "Select bg"] -font optionfont \
+ -command [list choosecolor selectbgcolor {} $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
bind $top <Visibility> "focus $top.buts.ok"
}
+proc choose_extdiff {} {
+ global extdifftool
+
+ set prog [tk_getOpenFile -title "External diff tool" -multiple false]
+ if {$prog ne {}} {
+ set extdifftool $prog
+ }
+}
+
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
# First check that Tcl/Tk is recent enough
if {[catch {package require Tk 8.4} err]} {
- show_error {} . "Sorry, gitk cannot run with this version of Tcl/Tk.\n\
- Gitk requires at least Tcl/Tk 8.4."
+ 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"
set gitencoding {}
set showlocalchanges 1
set limitdiffs 1
set datetimeformat "%Y-%m-%d %H:%M:%S"
+set autoselect 1
+
+set extdifftool "meld"
set colors {green red blue magenta darkgrey brown orange}
set bgcolor white
set fgcolor black
set diffcolors {red "#00a000" blue}
set diffcontext 3
+set ignorespace 0
set selectbgcolor gray85
+set circlecolors {white blue gray blue blue}
+
+# button for popping up context menus
+if {[tk windowingsystem] eq "aqua"} {
+ set ctxbut <Button-2>
+} else {
+ set ctxbut <Button-3>
+}
+
+## 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
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 selecthead {}
+set selectheadid {}
+
set revtreeargs {}
set cmdline_files {}
set i 0
+set revtreeargscmd {}
foreach arg $argv {
- switch -- $arg {
+ switch -glob -- $arg {
"" { }
- "-d" { set datemode 1 }
- "--merge" {
- set mergeonly 1
- lappend revtreeargs $arg
- }
"--" {
set cmdline_files [lrange $argv [expr {$i + 1}] end]
break
}
+ "--select-commit=*" {
+ set selecthead [string range $arg 16 end]
+ }
+ "--argscmd=*" {
+ set revtreeargscmd [string range $arg 10 end]
+ }
default {
lappend revtreeargs $arg
}
incr i
}
+if {$selecthead eq "HEAD"} {
+ set selecthead {}
+}
+
if {$i >= [llength $argv] && $revtreeargs ne {}} {
- # no -- on command line, but some arguments (other than -d)
+ # no -- on command line, but some arguments (other than --argscmd)
if {[catch {
set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
set cmdline_files [split $f "\n"]
# 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
}
}
if {$i > 0} {
set err [string range $err [expr {$i + 6}] end]
}
- show_error {} . "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 {} . "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 {} . "No files selected: --merge specified but\
- no files are unmerged."
- } else {
- show_error {} . "No files selected: --merge specified but\
- no unmerged files are within file limit."
- }
+ show_error {} . "[mc "Bad arguments to gitk:"]\n$err"
exit 1
}
- set cmdline_files $mlist
}
set nullid "0000000000000000000000000000000000000000"
set nullid2 "0000000000000000000000000000000000000001"
+set nullfile "/dev/null"
set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 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 viewargscmd(0) {}
+set selectedline {}
+set numcommits 0
set loginstance 0
-set getdbg 0
set cmdlineok 0
set stopped 0
set stuffsaved 0
set patchnum 0
set lserial 0
+set isworktree [expr {[exec git rev-parse --is-inside-work-tree] == "true"}]
setcoords
makewindow
# wait for the window to become visible
wm title . "[file tail $argv0]: [file tail [pwd]]"
readrefs
-if {$cmdline_files ne {} || $revtreeargs ne {}} {
+if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} {
# create a view for the files/dirs specified on the command line
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 viewargscmd(1) $revtreeargscmd
set viewperm(1) 0
+ set vdatemode(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]} {
set viewname($n) [lindex $v 0]
set viewfiles($n) [lindex $v 1]
set viewargs($n) [lindex $v 2]
+ set viewargscmd($n) [lindex $v 3]
set viewperm($n) 1
addviewmenu $n
}
}
-getcommits
+getcommits {}