From: Paul Mackerras Date: Sat, 26 Apr 2008 06:00:00 +0000 (+1000) Subject: gitk: Reorganize processing of arguments for git log X-Git-Url: http://privyetmir.co.uk/gitweb.cgi?a=commitdiff_plain;h=3ed31a8120ec78c495206c89cf5d421d9198f847;p=gitk gitk: Reorganize processing of arguments for git log This moves the scanning of the argument list for each view into a new function, parseviewargs, which is called from start_rev_list. This also makes the date mode and the merge mode be per-view rather than global. In merge mode, we work out the list of relevant files in a new function called from start_rev_list, so it will be updated on File->Reload. Plus we now do that after running the argscmd, so if we have one and it generates a -d or --merge option they will be correctly handled now. The other thing this does is to make errors detected in start_rev_list not be fatal. Now instead of doing exit 1 we just pop up and error window and put "No commits selected" in the graph pane. Signed-off-by: Paul Mackerras --- diff --git a/gitk b/gitk index bf6eb01..4f83977 100755 --- a/gitk +++ b/gitk @@ -90,20 +90,71 @@ proc dorunq {} { } } +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 viewargs vdatemode vmergeonly + + set vdatemode($n) 0 + set vmergeonly($n) 0 + set glargs {} + foreach arg $viewargs($n) { + switch -glob -- $arg { + "-d" - + "--date-order" { + set vdatemode($n) 1 + } + "--merge" { + set vmergeonly($n) 1 + lappend glargs $arg + } + default { + lappend glargs $arg + } + } + } + return $glargs +} + # 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 viewargscmd viewfiles commitidx viewcomplete + global startmsecs commitidx viewcomplete + global commfd leftover tclencoding + global viewargs viewargscmd vactualargs viewfiles vfilelimit global showlocalchanges commitinterest mainheadid global progressdirn progresscoords proglastnc curview - global viewactive loginstance viewinstances + global viewactive loginstance viewinstances vmergeonly global pending_select mainheadid set startmsecs [clock clicks -milliseconds] set commitidx($view) 0 - set viewcomplete($view) 0 - set viewactive($view) 1 + # these are set this way for the error exits + set viewcomplete($view) 1 + set viewactive($view) 0 varcinit $view set args $viewargs($view) @@ -112,16 +163,36 @@ proc start_rev_list {view} { set str [exec sh -c $viewargscmd($view)] } err]} { error_popup "Error executing --argscmd command: $err" - exit 1 + return 0 } set args [concat $args [split $str "\n"]] } + set args [parseviewargs $view $args] + set vactualargs($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 {[catch { set fd [open [concat | git log --no-color -z --pretty=raw --parents \ - --boundary $args "--" $viewfiles($view)] r] + --boundary $args "--" $files] r] } err]} { error_popup "[mc "Error executing git log:"] $err" - exit 1 + return 0 } set i [incr loginstance] set viewinstances($view) [list $i] @@ -142,6 +213,9 @@ proc start_rev_list {view} { set proglastnc 0 set pending_select $mainheadid } + set viewcomplete($view) 0 + set viewactive($view) 1 + return 1 } proc stop_rev_list {view} { @@ -162,16 +236,19 @@ proc stop_rev_list {view} { } proc getcommits {} { - global canv curview need_redisplay + global canv curview need_redisplay viewactive initlayout - start_rev_list $curview - show_status [mc "Reading commits..."] - set need_redisplay 1 + if {[start_rev_list $curview]} { + show_status [mc "Reading commits..."] + set need_redisplay 1 + } else { + show_status [mc "No commits selected"] + } } proc updatecommits {} { - global curview viewargs viewfiles viewinstances + global curview vactualargs vfilelimit viewinstances global viewactive viewcomplete loginstance tclencoding mainheadid global startmsecs commfd showneartags showlocalchanges leftover global mainheadid pending_select @@ -191,8 +268,8 @@ proc updatecommits {} { set view $curview if {[catch { set fd [open [concat | git log --no-color -z --pretty=raw --parents \ - --boundary $viewargs($view) --not [seeds $view] \ - "--" $viewfiles($view)] r] + --boundary $vactualargs($view) --not [seeds $view] \ + "--" $vfilelimit($view)] r] } err]} { error_popup "Error executing git log: $err" exit 1 @@ -316,13 +393,13 @@ proc seeds {v} { } proc newvarc {view id} { - global varcid varctok parents children datemode + 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 || $datemode} { + if {[llength $children($vid)] == 0 || $vdatemode($view)} { if {![info exists commitinfo($id)]} { parsecommit $id $commitdata($id) 1 } @@ -422,7 +499,7 @@ proc splitvarc {p v} { proc renumbervarc {a v} { global parents children varctok varcstart varccommits - global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod datemode + global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod vdatemode set t1 [clock clicks -milliseconds] set todo {} @@ -458,7 +535,7 @@ proc renumbervarc {a v} { $children($v,$id)] } set oldtok [lindex $varctok($v) $a] - if {!$datemode} { + if {!$vdatemode($v)} { set tok {} } else { set tok $oldtok @@ -992,10 +1069,10 @@ proc rewrite_commit {v id rwid} { proc getcommitlines {fd inst view updating} { global cmitlisted commitinterest leftover - global commitidx commitdata datemode + global commitidx commitdata vdatemode global parents children curview hlview global idpending ordertok - global varccommits varcid varctok vtokmod viewfiles + global varccommits varcid varctok vtokmod vfilelimit set stuff [read $fd 500000] # git log doesn't terminate the last commit with a null... @@ -1098,7 +1175,7 @@ proc getcommitlines {fd inst view updating} { set vid $view,$id if {!$listed && $updating && ![info exists varcid($vid)] && - $viewfiles($view) ne {}} { + $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 @@ -1106,7 +1183,7 @@ proc getcommitlines {fd inst view updating} { # parent as a substitute parent for $id's children. if {![catch { set rwid [exec git rev-list --first-parent --max-count=1 \ - $id -- $viewfiles($view)] + $id -- $vfilelimit($view)] }]} { if {$rwid ne {} && [info exists varcid($view,$rwid)]} { # use $rwid in place of $id @@ -1134,7 +1211,7 @@ proc getcommitlines {fd inst view updating} { } elseif {$a == 0 && [llength $children($vid)] == 1} { set k [lindex $children($vid) 0] if {[llength $parents($view,$k)] == 1 && - (!$datemode || + (!$vdatemode($view) || $varcid($view,$k) == [llength $varctok($view)] - 1)} { set a $varcid($view,$k) } @@ -2880,7 +2957,7 @@ proc addviewmenu {n} { } 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 @@ -5869,14 +5946,14 @@ proc mergediff {id} { global diffids global parents global diffcontext - global limitdiffs viewfiles curview + 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 -U$diffcontext $id] - if {$limitdiffs && $viewfiles($curview) ne {}} { - set cmd [concat $cmd -- $viewfiles($curview)] + if {$limitdiffs && $vfilelimit($curview) ne {}} { + set cmd [concat $cmd -- $vfilelimit($curview)] } if {[catch {set mdf [open $cmd r]} err]} { error_popup "[mc "Error getting merge diffs:"] $err" @@ -6054,7 +6131,7 @@ proc gettreediffs {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} { @@ -6071,10 +6148,10 @@ proc gettreediffline {gdtf ids} { 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 } } @@ -6120,14 +6197,14 @@ proc getblobdiffs {ids} { global diffinhdr treediffs global diffcontext global ignorespace - global limitdiffs viewfiles curview + global limitdiffs vfilelimit curview set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] if {$ignorespace} { append cmd " -w" } - if {$limitdiffs && $viewfiles($curview) ne {}} { - set cmd [concat $cmd -- $viewfiles($curview)] + if {$limitdiffs && $vfilelimit($curview) ne {}} { + set cmd [concat $cmd -- $vfilelimit($curview)] } if {[catch {set bdf [open $cmd r]} err]} { puts "error getting diffs: $err" @@ -9266,7 +9343,6 @@ if {[catch {package require Tk 8.4} err]} { } # defaults... -set datemode 0 set wrcomcmd "git diff-tree --stdin -p --pretty" set gitencoding {} @@ -9357,7 +9433,6 @@ if {![file isdirectory $gitdir]} { exit 1 } -set mergeonly 0 set revtreeargs {} set cmdline_files {} set i 0 @@ -9365,11 +9440,6 @@ set revtreeargscmd {} foreach arg $argv { switch -glob -- $arg { "" { } - "-d" { set datemode 1 } - "--merge" { - set mergeonly 1 - lappend revtreeargs $arg - } "--" { set cmdline_files [lrange $argv [expr {$i + 1}] end] break @@ -9385,7 +9455,7 @@ foreach arg $argv { } 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"] @@ -9413,40 +9483,6 @@ if {$i >= [llength $argv] && $revtreeargs ne {}} { } } -if {$mergeonly} { - # find the list of unmerged files - set mlist {} - set nr_unmerged 0 - if {[catch { - set fd [open "| git ls-files -u" r] - } err]} { - show_error {} . "[mc "Couldn't get list of unmerged files:"] $err" - exit 1 - } - while {[gets $fd line] >= 0} { - set i [string first "\t" $line] - if {$i < 0} continue - set fname [string range $line [expr {$i+1}] end] - if {[lsearch -exact $mlist $fname] >= 0} continue - incr nr_unmerged - if {$cmdline_files eq {} || [path_filter $cmdline_files $fname]} { - lappend mlist $fname - } - } - catch {close $fd} - if {$mlist eq {}} { - if {$nr_unmerged == 0} { - show_error {} . [mc "No files selected: --merge specified but\ - no files are unmerged."] - } else { - show_error {} . [mc "No files selected: --merge specified but\ - no unmerged files are within file limit."] - } - exit 1 - } - set cmdline_files $mlist -} - set nullid "0000000000000000000000000000000000000000" set nullid2 "0000000000000000000000000000000000000001" @@ -9504,6 +9540,7 @@ if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} { set viewargs(1) $revtreeargs set viewargscmd(1) $revtreeargscmd set viewperm(1) 0 + set vdatemode(1) 0 addviewmenu 1 .bar.view entryconf [mc "Edit view..."] -state normal .bar.view entryconf [mc "Delete view"] -state normal