git-submodule: fix subcommand parser
The subcommand parser of "git submodule" made its subcommand names reserved words. As a consequence, a command like this: $ git submodule add init update which is meant to add a submodule called 'init' at path 'update' was misinterpreted as a request to invoke more than one mutually incompatible subcommands and incorrectly rejected. This patch fixes the issue by stopping the subcommand parsing at the first subcommand word, to allow the sample command line above to work as expected. It also introduces the usual -- option disambiguator, so that a submodule at path '-foo' can be updated with $ git submodule update -- -foo without triggering an "unrecognized option -foo" error. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano committed
Jan 15, 2008 at 02:48 UTC
5c08dbbdf1a2d2565606bb43f7e42a5968fcbdf1
1 file changed
+116
-41
git-submodule.sh
+116
-41
@@ -9,11 +9,8 @@ OPTIONS_SPEC=
9
. git-sh-setup
10
require_work_tree
11
12
-add=
12
+command=
13
branch=
14
-init=
15
-update=
16
-status=
14
quiet=
15
cached=
16
@@ -123,6 +120,32 @@ module_clone()
120
#
121
cmd_add()
122
{
123
+ # parse $args after "submodule ... add".
124
+ while test $# -ne 0
125
+ do
126
+ case "$1" in
127
+ -b | --branch)
128
+ case "$2" in '') usage ;; esac
129
+ branch=$2
130
+ shift
131
+ ;;
132
+ -q|--quiet)
133
+ quiet=1
134
+ ;;
135
+ --)
136
+ shift
137
+ break
138
+ ;;
139
+ -*)
140
+ usage
141
+ ;;
142
+ *)
143
+ break
144
+ ;;
145
+ esac
146
+ shift
147
+ done
148
+
149
repo=$1
150
path=$2
151
@@ -176,6 +199,27 @@ cmd_add()
199
#
200
cmd_init()
201
{
202
+ # parse $args after "submodule ... init".
203
+ while test $# -ne 0
204
+ do
205
+ case "$1" in
206
+ -q|--quiet)
207
+ quiet=1
208
+ ;;
209
+ --)
210
+ shift
211
+ break
212
+ ;;
213
+ -*)
214
+ usage
215
+ ;;
216
+ *)
217
+ break
218
+ ;;
219
+ esac
220
+ shift
221
+ done
222
+
223
git ls-files --stage -- "$@" | grep -e '^160000 ' |
224
while read mode sha1 stage path
225
do
@@ -209,6 +253,27 @@ cmd_init()
253
#
254
cmd_update()
255
{
256
+ # parse $args after "submodule ... update".
257
+ while test $# -ne 0
258
+ do
259
+ case "$1" in
260
+ -q|--quiet)
261
+ quiet=1
262
+ ;;
263
+ --)
264
+ shift
265
+ break
266
+ ;;
267
+ -*)
268
+ usage
269
+ ;;
270
+ *)
271
+ break
272
+ ;;
273
+ esac
274
+ shift
275
+ done
276
+
277
git ls-files --stage -- "$@" | grep -e '^160000 ' |
278
while read mode sha1 stage path
279
do
@@ -268,6 +333,30 @@ set_name_rev () {
333
#
334
cmd_status()
335
{
336
+ # parse $args after "submodule ... status".
337
+ while test $# -ne 0
338
+ do
339
+ case "$1" in
340
+ -q|--quiet)
341
+ quiet=1
342
+ ;;
343
+ --cached)
344
+ cached=1
345
+ ;;
346
+ --)
347
+ shift
348
+ break
349
+ ;;
350
+ -*)
351
+ usage
352
+ ;;
353
+ *)
354
+ break
355
+ ;;
356
+ esac
357
+ shift
358
+ done
359
+
360
git ls-files --stage -- "$@" | grep -e '^160000 ' |
361
while read mode sha1 stage path
362
do
@@ -293,20 +382,17 @@ cmd_status()
382
done
383
}
384
296
-while test $# != 0
385
+# This loop parses the command line arguments to find the
386
+# subcommand name to dispatch. Parsing of the subcommand specific
387
+# options are primarily done by the subcommand implementations.
388
+# Subcommand specific options such as --branch and --cached are
389
+# parsed here as well, for backward compatibility.
390
+
391
+while test $# != 0 && test -z "$command"
392
do
393
case "$1" in
299
- add)
300
- add=1
301
- ;;
302
- init)
303
- init=1
304
- ;;
305
- update)
306
- update=1
307
- ;;
308
- status)
309
- status=1
394
+ add | init | update | status)
395
+ command=$1
396
;;
397
-q|--quiet)
398
quiet=1
@@ -335,30 +421,19 @@ do
421
shift
422
done
423
338
-case "$add,$branch" in
339
-1,*)
340
- ;;
341
-,)
342
- ;;
343
-,*)
424
+# No command word defaults to "status"
425
+test -n "$command" || command=status
426
+
427
+# "-b branch" is accepted only by "add"
428
+if test -n "$branch" && test "$command" != add
429
+then
430
usage
345
- ;;
346
-esac
347
-
348
-case "$add,$init,$update,$status,$cached" in
349
-1,,,,)
350
- cmd_add "$@"
351
- ;;
352
-,1,,,)
353
- cmd_init "$@"
354
- ;;
355
-,,1,,)
356
- cmd_update "$@"
357
- ;;
358
-,,,*,*)
359
- cmd_status "$@"
360
- ;;
361
-*)
431
+fi
432
+
433
+# "--cached" is accepted only by "status"
434
+if test -n "$cached" && test "$command" != status
435
+then
436
usage
363
- ;;
364
-esac
437
+fi
438
+
439
+"cmd_$command" "$@"