}
}
-proc getcommits {rargs} {
- global commits commfd phase canv mainfont env
- global startmsecs nextupdate ncmupdate
- global ctext maincursor textcursor leftover gitencoding
+proc parse_args {rargs} {
+ global parsed_args
- # check that we can find a .git directory somewhere...
- set gitdir [gitdir]
- if {![file isdirectory $gitdir]} {
- error_popup "Cannot find the git directory \"$gitdir\"."
- exit 1
- }
- set commits {}
- set phase getcommits
- set startmsecs [clock clicks -milliseconds]
- set nextupdate [expr {$startmsecs + 100}]
- set ncmupdate 1
if [catch {
set parse_args [concat --default HEAD $rargs]
set parsed_args [split [eval exec git-rev-parse $parse_args] "\n"]
}
set parsed_args $rargs
}
+ return $parsed_args
+}
+
+proc start_rev_list {rlargs} {
+ global startmsecs nextupdate ncmupdate
+ global commfd leftover gitencoding
+
+ set startmsecs [clock clicks -milliseconds]
+ set nextupdate [expr {$startmsecs + 100}]
+ set ncmupdate 1
if [catch {
- set commfd [open "|git-rev-list --header --topo-order --parents $parsed_args" r]
+ set commfd [open [concat | git-rev-list --header --topo-order \
+ --parents $rlargs] r]
} err] {
puts stderr "Error executing git-rev-list: $err"
exit 1
set leftover {}
fconfigure $commfd -blocking 0 -translation lf -encoding $gitencoding
fileevent $commfd readable [list getcommitlines $commfd]
+ . config -cursor watch
+ settextcursor watch
+}
+
+proc getcommits {rargs} {
+ global oldcommits commits phase canv mainfont env
+
+ # check that we can find a .git directory somewhere...
+ set gitdir [gitdir]
+ if {![file isdirectory $gitdir]} {
+ error_popup "Cannot find the git directory \"$gitdir\"."
+ exit 1
+ }
+ set oldcommits {}
+ set commits {}
+ set phase getcommits
+ start_rev_list [parse_args $rargs]
$canv delete all
$canv create text 3 3 -anchor nw -text "Reading commits..." \
-font $mainfont -tags textitems
- . config -cursor watch
- settextcursor watch
}
proc getcommitlines {commfd} {
- global commits parents cdate children
+ global oldcommits commits parents cdate children nchildren
global commitlisted phase nextupdate
global stopped redisplaying leftover
+ global canv
set stuff [read $commfd]
if {$stuff == {}} {
lappend commits $id
set commitlisted($id) 1
parsecommit $id $cmit 1 [lrange $ids 1 end]
- drawcommit $id
+ drawcommit $id 1
if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate 1
}
set stopped 0
set phase "getcommits"
foreach id $commits {
- drawcommit $id
+ drawcommit $id 1
if {$stopped} break
if {[clock clicks -milliseconds] >= $nextupdate} {
doupdate 1
parsecommit $id $contents 0 {}
}
-proc parsecommit {id contents listed olds} {
- global commitinfo children nchildren parents nparents cdate ncleft
+proc updatechildren {id olds} {
+ global children nchildren parents nparents ncleft
- set inhdr 1
- set comment {}
- set headline {}
- set auname {}
- set audate {}
- set comname {}
- set comdate {}
if {![info exists nchildren($id)]} {
set children($id) {}
set nchildren($id) 0
incr ncleft($p)
}
}
+}
+
+proc parsecommit {id contents listed olds} {
+ global commitinfo cdate
+
+ set inhdr 1
+ set comment {}
+ set headline {}
+ set auname {}
+ set audate {}
+ set comname {}
+ set comdate {}
+ updatechildren $id $olds
set hdrend [string first "\n\n" $contents]
if {$hdrend < 0} {
# should never happen...
global tagids idtags headids idheads tagcontents
global otherrefids idotherrefs
+ foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
+ catch {unset $v}
+ }
set refd [open [list | git-ls-remote [gitdir]] r]
while {0 <= [set n [gets $refd line]]} {
if {![regexp {^([0-9a-f]{40}) refs/([^^]*)$} $line \
tkwait window $w
}
-proc makewindow {} {
+proc makewindow {rargs} {
global canv canv2 canv3 linespc charspc ctext cflist textfont
global findtype findtypemenu findloc findstring fstring geometry
global entries sha1entry sha1string sha1but
global maincursor textcursor curtextcursor
- global rowctxmenu gaudydiff mergemax
+ global rowctxmenu mergemax
menu .bar
.bar add cascade -label "File" -menu .bar.file
menu .bar.file
+ .bar.file add command -label "Update" -command [list updatecommits $rargs]
.bar.file add command -label "Reread references" -command rereadrefs
.bar.file add command -label "Quit" -command doquit
+ menu .bar.edit
+ .bar add cascade -label "Edit" -menu .bar.edit
+ .bar.edit add command -label "Preferences" -command doprefs
menu .bar.help
.bar add cascade -label "Help" -menu .bar.help
.bar.help add command -label "About gitk" -command about
.ctop.cdet add .ctop.cdet.left
$ctext tag conf filesep -font [concat $textfont bold] -back "#aaaaaa"
- if {$gaudydiff} {
- $ctext tag conf hunksep -back blue -fore white
- $ctext tag conf d0 -back "#ff8080"
- $ctext tag conf d1 -back green
- } else {
- $ctext tag conf hunksep -fore blue
- $ctext tag conf d0 -fore red
- $ctext tag conf d1 -fore "#00a000"
- $ctext tag conf m0 -fore red
- $ctext tag conf m1 -fore blue
- $ctext tag conf m2 -fore green
- $ctext tag conf m3 -fore purple
- $ctext tag conf m4 -fore brown
- $ctext tag conf mmax -fore darkgrey
- set mergemax 5
- $ctext tag conf mresult -font [concat $textfont bold]
- $ctext tag conf msep -font [concat $textfont bold]
- $ctext tag conf found -back yellow
- }
+ $ctext tag conf hunksep -fore blue
+ $ctext tag conf d0 -fore red
+ $ctext tag conf d1 -fore "#00a000"
+ $ctext tag conf m0 -fore red
+ $ctext tag conf m1 -fore blue
+ $ctext tag conf m2 -fore green
+ $ctext tag conf m3 -fore purple
+ $ctext tag conf m4 -fore brown
+ $ctext tag conf mmax -fore darkgrey
+ set mergemax 5
+ $ctext tag conf mresult -font [concat $textfont bold]
+ $ctext tag conf msep -font [concat $textfont bold]
+ $ctext tag conf found -back yellow
frame .ctop.cdet.right
set cflist .ctop.cdet.right.cfiles
proc savestuff {w} {
global canv canv2 canv3 ctext cflist mainfont textfont
- global stuffsaved findmergefiles gaudydiff maxgraphpct
+ global stuffsaved findmergefiles maxgraphpct
global maxwidth
if {$stuffsaved} return
puts $f [list set mainfont $mainfont]
puts $f [list set textfont $textfont]
puts $f [list set findmergefiles $findmergefiles]
- puts $f [list set gaudydiff $gaudydiff]
puts $f [list set maxgraphpct $maxgraphpct]
puts $f [list set maxwidth $maxwidth]
puts $f "set geometry(width) [winfo width .ctop]"
proc initgraph {} {
global canvy canvy0 lineno numcommits nextcolor linespc
- global mainline mainlinearrow sidelines
global nchildren ncleft
global displist nhyperspace
set canvy $canvy0
set lineno -1
set numcommits 0
- catch {unset mainline}
- catch {unset mainlinearrow}
- catch {unset sidelines}
+ foreach v {mainline mainlinearrow sidelines colormap cornercrossings
+ crossings idline lineid} {
+ global $v
+ catch {unset $v}
+ }
foreach id [array names nchildren] {
set ncleft($id) $nchildren($id)
}
}
}
}
- if {$level < 0} {
- if {$todo != {}} {
- puts "ERROR: none of the pending commits can be done yet:"
- foreach p $todo {
- puts " $p ($ncleft($p))"
- }
- }
- return -1
- }
return $level
}
-proc drawcommit {id} {
- global phase todo nchildren datemode nextupdate revlistorder
+proc drawcommit {id reading} {
+ global phase todo nchildren datemode nextupdate revlistorder ncleft
global numcommits ncmupdate displayorder todo onscreen parents
+ global commitlisted commitordered
if {$phase != "incrdraw"} {
set phase incrdraw
set displayorder {}
set todo {}
initgraph
+ catch {unset commitordered}
}
+ set commitordered($id) 1
if {$nchildren($id) == 0} {
lappend todo $id
set onscreen($id) 0
updatetodo $level 0
} else {
set level [decidenext 1]
- if {$level == {} || $id != [lindex $todo $level]} {
- return
- }
+ if {$level == {} || $level < 0} return
while 1 {
+ set id [lindex $todo $level]
+ if {![info exists commitordered($id)]} {
+ break
+ }
lappend displayorder [lindex $todo $level]
if {[updatetodo $level $datemode]} {
set level [decidenext 1]
- if {$level == {}} break
- }
- set id [lindex $todo $level]
- if {![info exists commitlisted($id)]} {
- break
+ if {$level == {} || $level < 0} break
}
}
}
- drawmore 1
+ drawmore $reading
}
proc finishcommits {} {
- global phase
+ global phase oldcommits commits
global canv mainfont ctext maincursor textcursor
+ global parents displayorder todo
- if {$phase != "incrdraw"} {
+ if {$phase == "incrdraw" || $phase == "removecommits"} {
+ foreach id $oldcommits {
+ lappend commits $id
+ drawcommit $id 0
+ }
+ set oldcommits {}
+ drawrest
+ } elseif {$phase == "updatecommits"} {
+ # there were no new commits, in fact
+ set commits $oldcommits
+ set oldcommits {}
+ set phase {}
+ } else {
$canv delete all
$canv create text 3 3 -anchor nw -text "No commits selected" \
-font $mainfont -tags textitems
set phase {}
- } else {
- drawrest
}
. config -cursor $maincursor
settextcursor $textcursor
proc drawrest {} {
global phase stopped redisplaying selectedline
- global datemode todo displayorder
+ global datemode todo displayorder ncleft
global numcommits ncmupdate
global nextupdate startmsecs revlistorder
}
}
}
+ if {$todo != {}} {
+ puts "ERROR: none of the pending commits can be done yet:"
+ foreach p $todo {
+ puts " $p ($ncleft($p))"
+ }
+ }
+
drawmore 0
set phase {}
set drawmsecs [expr {[clock clicks -milliseconds] - $startmsecs}]
global diffids blobdifffd ctext curdifftag curtagstart
global diffnexthead diffnextnote difffilestart
global nextupdate diffinhdr treediffs
- global gaudydiff
set n [gets $bdf line]
if {$n < 0} {
set diffinhdr 0
} elseif {[regexp {^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@(.*)} \
$line match f1l f1c f2l f2c rest]} {
- if {$gaudydiff} {
- $ctext insert end "\t" hunksep
- $ctext insert end " $f1l " d0 " $f2l " d1
- $ctext insert end " $rest \n" hunksep
- } else {
- $ctext insert end "$line\n" hunksep
- }
+ $ctext insert end "$line\n" hunksep
set diffinhdr 0
} else {
set x [string range $line 0 0]
if {$x == "-" || $x == "+"} {
set tag [expr {$x == "+"}]
- if {$gaudydiff} {
- set line [string range $line 1 end]
- }
$ctext insert end "$line\n" d$tag
} elseif {$x == " "} {
- if {$gaudydiff} {
- set line [string range $line 1 end]
- }
$ctext insert end "$line\n"
} elseif {$diffinhdr || $x == "\\"} {
# e.g. "\ No newline at end of file"
set ref($id) [listrefs $id]
}
}
- foreach v {tagids idtags headids idheads otherrefids idotherrefs} {
- catch {unset $v}
- }
readrefs
set refids [lsort -unique [concat $refids [array names idtags] \
[array names idheads] [array names idotherrefs]]]
}
}
+proc updatecommits {rargs} {
+ global commitlisted commfd phase
+ global startmsecs nextupdate ncmupdate
+ global idtags idheads idotherrefs
+ global leftover
+ global parsed_args
+ global canv mainfont
+ global oldcommits commits
+ global parents nchildren children ncleft
+
+ set old_args $parsed_args
+ parse_args $rargs
+
+ if {$phase == "getcommits" || $phase == "incrdraw"} {
+ # havent read all the old commits, just start again from scratch
+ stopfindproc
+ set oldcommits {}
+ set commits {}
+ foreach v {children nchildren parents commitlisted commitinfo
+ selectedline matchinglines treediffs
+ mergefilelist currentid rowtextx} {
+ global $v
+ catch {unset $v}
+ }
+ readrefs
+ if {$phase == "incrdraw"} {
+ allcanvs delete all
+ $canv create text 3 3 -anchor nw -text "Reading commits..." \
+ -font $mainfont -tags textitems
+ set phase getcommits
+ }
+ start_rev_list $parsed_args
+ return
+ }
+
+ foreach id $old_args {
+ if {![regexp {^[0-9a-f]{40}$} $id]} continue
+ if {[info exists oldref($id)]} continue
+ set oldref($id) $id
+ lappend ignoreold "^$id"
+ }
+ foreach id $parsed_args {
+ if {![regexp {^[0-9a-f]{40}$} $id]} continue
+ if {[info exists ref($id)]} continue
+ set ref($id) $id
+ lappend ignorenew "^$id"
+ }
+
+ foreach a $old_args {
+ if {![info exists ref($a)]} {
+ lappend ignorenew $a
+ }
+ }
+
+ set phase updatecommits
+ set oldcommits $commits
+ set commits {}
+ set removed_commits [split [eval exec git-rev-list $ignorenew] "\n" ]
+ if {[llength $removed_commits] > 0} {
+ allcanvs delete all
+ foreach c $removed_commits {
+ set i [lsearch -exact $oldcommits $c]
+ if {$i >= 0} {
+ set oldcommits [lreplace $oldcommits $i $i]
+ unset commitlisted($c)
+ foreach p $parents($c) {
+ if {[info exists nchildren($p)]} {
+ set j [lsearch -exact $children($p) $c]
+ if {$j >= 0} {
+ set children($p) [lreplace $children($p) $j $j]
+ incr nchildren($p) -1
+ }
+ }
+ }
+ }
+ }
+ set phase removecommits
+ }
+
+ set args {}
+ foreach a $parsed_args {
+ if {![info exists oldref($a)]} {
+ lappend args $a
+ }
+ }
+
+ readrefs
+ start_rev_list [concat $ignoreold $args]
+}
+
proc showtag {tag isnew} {
global ctext cflist tagcontents tagids linknum
destroy .
}
-proc formatdate {d} {
- global hours nhours tfd fastdate
+proc doprefs {} {
+ global maxwidth maxgraphpct diffopts findmergefiles
+ global oldprefs prefstop
- if {!$fastdate} {
- return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
+ set top .gitkprefs
+ set prefstop $top
+ if {[winfo exists $top]} {
+ raise $top
+ return
}
- set hr [expr {$d / 3600}]
- set ms [expr {$d % 3600}]
- if {![info exists hours($hr)]} {
- set hours($hr) [clock format $d -format "%Y-%m-%d %H"]
- set nhours($hr) 0
+ foreach v {maxwidth maxgraphpct diffopts findmergefiles} {
+ set oldprefs($v) [set $v]
+ }
+ toplevel $top
+ wm title $top "Gitk preferences"
+ label $top.ldisp -text "Commit list display options"
+ grid $top.ldisp - -sticky w -pady 10
+ label $top.spacer -text " "
+ label $top.maxwidthl -text "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)" \
+ -font optionfont
+ spinbox $top.maxpct -from 1 -to 100 -width 4 -textvariable maxgraphpct
+ grid x $top.maxpctl $top.maxpct -sticky w
+ checkbutton $top.findm -variable findmergefiles
+ label $top.findml -text "Include merges for \"Find\" in \"Files\"" \
+ -font optionfont
+ grid $top.findm $top.findml - -sticky w
+ label $top.ddisp -text "Diff display options"
+ grid $top.ddisp - -sticky w -pady 10
+ label $top.diffoptl -text "Options for diff program" \
+ -font optionfont
+ entry $top.diffopt -width 20 -textvariable diffopts
+ grid x $top.diffoptl $top.diffopt -sticky w
+ frame $top.buts
+ button $top.buts.ok -text "OK" -command prefsok
+ button $top.buts.can -text "Cancel" -command prefscan
+ 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
+ grid $top.buts - - -pady 10 -sticky ew
+}
+
+proc prefscan {} {
+ global maxwidth maxgraphpct diffopts findmergefiles
+ global oldprefs prefstop
+
+ foreach v {maxwidth maxgraphpct diffopts findmergefiles} {
+ set $v $oldprefs($v)
+ }
+ catch {destroy $prefstop}
+ unset prefstop
+}
+
+proc prefsok {} {
+ global maxwidth maxgraphpct
+ global oldprefs prefstop
+
+ catch {destroy $prefstop}
+ unset prefstop
+ if {$maxwidth != $oldprefs(maxwidth)
+ || $maxgraphpct != $oldprefs(maxgraphpct)} {
+ redisplay
}
- incr nhours($hr)
- set minsec [format "%.2d:%.2d" [expr {$ms/60}] [expr {$ms%60}]]
- return "$hours($hr):$minsec"
+}
+
+proc formatdate {d} {
+ return [clock format $d -format "%Y-%m-%d %H:%M:%S"]
}
# defaults...
set datemode 0
-set boldnames 0
set diffopts "-U 5 -p"
set wrcomcmd "git-diff-tree --stdin -p --pretty"
-set gitencoding "utf-8"
+
+set gitencoding ""
+catch {
+ set gitencoding [exec git-repo-config --get i18n.commitencoding]
+}
+if {$gitencoding == ""} {
+ set gitencoding "utf-8"
+}
set mainfont {Helvetica 9}
set textfont {Courier 9}
set findmergefiles 0
-set gaudydiff 0
set maxgraphpct 50
set maxwidth 16
set revlistorder 0
catch {source ~/.gitk}
set namefont $mainfont
-if {$boldnames} {
- lappend namefont bold
-}
+
+font create optionfont -family sans-serif -size -12
set revtreeargs {}
foreach arg $argv {
switch -regexp -- $arg {
"^$" { }
- "^-b" { set boldnames 1 }
"^-d" { set datemode 1 }
"^-r" { set revlistorder 1 }
default {
set stuffsaved 0
set patchnum 0
setcoords
-makewindow
+makewindow $revtreeargs
readrefs
getcommits $revtreeargs