Skip to content

Commit 5c08dbb

Browse files
committed
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>
1 parent 23a485e commit 5c08dbb

File tree

1 file changed

+116
-41
lines changed

1 file changed

+116
-41
lines changed

git-submodule.sh

Lines changed: 116 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,8 @@ OPTIONS_SPEC=
99
. git-sh-setup
1010
require_work_tree
1111

12-
add=
12+
command=
1313
branch=
14-
init=
15-
update=
16-
status=
1714
quiet=
1815
cached=
1916

@@ -123,6 +120,32 @@ module_clone()
123120
#
124121
cmd_add()
125122
{
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+
126149
repo=$1
127150
path=$2
128151

@@ -176,6 +199,27 @@ cmd_add()
176199
#
177200
cmd_init()
178201
{
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+
179223
git ls-files --stage -- "$@" | grep -e '^160000 ' |
180224
while read mode sha1 stage path
181225
do
@@ -209,6 +253,27 @@ cmd_init()
209253
#
210254
cmd_update()
211255
{
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+
212277
git ls-files --stage -- "$@" | grep -e '^160000 ' |
213278
while read mode sha1 stage path
214279
do
@@ -268,6 +333,30 @@ set_name_rev () {
268333
#
269334
cmd_status()
270335
{
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+
271360
git ls-files --stage -- "$@" | grep -e '^160000 ' |
272361
while read mode sha1 stage path
273362
do
@@ -293,20 +382,17 @@ cmd_status()
293382
done
294383
}
295384

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"
297392
do
298393
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
310396
;;
311397
-q|--quiet)
312398
quiet=1
@@ -335,30 +421,19 @@ do
335421
shift
336422
done
337423

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
344430
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
362436
usage
363-
;;
364-
esac
437+
fi
438+
439+
"cmd_$command" "$@"

0 commit comments

Comments
 (0)