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>
Paul Mackerras committed
Apr 26, 2008 at 16:00 UTC
3ed31a8120ec78c495206c89cf5d421d9198f847
1 file changed
+114
-77
gitk
+114
-77
@@ -90,20 +90,71 @@ proc dorunq {} {
90
}
91
}
92
93
+proc unmerged_files {files} {
94
+ global nr_unmerged
95
+
96
+ # find the list of unmerged files
97
+ set mlist {}
98
+ set nr_unmerged 0
99
+ if {[catch {
100
+ set fd [open "| git ls-files -u" r]
101
+ } err]} {
102
+ show_error {} . "[mc "Couldn't get list of unmerged files:"] $err"
103
+ exit 1
104
+ }
105
+ while {[gets $fd line] >= 0} {
106
+ set i [string first "\t" $line]
107
+ if {$i < 0} continue
108
+ set fname [string range $line [expr {$i+1}] end]
109
+ if {[lsearch -exact $mlist $fname] >= 0} continue
110
+ incr nr_unmerged
111
+ if {$files eq {} || [path_filter $files $fname]} {
112
+ lappend mlist $fname
113
+ }
114
+ }
115
+ catch {close $fd}
116
+ return $mlist
117
+}
118
+
119
+proc parseviewargs {n arglist} {
120
+ global viewargs vdatemode vmergeonly
121
+
122
+ set vdatemode($n) 0
123
+ set vmergeonly($n) 0
124
+ set glargs {}
125
+ foreach arg $viewargs($n) {
126
+ switch -glob -- $arg {
127
+ "-d" -
128
+ "--date-order" {
129
+ set vdatemode($n) 1
130
+ }
131
+ "--merge" {
132
+ set vmergeonly($n) 1
133
+ lappend glargs $arg
134
+ }
135
+ default {
136
+ lappend glargs $arg
137
+ }
138
+ }
139
+ }
140
+ return $glargs
141
+}
142
+
143
# Start off a git log process and arrange to read its output
144
proc start_rev_list {view} {
95
- global startmsecs
96
- global commfd leftover tclencoding datemode
97
- global viewargs viewargscmd viewfiles commitidx viewcomplete
145
+ global startmsecs commitidx viewcomplete
146
+ global commfd leftover tclencoding
147
+ global viewargs viewargscmd vactualargs viewfiles vfilelimit
148
global showlocalchanges commitinterest mainheadid
149
global progressdirn progresscoords proglastnc curview
100
- global viewactive loginstance viewinstances
150
+ global viewactive loginstance viewinstances vmergeonly
151
global pending_select mainheadid
152
153
set startmsecs [clock clicks -milliseconds]
154
set commitidx($view) 0
105
- set viewcomplete($view) 0
106
- set viewactive($view) 1
155
+ # these are set this way for the error exits
156
+ set viewcomplete($view) 1
157
+ set viewactive($view) 0
158
varcinit $view
159
160
set args $viewargs($view)
@@ -112,16 +163,36 @@ proc start_rev_list {view} {
163
set str [exec sh -c $viewargscmd($view)]
164
} err]} {
165
error_popup "Error executing --argscmd command: $err"
115
- exit 1
166
+ return 0
167
}
168
set args [concat $args [split $str "\n"]]
169
}
170
+ set args [parseviewargs $view $args]
171
+ set vactualargs($view) $args
172
+
173
+ set files $viewfiles($view)
174
+ if {$vmergeonly($view)} {
175
+ set files [unmerged_files $files]
176
+ if {$files eq {}} {
177
+ global nr_unmerged
178
+ if {$nr_unmerged == 0} {
179
+ error_popup [mc "No files selected: --merge specified but\
180
+ no files are unmerged."]
181
+ } else {
182
+ error_popup [mc "No files selected: --merge specified but\
183
+ no unmerged files are within file limit."]
184
+ }
185
+ return 0
186
+ }
187
+ }
188
+ set vfilelimit($view) $files
189
+
190
if {[catch {
191
set fd [open [concat | git log --no-color -z --pretty=raw --parents \
121
- --boundary $args "--" $viewfiles($view)] r]
192
+ --boundary $args "--" $files] r]
193
} err]} {
194
error_popup "[mc "Error executing git log:"] $err"
124
- exit 1
195
+ return 0
196
}
197
set i [incr loginstance]
198
set viewinstances($view) [list $i]
@@ -142,6 +213,9 @@ proc start_rev_list {view} {
213
set proglastnc 0
214
set pending_select $mainheadid
215
}
216
+ set viewcomplete($view) 0
217
+ set viewactive($view) 1
218
+ return 1
219
}
220
221
proc stop_rev_list {view} {
@@ -162,16 +236,19 @@ proc stop_rev_list {view} {
236
}
237
238
proc getcommits {} {
165
- global canv curview need_redisplay
239
+ global canv curview need_redisplay viewactive
240
241
initlayout
168
- start_rev_list $curview
169
- show_status [mc "Reading commits..."]
170
- set need_redisplay 1
242
+ if {[start_rev_list $curview]} {
243
+ show_status [mc "Reading commits..."]
244
+ set need_redisplay 1
245
+ } else {
246
+ show_status [mc "No commits selected"]
247
+ }
248
}
249
250
proc updatecommits {} {
174
- global curview viewargs viewfiles viewinstances
251
+ global curview vactualargs vfilelimit viewinstances
252
global viewactive viewcomplete loginstance tclencoding mainheadid
253
global startmsecs commfd showneartags showlocalchanges leftover
254
global mainheadid pending_select
@@ -191,8 +268,8 @@ proc updatecommits {} {
268
set view $curview
269
if {[catch {
270
set fd [open [concat | git log --no-color -z --pretty=raw --parents \
194
- --boundary $viewargs($view) --not [seeds $view] \
195
- "--" $viewfiles($view)] r]
271
+ --boundary $vactualargs($view) --not [seeds $view] \
272
+ "--" $vfilelimit($view)] r]
273
} err]} {
274
error_popup "Error executing git log: $err"
275
exit 1
@@ -316,13 +393,13 @@ proc seeds {v} {
393
}
394
395
proc newvarc {view id} {
319
- global varcid varctok parents children datemode
396
+ global varcid varctok parents children vdatemode
397
global vupptr vdownptr vleftptr vbackptr varcrow varcix varcstart
398
global commitdata commitinfo vseedcount varccommits vlastins
399
400
set a [llength $varctok($view)]
401
set vid $view,$id
325
- if {[llength $children($vid)] == 0 || $datemode} {
402
+ if {[llength $children($vid)] == 0 || $vdatemode($view)} {
403
if {![info exists commitinfo($id)]} {
404
parsecommit $id $commitdata($id) 1
405
}
@@ -422,7 +499,7 @@ proc splitvarc {p v} {
499
500
proc renumbervarc {a v} {
501
global parents children varctok varcstart varccommits
425
- global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod datemode
502
+ global vupptr vdownptr vleftptr vbackptr vlastins varcid vtokmod vdatemode
503
504
set t1 [clock clicks -milliseconds]
505
set todo {}
@@ -458,7 +535,7 @@ proc renumbervarc {a v} {
535
$children($v,$id)]
536
}
537
set oldtok [lindex $varctok($v) $a]
461
- if {!$datemode} {
538
+ if {!$vdatemode($v)} {
539
set tok {}
540
} else {
541
set tok $oldtok
@@ -992,10 +1069,10 @@ proc rewrite_commit {v id rwid} {
1069
1070
proc getcommitlines {fd inst view updating} {
1071
global cmitlisted commitinterest leftover
995
- global commitidx commitdata datemode
1072
+ global commitidx commitdata vdatemode
1073
global parents children curview hlview
1074
global idpending ordertok
998
- global varccommits varcid varctok vtokmod viewfiles
1075
+ global varccommits varcid varctok vtokmod vfilelimit
1076
1077
set stuff [read $fd 500000]
1078
# git log doesn't terminate the last commit with a null...
@@ -1098,7 +1175,7 @@ proc getcommitlines {fd inst view updating} {
1175
set vid $view,$id
1176
1177
if {!$listed && $updating && ![info exists varcid($vid)] &&
1101
- $viewfiles($view) ne {}} {
1178
+ $vfilelimit($view) ne {}} {
1179
# git log doesn't rewrite parents for unlisted commits
1180
# when doing path limiting, so work around that here
1181
# by working out the rewritten parent with git rev-list
@@ -1106,7 +1183,7 @@ proc getcommitlines {fd inst view updating} {
1183
# parent as a substitute parent for $id's children.
1184
if {![catch {
1185
set rwid [exec git rev-list --first-parent --max-count=1 \
1109
- $id -- $viewfiles($view)]
1186
+ $id -- $vfilelimit($view)]
1187
}]} {
1188
if {$rwid ne {} && [info exists varcid($view,$rwid)]} {
1189
# use $rwid in place of $id
@@ -1134,7 +1211,7 @@ proc getcommitlines {fd inst view updating} {
1211
} elseif {$a == 0 && [llength $children($vid)] == 1} {
1212
set k [lindex $children($vid) 0]
1213
if {[llength $parents($view,$k)] == 1 &&
1137
- (!$datemode ||
1214
+ (!$vdatemode($view) ||
1215
$varcid($view,$k) == [llength $varctok($view)] - 1)} {
1216
set a $varcid($view,$k)
1217
}
@@ -2880,7 +2957,7 @@ proc addviewmenu {n} {
2957
}
2958
2959
proc showview {n} {
2883
- global curview viewfiles cached_commitrow ordertok
2960
+ global curview cached_commitrow ordertok
2961
global displayorder parentlist rowidlist rowisopt rowfinal
2962
global colormap rowtextx nextcolor canvxmax
2963
global numcommits viewcomplete
@@ -5869,14 +5946,14 @@ proc mergediff {id} {
5946
global diffids
5947
global parents
5948
global diffcontext
5872
- global limitdiffs viewfiles curview
5949
+ global limitdiffs vfilelimit curview
5950
5951
set diffmergeid $id
5952
set diffids $id
5953
# this doesn't seem to actually affect anything...
5954
set cmd [concat | git diff-tree --no-commit-id --cc -U$diffcontext $id]
5878
- if {$limitdiffs && $viewfiles($curview) ne {}} {
5879
- set cmd [concat $cmd -- $viewfiles($curview)]
5955
+ if {$limitdiffs && $vfilelimit($curview) ne {}} {
5956
+ set cmd [concat $cmd -- $vfilelimit($curview)]
5957
}
5958
if {[catch {set mdf [open $cmd r]} err]} {
5959
error_popup "[mc "Error getting merge diffs:"] $err"
@@ -6054,7 +6131,7 @@ proc gettreediffs {ids} {
6131
6132
proc gettreediffline {gdtf ids} {
6133
global treediff treediffs treepending diffids diffmergeid
6057
- global cmitmode viewfiles curview limitdiffs
6134
+ global cmitmode vfilelimit curview limitdiffs
6135
6136
set nr 0
6137
while {[incr nr] <= 1000 && [gets $gdtf line] >= 0} {
@@ -6071,10 +6148,10 @@ proc gettreediffline {gdtf ids} {
6148
return [expr {$nr >= 1000? 2: 1}]
6149
}
6150
close $gdtf
6074
- if {$limitdiffs && $viewfiles($curview) ne {}} {
6151
+ if {$limitdiffs && $vfilelimit($curview) ne {}} {
6152
set flist {}
6153
foreach f $treediff {
6077
- if {[path_filter $viewfiles($curview) $f]} {
6154
+ if {[path_filter $vfilelimit($curview) $f]} {
6155
lappend flist $f
6156
}
6157
}
@@ -6120,14 +6197,14 @@ proc getblobdiffs {ids} {
6197
global diffinhdr treediffs
6198
global diffcontext
6199
global ignorespace
6123
- global limitdiffs viewfiles curview
6200
+ global limitdiffs vfilelimit curview
6201
6202
set cmd [diffcmd $ids "-p -C --no-commit-id -U$diffcontext"]
6203
if {$ignorespace} {
6204
append cmd " -w"
6205
}
6129
- if {$limitdiffs && $viewfiles($curview) ne {}} {
6130
- set cmd [concat $cmd -- $viewfiles($curview)]
6206
+ if {$limitdiffs && $vfilelimit($curview) ne {}} {
6207
+ set cmd [concat $cmd -- $vfilelimit($curview)]
6208
}
6209
if {[catch {set bdf [open $cmd r]} err]} {
6210
puts "error getting diffs: $err"
@@ -9266,7 +9343,6 @@ if {[catch {package require Tk 8.4} err]} {
9343
}
9344
9345
# defaults...
9269
-set datemode 0
9346
set wrcomcmd "git diff-tree --stdin -p --pretty"
9347
9348
set gitencoding {}
@@ -9357,7 +9433,6 @@ if {![file isdirectory $gitdir]} {
9433
exit 1
9434
}
9435
9360
-set mergeonly 0
9436
set revtreeargs {}
9437
set cmdline_files {}
9438
set i 0
@@ -9365,11 +9440,6 @@ set revtreeargscmd {}
9440
foreach arg $argv {
9441
switch -glob -- $arg {
9442
"" { }
9368
- "-d" { set datemode 1 }
9369
- "--merge" {
9370
- set mergeonly 1
9371
- lappend revtreeargs $arg
9372
- }
9443
"--" {
9444
set cmdline_files [lrange $argv [expr {$i + 1}] end]
9445
break
@@ -9385,7 +9455,7 @@ foreach arg $argv {
9455
}
9456
9457
if {$i >= [llength $argv] && $revtreeargs ne {}} {
9388
- # no -- on command line, but some arguments (other than -d)
9458
+ # no -- on command line, but some arguments (other than --argscmd)
9459
if {[catch {
9460
set f [eval exec git rev-parse --no-revs --no-flags $revtreeargs]
9461
set cmdline_files [split $f "\n"]
@@ -9413,40 +9483,6 @@ if {$i >= [llength $argv] && $revtreeargs ne {}} {
9483
}
9484
}
9485
9416
-if {$mergeonly} {
9417
- # find the list of unmerged files
9418
- set mlist {}
9419
- set nr_unmerged 0
9420
- if {[catch {
9421
- set fd [open "| git ls-files -u" r]
9422
- } err]} {
9423
- show_error {} . "[mc "Couldn't get list of unmerged files:"] $err"
9424
- exit 1
9425
- }
9426
- while {[gets $fd line] >= 0} {
9427
- set i [string first "\t" $line]
9428
- if {$i < 0} continue
9429
- set fname [string range $line [expr {$i+1}] end]
9430
- if {[lsearch -exact $mlist $fname] >= 0} continue
9431
- incr nr_unmerged
9432
- if {$cmdline_files eq {} || [path_filter $cmdline_files $fname]} {
9433
- lappend mlist $fname
9434
- }
9435
- }
9436
- catch {close $fd}
9437
- if {$mlist eq {}} {
9438
- if {$nr_unmerged == 0} {
9439
- show_error {} . [mc "No files selected: --merge specified but\
9440
- no files are unmerged."]
9441
- } else {
9442
- show_error {} . [mc "No files selected: --merge specified but\
9443
- no unmerged files are within file limit."]
9444
- }
9445
- exit 1
9446
- }
9447
- set cmdline_files $mlist
9448
-}
9449
-
9486
set nullid "0000000000000000000000000000000000000000"
9487
set nullid2 "0000000000000000000000000000000000000001"
9488
@@ -9504,6 +9540,7 @@ if {$cmdline_files ne {} || $revtreeargs ne {} || $revtreeargscmd ne {}} {
9540
set viewargs(1) $revtreeargs
9541
set viewargscmd(1) $revtreeargscmd
9542
set viewperm(1) 0
9543
+ set vdatemode(1) 0
9544
addviewmenu 1
9545
.bar.view entryconf [mc "Edit view..."] -state normal
9546
.bar.view entryconf [mc "Delete view"] -state normal