#!/bin/sh
# Tcl ignores the next line -*- tcl -*- \
-exec wish "$0" -- "${1+$@}"
+exec wish "$0" -- "$@"
# Copyright (C) 2005 Paul Mackerras. All rights reserved.
# This program is free software; it may be used, copied, modified
proc getcommitlines {commfd} {
global commits parents cdate children
- global commitlisted phase commitinfo nextupdate
+ global commitlisted phase nextupdate
global stopped redisplaying leftover
set stuff [read $commfd]
incr ncleft($p)
}
}
- foreach line [split $contents "\n"] {
- if {$inhdr} {
- if {$line == {}} {
- set inhdr 0
- } else {
- set tag [lindex $line 0]
- if {$tag == "author"} {
- set x [expr {[llength $line] - 2}]
- set audate [lindex $line $x]
- set auname [lrange $line 1 [expr {$x - 1}]]
- } elseif {$tag == "committer"} {
- set x [expr {[llength $line] - 2}]
- set comdate [lindex $line $x]
- set comname [lrange $line 1 [expr {$x - 1}]]
- }
- }
- } else {
- if {$comment == {}} {
- set headline [string trim $line]
- } else {
- append comment "\n"
- }
- if {!$listed} {
- # git-rev-list indents the comment by 4 spaces;
- # if we got this via git-cat-file, add the indentation
- append comment " "
- }
- append comment $line
+ set hdrend [string first "\n\n" $contents]
+ if {$hdrend < 0} {
+ # should never happen...
+ set hdrend [string length $contents]
+ }
+ set header [string range $contents 0 [expr {$hdrend - 1}]]
+ set comment [string range $contents [expr {$hdrend + 2}] end]
+ foreach line [split $header "\n"] {
+ set tag [lindex $line 0]
+ if {$tag == "author"} {
+ set audate [lindex $line end-1]
+ set auname [lrange $line 1 end-2]
+ } elseif {$tag == "committer"} {
+ set comdate [lindex $line end-1]
+ set comname [lrange $line 1 end-2]
}
}
- if {$audate != {}} {
- set audate [clock format $audate -format "%Y-%m-%d %H:%M:%S"]
+ set headline {}
+ # take the first line of the comment as the headline
+ set i [string first "\n" $comment]
+ if {$i >= 0} {
+ set headline [string trim [string range $comment 0 $i]]
+ }
+ if {!$listed} {
+ # git-rev-list indents the comment by 4 spaces;
+ # if we got this via git-cat-file, add the indentation
+ set newcomment {}
+ foreach line [split $comment "\n"] {
+ append newcomment " "
+ append newcomment $line
+ }
+ set comment $newcomment
}
if {$comdate != {}} {
set cdate($id) $comdate
- set comdate [clock format $comdate -format "%Y-%m-%d %H:%M:%S"]
}
set commitinfo($id) [list $headline $auname $audate \
$comname $comdate $comment]
}
proc readrefs {} {
- global tagids idtags headids idheads
+ global tagids idtags headids idheads tagcontents
+
set tags [glob -nocomplain -types f [gitdir]/refs/tags/*]
foreach f $tags {
catch {
set direct [file tail $f]
set tagids($direct) $id
lappend idtags($id) $direct
- set contents [split [exec git-cat-file tag $id] "\n"]
+ set tagblob [exec git-cat-file tag $id]
+ set contents [split $tagblob "\n"]
set obj {}
set type {}
set tag {}
if {$obj != {} && $type == "commit" && $tag != {}} {
set tagids($tag) $obj
lappend idtags($obj) $tag
+ set tagcontents($tag) $tagblob
}
}
close $fd
close $fd
}
}
+ readotherrefs refs {} {tags heads}
+}
+
+proc readotherrefs {base dname excl} {
+ global otherrefids idotherrefs
+
+ set git [gitdir]
+ set files [glob -nocomplain -types f [file join $git $base *]]
+ foreach f $files {
+ catch {
+ set fd [open $f r]
+ set line [read $fd 40]
+ if {[regexp {^[0-9a-f]{40}} $line id]} {
+ set name "$dname[file tail $f]"
+ set otherrefids($name) $id
+ lappend idotherrefs($id) $name
+ }
+ close $fd
+ }
+ }
+ set dirs [glob -nocomplain -types d [file join $git $base *]]
+ foreach d $dirs {
+ set dir [file tail $d]
+ if {[lsearch -exact $excl $dir] >= 0} continue
+ readotherrefs [file join $base $dir] "$dname$dir/" {}
+ }
}
proc error_popup msg {
menu .bar
.bar add cascade -label "File" -menu .bar.file
menu .bar.file
+ .bar.file add command -label "Reread references" -command rereadrefs
.bar.file add command -label "Quit" -command doquit
menu .bar.help
.bar add cascade -label "Help" -menu .bar.help
bindall <B2-Motion> "allcanvs scan dragto 0 %y"
bind . <Key-Up> "selnextline -1"
bind . <Key-Down> "selnextline 1"
+ bind . <Key-Right> "goforw"
+ bind . <Key-Left> "goback"
bind . <Key-Prior> "allcanvs yview scroll -1 pages"
bind . <Key-Next> "allcanvs yview scroll 1 pages"
bindkey <Key-Delete> "$ctext yview scroll -1 pages"
bindkey <Key-space> "$ctext yview scroll 1 pages"
bindkey p "selnextline -1"
bindkey n "selnextline 1"
+ bindkey z "goback"
+ bindkey x "goforw"
+ bindkey i "selnextline -1"
+ bindkey k "selnextline 1"
+ bindkey j "goback"
+ bindkey l "goforw"
bindkey b "$ctext yview scroll -1 pages"
bindkey d "$ctext yview scroll 18 units"
bindkey u "$ctext yview scroll -18 units"
}
proc assigncolor {id} {
- global commitinfo colormap commcolors colors nextcolor
+ global colormap commcolors colors nextcolor
global parents nparents children nchildren
global cornercrossings crossings
$canv bind $t <Button-1> "lineclick %x %y $id 1"
}
+proc drawlines {id xtra delold} {
+ global mainline mainlinearrow sidelines lthickness colormap canv
+
+ if {$delold} {
+ $canv delete lines.$id
+ }
+ if {[info exists mainline($id)]} {
+ set t [$canv create line $mainline($id) \
+ -width [expr {($xtra + 1) * $lthickness}] \
+ -fill $colormap($id) -tags lines.$id \
+ -arrow $mainlinearrow($id)]
+ $canv lower $t
+ bindline $t $id
+ }
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set coords [lindex $ls 0]
+ set thick [lindex $ls 1]
+ set arrow [lindex $ls 2]
+ set t [$canv create line $coords -fill $colormap($id) \
+ -width [expr {($thick + $xtra) * $lthickness}] \
+ -arrow $arrow -tags lines.$id]
+ $canv lower $t
+ bindline $t $id
+ }
+ }
+}
+
# level here is an index in displist
proc drawcommitline {level} {
global parents children nparents displist
global canv canv2 canv3 mainfont namefont canvy linespc
global lineid linehtag linentag linedtag commitinfo
global colormap numcommits currentparents dupparents
- global idtags idline idheads
+ global idtags idline idheads idotherrefs
global lineno lthickness mainline mainlinearrow sidelines
global commitlisted rowtextx idpos lastuse displist
global oldnlines olddlevel olddisplist
if {$mainlinearrow($id) ne "none"} {
set mainline($id) [trimdiagstart $mainline($id)]
}
- set t [$canv create line $mainline($id) \
- -width $lthickness -fill $colormap($id) \
- -arrow $mainlinearrow($id)]
- $canv lower $t
- bindline $t $id
- }
- if {[info exists sidelines($id)]} {
- foreach ls $sidelines($id) {
- set coords [lindex $ls 0]
- set thick [lindex $ls 1]
- set arrow [lindex $ls 2]
- set t [$canv create line $coords -fill $colormap($id) \
- -width [expr {$thick * $lthickness}] -arrow $arrow]
- $canv lower $t
- bindline $t $id
- }
}
+ drawlines $id 0 0
set orad [expr {$linespc / 3}]
set t [$canv create oval [expr $x - $orad] [expr $y1 - $orad] \
[expr $x + $orad - 1] [expr $y1 + $orad - 1] \
}
set rowtextx($lineno) $xt
set idpos($id) [list $x $xt $y1]
- if {[info exists idtags($id)] || [info exists idheads($id)]} {
+ if {[info exists idtags($id)] || [info exists idheads($id)]
+ || [info exists idotherrefs($id)]} {
set xt [drawtags $id $x $xt $y1]
}
set headline [lindex $commitinfo($id) 0]
set name [lindex $commitinfo($id) 1]
set date [lindex $commitinfo($id) 2]
+ set date [formatdate $date]
set linehtag($lineno) [$canv create text $xt $y1 -anchor w \
-text $headline -font $mainfont ]
$canv bind $linehtag($lineno) <Button-3> "rowmenu %X %Y $id"
}
proc drawtags {id x xt y1} {
- global idtags idheads
+ global idtags idheads idotherrefs
global linespc lthickness
- global canv mainfont
+ global canv mainfont idline rowtextx
set marks {}
set ntags 0
+ set nheads 0
if {[info exists idtags($id)]} {
set marks $idtags($id)
set ntags [llength $marks]
}
if {[info exists idheads($id)]} {
set marks [concat $marks $idheads($id)]
+ set nheads [llength $idheads($id)]
+ }
+ if {[info exists idotherrefs($id)]} {
+ set marks [concat $marks $idotherrefs($id)]
}
if {$marks eq {}} {
return $xt
set xr [expr $x + $delta + $wid + $lthickness]
if {[incr ntags -1] >= 0} {
# draw a tag
- $canv create polygon $x [expr $yt + $delta] $xl $yt\
- $xr $yt $xr $yb $xl $yb $x [expr $yb - $delta] \
- -width 1 -outline black -fill yellow -tags tag.$id
+ set t [$canv create polygon $x [expr $yt + $delta] $xl $yt \
+ $xr $yt $xr $yb $xl $yb $x [expr $yb - $delta] \
+ -width 1 -outline black -fill yellow -tags tag.$id]
+ $canv bind $t <1> [list showtag $tag 1]
+ set rowtextx($idline($id)) [expr {$xr + $linespc}]
} else {
- # draw a head
+ # draw a head or other ref
+ if {[incr nheads -1] >= 0} {
+ set col green
+ } else {
+ set col "#ddddff"
+ }
set xl [expr $xl - $delta/2]
$canv create polygon $x $yt $xr $yt $xr $yb $x $yb \
- -width 1 -outline black -fill green -tags tag.$id
+ -width 1 -outline black -fill $col -tags tag.$id
+ }
+ set t [$canv create text $xl $y1 -anchor w -text $tag \
+ -font $mainfont -tags tag.$id]
+ if {$ntags >= 0} {
+ $canv bind $t <1> [list showtag $tag 1]
}
- $canv create text $xl $y1 -anchor w -text $tag \
- -font $mainfont -tags tag.$id
}
return $xt
}
}
proc drawcommit {id} {
- global phase todo nchildren datemode nextupdate
- global numcommits ncmupdate displayorder todo onscreen
+ global phase todo nchildren datemode nextupdate revlistorder
+ global numcommits ncmupdate displayorder todo onscreen parents
if {$phase != "incrdraw"} {
set phase incrdraw
lappend todo $id
set onscreen($id) 0
}
- set level [decidenext 1]
- if {$level == {} || $id != [lindex $todo $level]} {
- return
- }
- while 1 {
- lappend displayorder [lindex $todo $level]
- if {[updatetodo $level $datemode]} {
- set level [decidenext 1]
- if {$level == {}} break
+ if {$revlistorder} {
+ set level [lsearch -exact $todo $id]
+ if {$level < 0} {
+ error_popup "oops, $id isn't in todo"
+ return
}
- set id [lindex $todo $level]
- if {![info exists commitlisted($id)]} {
- break
+ lappend displayorder $id
+ updatetodo $level 0
+ } else {
+ set level [decidenext 1]
+ if {$level == {} || $id != [lindex $todo $level]} {
+ return
+ }
+ while 1 {
+ 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
+ }
}
}
drawmore 1
global phase stopped redisplaying selectedline
global datemode todo displayorder
global numcommits ncmupdate
- global nextupdate startmsecs idline
-
- set level [decidenext]
- if {$level >= 0} {
- set phase drawgraph
- while 1 {
- lappend displayorder [lindex $todo $level]
- set hard [updatetodo $level $datemode]
- if {$hard} {
- set level [decidenext]
- if {$level < 0} break
+ global nextupdate startmsecs revlistorder
+
+ if {!$revlistorder} {
+ set level [decidenext]
+ if {$level >= 0} {
+ set phase drawgraph
+ while 1 {
+ lappend displayorder [lindex $todo $level]
+ set hard [updatetodo $level $datemode]
+ if {$hard} {
+ set level [decidenext]
+ if {$level < 0} break
+ }
}
}
- drawmore 0
}
+ drawmore 0
set phase {}
set drawmsecs [expr [clock clicks -milliseconds] - $startmsecs]
#puts "overall $drawmsecs ms for $numcommits commits"
return "$p ($l)"
}
+# append some text to the ctext widget, and make any SHA1 ID
+# that we know about be a clickable link.
+proc appendwithlinks {text} {
+ global ctext idline linknum
+
+ set start [$ctext index "end - 1c"]
+ $ctext insert end $text
+ $ctext insert end "\n"
+ set links [regexp -indices -all -inline {[0-9a-f]{40}} $text]
+ foreach l $links {
+ set s [lindex $l 0]
+ set e [lindex $l 1]
+ set linkid [string range $text $s $e]
+ if {![info exists idline($linkid)]} continue
+ incr e
+ $ctext tag add link "$start + $s c" "$start + $e c"
+ $ctext tag add link$linknum "$start + $s c" "$start + $e c"
+ $ctext tag bind link$linknum <1> [list selectline $idline($linkid) 1]
+ incr linknum
+ }
+ $ctext tag conf link -foreground blue -underline 1
+ $ctext tag bind link <Enter> { %W configure -cursor hand2 }
+ $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+}
+
proc selectline {l isnew} {
global canv canv2 canv3 ctext commitinfo selectedline
global lineid linehtag linentag linedtag
global canvy0 linespc parents nparents children
global cflist currentid sha1entry
- global commentend idtags idline
+ global commentend idtags idline linknum
$canv delete hover
+ normalline
if {![info exists lineid($l)] || ![info exists linehtag($l)]} return
$canv delete secsel
set t [eval $canv create rect [$canv bbox $linehtag($l)] -outline {{}} \
$ctext conf -state normal
$ctext delete 0.0 end
+ set linknum 0
$ctext mark set fmark.0 0.0
$ctext mark gravity fmark.0 left
set info $commitinfo($id)
- $ctext insert end "Author: [lindex $info 1] [lindex $info 2]\n"
- $ctext insert end "Committer: [lindex $info 3] [lindex $info 4]\n"
+ set date [formatdate [lindex $info 2]]
+ $ctext insert end "Author: [lindex $info 1] $date\n"
+ set date [formatdate [lindex $info 4]]
+ $ctext insert end "Committer: [lindex $info 3] $date\n"
if {[info exists idtags($id)]} {
$ctext insert end "Tags:"
foreach tag $idtags($id) {
$ctext insert end "\n"
}
- set commentstart [$ctext index "end - 1c"]
set comment {}
if {[info exists parents($id)]} {
foreach p $parents($id) {
}
append comment "\n"
append comment [lindex $info 5]
- $ctext insert end $comment
- $ctext insert end "\n"
# make anything that looks like a SHA1 ID be a clickable link
- set links [regexp -indices -all -inline {[0-9a-f]{40}} $comment]
- set i 0
- foreach l $links {
- set s [lindex $l 0]
- set e [lindex $l 1]
- set linkid [string range $comment $s $e]
- if {![info exists idline($linkid)]} continue
- incr e
- $ctext tag add link "$commentstart + $s c" "$commentstart + $e c"
- $ctext tag add link$i "$commentstart + $s c" "$commentstart + $e c"
- $ctext tag bind link$i <1> [list selectline $idline($linkid) 1]
- incr i
- }
- $ctext tag conf link -foreground blue -underline 1
- $ctext tag bind link <Enter> { %W configure -cursor hand2 }
- $ctext tag bind link <Leave> { %W configure -cursor $curtextcursor }
+ appendwithlinks $comment
$ctext tag delete Comments
$ctext tag remove found 1.0 end
set treediff {}
set id [lindex $ids 0]
set p [lindex $ids 1]
- if [catch {set gdtf [open "|git-diff-tree -r $p $id" r]}] return
+ if [catch {set gdtf [open "|git-diff-tree -r $id" r]}] return
fconfigure $gdtf -blocking 0
fileevent $gdtf readable [list gettreediffline $gdtf $ids]
}
set id [lindex $ids 0]
set p [lindex $ids 1]
set env(GIT_DIFF_OPTS) $diffopts
- set cmd [list | git-diff-tree -r -p -C $p $id]
+ set cmd [list | git-diff-tree -r -p -C $id]
if {[catch {set bdf [open $cmd r]} err]} {
puts "error getting diffs: $err"
return
$canv raise $t
}
+proc clickisonarrow {id y} {
+ global mainline mainlinearrow sidelines lthickness
+
+ set thresh [expr {2 * $lthickness + 6}]
+ if {[info exists mainline($id)]} {
+ if {$mainlinearrow($id) ne "none"} {
+ if {abs([lindex $mainline($id) 1] - $y) < $thresh} {
+ return "up"
+ }
+ }
+ }
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set coords [lindex $ls 0]
+ set arrow [lindex $ls 2]
+ if {$arrow eq "first" || $arrow eq "both"} {
+ if {abs([lindex $coords 1] - $y) < $thresh} {
+ return "up"
+ }
+ }
+ if {$arrow eq "last" || $arrow eq "both"} {
+ if {abs([lindex $coords end] - $y) < $thresh} {
+ return "down"
+ }
+ }
+ }
+ }
+ return {}
+}
+
+proc arrowjump {id dirn y} {
+ global mainline sidelines canv
+
+ set yt {}
+ if {$dirn eq "down"} {
+ if {[info exists mainline($id)]} {
+ set y1 [lindex $mainline($id) 1]
+ if {$y1 > $y} {
+ set yt $y1
+ }
+ }
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set y1 [lindex $ls 0 1]
+ if {$y1 > $y && ($yt eq {} || $y1 < $yt)} {
+ set yt $y1
+ }
+ }
+ }
+ } else {
+ if {[info exists sidelines($id)]} {
+ foreach ls $sidelines($id) {
+ set y1 [lindex $ls 0 end]
+ if {$y1 < $y && ($yt eq {} || $y1 > $yt)} {
+ set yt $y1
+ }
+ }
+ }
+ }
+ if {$yt eq {}} return
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ if {$ymax eq {} || $ymax <= 0} return
+ set view [$canv yview]
+ set yspan [expr {[lindex $view 1] - [lindex $view 0]}]
+ set yfrac [expr {$yt / $ymax - $yspan / 2}]
+ if {$yfrac < 0} {
+ set yfrac 0
+ }
+ $canv yview moveto $yfrac
+}
+
proc lineclick {x y id isnew} {
- global ctext commitinfo children cflist canv
+ global ctext commitinfo children cflist canv thickerline
unmarkmatches
unselectline
+ normalline
+ $canv delete hover
+ # draw this line thicker than normal
+ drawlines $id 1 1
+ set thickerline $id
if {$isnew} {
- addtohistory [list lineclick $x $x $id 0]
+ set ymax [lindex [$canv cget -scrollregion] 3]
+ if {$ymax eq {}} return
+ set yfrac [lindex [$canv yview] 0]
+ set y [expr {$y + $yfrac * $ymax}]
+ }
+ set dirn [clickisonarrow $id $y]
+ if {$dirn ne {}} {
+ arrowjump $id $dirn $y
+ return
+ }
+
+ if {$isnew} {
+ addtohistory [list lineclick $x $y $id 0]
}
- $canv delete hover
# fill the details pane with info about this line
$ctext conf -state normal
$ctext delete 0.0 end
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 "\tDate:\t[lindex $info 2]\n"
+ set date [formatdate [lindex $info 2]]
+ $ctext insert end "\tDate:\t$date\n"
if {[info exists children($id)]} {
$ctext insert end "\nChildren:"
set i 0
$ctext tag bind link$i <1> [list selbyid $child]
$ctext insert end "\n\t[lindex $info 0]"
$ctext insert end "\n\tAuthor:\t[lindex $info 1]"
- $ctext insert end "\n\tDate:\t[lindex $info 2]\n"
+ set date [formatdate [lindex $info 2]]
+ $ctext insert end "\n\tDate:\t$date\n"
}
}
$ctext conf -state disabled
$cflist delete 0 end
}
+proc normalline {} {
+ global thickerline
+ if {[info exists thickerline]} {
+ drawlines $thickerline 0 1
+ unset thickerline
+ }
+}
+
proc selbyid {id} {
global idline
if {[info exists idline($id)]} {
proc domktag {} {
global mktagtop env tagids idtags
- global idpos idline linehtag canv selectedline
set id [$mktagtop.sha1 get]
set tag [$mktagtop.tag get]
set tagids($tag) $id
lappend idtags($id) $tag
+ redrawtags $id
+}
+
+proc redrawtags {id} {
+ global canv linehtag idline idpos selectedline
+
+ if {![info exists idline($id)]} return
$canv delete tag.$id
set xt [eval drawtags $id $idpos($id)]
$canv coords $linehtag($idline($id)) $xt [lindex $idpos($id) 2]
unset wrcomtop
}
+proc listrefs {id} {
+ global idtags idheads idotherrefs
+
+ set x {}
+ if {[info exists idtags($id)]} {
+ set x $idtags($id)
+ }
+ set y {}
+ if {[info exists idheads($id)]} {
+ set y $idheads($id)
+ }
+ set z {}
+ if {[info exists idotherrefs($id)]} {
+ set z $idotherrefs($id)
+ }
+ return [list $x $y $z]
+}
+
+proc rereadrefs {} {
+ global idtags idheads idotherrefs
+ global tagids headids otherrefids
+
+ set refids [concat [array names idtags] \
+ [array names idheads] [array names idotherrefs]]
+ foreach id $refids {
+ if {![info exists ref($id)]} {
+ 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]]]
+ foreach id $refids {
+ set v [listrefs $id]
+ if {![info exists ref($id)] || $ref($id) != $v} {
+ redrawtags $id
+ }
+ }
+}
+
+proc showtag {tag isnew} {
+ global ctext cflist tagcontents tagids linknum
+
+ if {$isnew} {
+ addtohistory [list showtag $tag 0]
+ }
+ $ctext conf -state normal
+ $ctext delete 0.0 end
+ set linknum 0
+ if {[info exists tagcontents($tag)]} {
+ set text $tagcontents($tag)
+ } else {
+ set text "Tag: $tag\nId: $tagids($tag)"
+ }
+ appendwithlinks $text
+ $ctext conf -state disabled
+ $cflist delete 0 end
+}
+
proc doquit {} {
global stopped
set stopped 100
destroy .
}
+proc formatdate {d} {
+ global hours nhours tfd
+
+ 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
+ }
+ incr nhours($hr)
+ set minsec [format "%.2d:%.2d" [expr {$ms/60}] [expr {$ms%60}]]
+ return "$hours($hr):$minsec"
+}
+
# defaults...
set datemode 0
set boldnames 0
set gaudydiff 0
set maxgraphpct 50
set maxwidth 16
+set revlistorder 0
set colors {green red blue magenta darkgrey brown orange}
"^$" { }
"^-b" { set boldnames 1 }
"^-d" { set datemode 1 }
+ "^-r" { set revlistorder 1 }
default {
lappend revtreeargs $arg
}