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 <paulus@samba.org>
This commit is contained in:
Paul Mackerras 2008-04-26 16:00:00 +10:00
parent 92e22ca0a2
commit 3ed31a8120

191
gitk
View File

@ -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 # Start off a git log process and arrange to read its output
proc start_rev_list {view} { proc start_rev_list {view} {
global startmsecs global startmsecs commitidx viewcomplete
global commfd leftover tclencoding datemode global commfd leftover tclencoding
global viewargs viewargscmd viewfiles commitidx viewcomplete global viewargs viewargscmd vactualargs viewfiles vfilelimit
global showlocalchanges commitinterest mainheadid global showlocalchanges commitinterest mainheadid
global progressdirn progresscoords proglastnc curview global progressdirn progresscoords proglastnc curview
global viewactive loginstance viewinstances global viewactive loginstance viewinstances vmergeonly
global pending_select mainheadid global pending_select mainheadid
set startmsecs [clock clicks -milliseconds] set startmsecs [clock clicks -milliseconds]
set commitidx($view) 0 set commitidx($view) 0
set viewcomplete($view) 0 # these are set this way for the error exits
set viewactive($view) 1 set viewcomplete($view) 1
set viewactive($view) 0
varcinit $view varcinit $view
set args $viewargs($view) set args $viewargs($view)
@ -112,16 +163,36 @@ proc start_rev_list {view} {
set str [exec sh -c $viewargscmd($view)] set str [exec sh -c $viewargscmd($view)]
} err]} { } err]} {
error_popup "Error executing --argscmd command: $err" error_popup "Error executing --argscmd command: $err"
exit 1 return 0
} }
set args [concat $args [split $str "\n"]] 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 { if {[catch {
set fd [open [concat | git log --no-color -z --pretty=raw --parents \ set fd [open [concat | git log --no-color -z --pretty=raw --parents \
--boundary $args "--" $viewfiles($view)] r] --boundary $args "--" $files] r]
} err]} { } err]} {
error_popup "[mc "Error executing git log:"] $err" error_popup "[mc "Error executing git log:"] $err"
exit 1 return 0
} }
set i [incr loginstance] set i [incr loginstance]
set viewinstances($view) [list $i] set viewinstances($view) [list $i]
@ -142,6 +213,9 @@ proc start_rev_list {view} {
set proglastnc 0 set proglastnc 0
set pending_select $mainheadid set pending_select $mainheadid
} }
set viewcomplete($view) 0
set viewactive($view) 1
return 1
} }
proc stop_rev_list {view} { proc stop_rev_list {view} {
@ -162,16 +236,19 @@ proc stop_rev_list {view} {
} }
proc getcommits {} { proc getcommits {} {
global canv curview need_redisplay global canv curview need_redisplay viewactive
initlayout initlayout
start_rev_list $curview if {[start_rev_list $curview]} {
show_status [mc "Reading commits..."] show_status [mc "Reading commits..."]
set need_redisplay 1 set need_redisplay 1
} else {
show_status [mc "No commits selected"]
}
} }
proc updatecommits {} { proc updatecommits {} {
global curview viewargs viewfiles viewinstances global curview vactualargs vfilelimit viewinstances
global viewactive viewcomplete loginstance tclencoding mainheadid global viewactive viewcomplete loginstance tclencoding mainheadid
global startmsecs commfd showneartags showlocalchanges leftover global startmsecs commfd showneartags showlocalchanges leftover
global mainheadid pending_select global mainheadid pending_select
@ -191,8 +268,8 @@ proc updatecommits {} {
set view $curview set view $curview
if {[catch { if {[catch {
set fd [open [concat | git log --no-color -z --pretty=raw --parents \ set fd [open [concat | git log --no-color -z --pretty=raw --parents \
--boundary $viewargs($view) --not [seeds $view] \ --boundary $vactualargs($view) --not [seeds $view] \
"--" $viewfiles($view)] r] "--" $vfilelimit($view)] r]
} err]} { } err]} {
error_popup "Error executing git log: $err" error_popup "Error executing git log: $err"
exit 1 exit 1
@ -316,13 +393,13 @@ proc seeds {v} {
} }
proc newvarc {view id} { 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 vupptr vdownptr vleftptr vbackptr varcrow varcix varcstart
global commitdata commitinfo vseedcount varccommits vlastins global commitdata commitinfo vseedcount varccommits vlastins
set a [llength $varctok($view)] set a [llength $varctok($view)]
set vid $view,$id set vid $view,$id
if {[llength $children($vid)] == 0 || $datemode} { if {[llength $children($vid)] == 0 || $vdatemode($view)} {
if {![info exists commitinfo($id)]} { if {![info exists commitinfo($id)]} {
parsecommit $id $commitdata($id) 1 parsecommit $id $commitdata($id) 1
} }
@ -422,7 +499,7 @@ proc splitvarc {p v} {
proc renumbervarc {a v} { proc renumbervarc {a v} {
global parents children varctok varcstart varccommits 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 t1 [clock clicks -milliseconds]
set todo {} set todo {}
@ -458,7 +535,7 @@ proc renumbervarc {a v} {
$children($v,$id)] $children($v,$id)]
} }
set oldtok [lindex $varctok($v) $a] set oldtok [lindex $varctok($v) $a]
if {!$datemode} { if {!$vdatemode($v)} {
set tok {} set tok {}
} else { } else {
set tok $oldtok set tok $oldtok
@ -992,10 +1069,10 @@ proc rewrite_commit {v id rwid} {
proc getcommitlines {fd inst view updating} { proc getcommitlines {fd inst view updating} {
global cmitlisted commitinterest leftover global cmitlisted commitinterest leftover
global commitidx commitdata datemode global commitidx commitdata vdatemode
global parents children curview hlview global parents children curview hlview
global idpending ordertok global idpending ordertok
global varccommits varcid varctok vtokmod viewfiles global varccommits varcid varctok vtokmod vfilelimit
set stuff [read $fd 500000] set stuff [read $fd 500000]
# git log doesn't terminate the last commit with a null... # 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 set vid $view,$id
if {!$listed && $updating && ![info exists varcid($vid)] && if {!$listed && $updating && ![info exists varcid($vid)] &&
$viewfiles($view) ne {}} { $vfilelimit($view) ne {}} {
# git log doesn't rewrite parents for unlisted commits # git log doesn't rewrite parents for unlisted commits
# when doing path limiting, so work around that here # when doing path limiting, so work around that here
# by working out the rewritten parent with git rev-list # 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. # parent as a substitute parent for $id's children.
if {![catch { if {![catch {
set rwid [exec git rev-list --first-parent --max-count=1 \ 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)]} { if {$rwid ne {} && [info exists varcid($view,$rwid)]} {
# use $rwid in place of $id # use $rwid in place of $id
@ -1134,7 +1211,7 @@ proc getcommitlines {fd inst view updating} {
} elseif {$a == 0 && [llength $children($vid)] == 1} { } elseif {$a == 0 && [llength $children($vid)] == 1} {
set k [lindex $children($vid) 0] set k [lindex $children($vid) 0]
if {[llength $parents($view,$k)] == 1 && if {[llength $parents($view,$k)] == 1 &&
(!$datemode || (!$vdatemode($view) ||
$varcid($view,$k) == [llength $varctok($view)] - 1)} { $varcid($view,$k) == [llength $varctok($view)] - 1)} {
set a $varcid($view,$k) set a $varcid($view,$k)
} }
@ -2880,7 +2957,7 @@ proc addviewmenu {n} {
} }
proc showview {n} { proc showview {n} {
global curview viewfiles cached_commitrow ordertok global curview cached_commitrow ordertok
global displayorder parentlist rowidlist rowisopt rowfinal global displayorder parentlist rowidlist rowisopt rowfinal
global colormap rowtextx nextcolor canvxmax global colormap rowtextx nextcolor canvxmax
global numcommits viewcomplete global numcommits viewcomplete
@ -5869,14 +5946,14 @@ proc mergediff {id} {
global diffids global diffids
global parents global parents
global diffcontext global diffcontext
global limitdiffs viewfiles curview global limitdiffs vfilelimit curview
set diffmergeid $id set diffmergeid $id
set diffids $id set diffids $id
# this doesn't seem to actually affect anything... # this doesn't seem to actually affect anything...
set cmd [concat | git diff-tree --no-commit-id --cc -U$diffcontext $id] set cmd [concat | git diff-tree --no-commit-id --cc -U$diffcontext $id]
if {$limitdiffs && $viewfiles($curview) ne {}} { if {$limitdiffs && $vfilelimit($curview) ne {}} {
set cmd [concat $cmd -- $viewfiles($curview)] set cmd [concat $cmd -- $vfilelimit($curview)]
} }
if {[catch {set mdf [open $cmd r]} err]} { if {[catch {set mdf [open $cmd r]} err]} {
error_popup "[mc "Error getting merge diffs:"] $err" error_popup "[mc "Error getting merge diffs:"] $err"
@ -6054,7 +6131,7 @@ proc gettreediffs {ids} {
proc gettreediffline {gdtf ids} { proc gettreediffline {gdtf ids} {
global treediff treediffs treepending diffids diffmergeid global treediff treediffs treepending diffids diffmergeid
global cmitmode viewfiles curview limitdiffs global cmitmode vfilelimit curview limitdiffs
set nr 0 set nr 0
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} { while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
@ -6071,10 +6148,10 @@ proc gettreediffline {gdtf ids} {
return [expr {$nr >= 1000? 2: 1}] return [expr {$nr >= 1000? 2: 1}]
} }
close $gdtf close $gdtf
if {$limitdiffs && $viewfiles($curview) ne {}} { if {$limitdiffs && $vfilelimit($curview) ne {}} {
set flist {} set flist {}
foreach f $treediff { foreach f $treediff {
if {[path_filter $viewfiles($curview) $f]} { if {[path_filter $vfilelimit($curview) $f]} {
lappend flist $f lappend flist $f
} }
} }
@ -6120,14 +6197,14 @@ proc getblobdiffs {ids} {
global diffinhdr treediffs global diffinhdr treediffs
global diffcontext global diffcontext
global ignorespace global ignorespace
global limitdiffs viewfiles curview global limitdiffs vfilelimit curview
set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"] set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"]
if {$ignorespace} { if {$ignorespace} {
append cmd " -w" append cmd " -w"
} }
if {$limitdiffs && $viewfiles($curview) ne {}} { if {$limitdiffs && $vfilelimit($curview) ne {}} {
set cmd [concat $cmd -- $viewfiles($curview)] set cmd [concat $cmd -- $vfilelimit($curview)]
} }
if {[catch {set bdf [open $cmd r]} err]} { if {[catch {set bdf [open $cmd r]} err]} {
puts "error getting diffs: $err" puts "error getting diffs: $err"
@ -9266,7 +9343,6 @@ if {[catch {package require Tk 8.4} err]} {
} }
# defaults... # defaults...
set datemode 0
set wrcomcmd "git diff-tree --stdin -p --pretty" set wrcomcmd "git diff-tree --stdin -p --pretty"
set gitencoding {} set gitencoding {}
@ -9357,7 +9433,6 @@ if {![file isdirectory $gitdir]} {
exit 1 exit 1
} }
set mergeonly 0
set revtreeargs {} set revtreeargs {}
set cmdline_files {} set cmdline_files {}
set i 0 set i 0
@ -9365,11 +9440,6 @@ set revtreeargscmd {}
foreach arg $argv { foreach arg $argv {
switch -glob -- $arg { switch -glob -- $arg {
"" { } "" { }
"-d" { set datemode 1 }
"--merge" {
set mergeonly 1
lappend revtreeargs $arg
}
"--" { "--" {
set cmdline_files [lrange $argv [expr {$i + 1}] end] set cmdline_files [lrange $argv [expr {$i + 1}] end]
break break
@ -9385,7 +9455,7 @@ foreach arg $argv {
} }
if {$i >= [llength $argv] && $revtreeargs ne {}} { 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 { if {[catch {
set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs] set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
set cmdline_files [split $f "\n"] 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 nullid "0000000000000000000000000000000000000000"
set nullid2 "0000000000000000000000000000000000000001" set nullid2 "0000000000000000000000000000000000000001"
@ -9504,6 +9540,7 @@ if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} {
set viewargs(1) $revtreeargs set viewargs(1) $revtreeargs
set viewargscmd(1) $revtreeargscmd set viewargscmd(1) $revtreeargscmd
set viewperm(1) 0 set viewperm(1) 0
set vdatemode(1) 0
addviewmenu 1 addviewmenu 1
.bar.view entryconf [mc "Edit view..."] -state normal .bar.view entryconf [mc "Edit view..."] -state normal
.bar.view entryconf [mc "Delete view"] -state normal .bar.view entryconf [mc "Delete view"] -state normal