Merge branch 'ab/config-based-hooks-base' into seen
[git] / git-submodule.sh
1 #!/bin/sh
2 #
3 # git-submodule.sh: add, init, update or list git submodules
4 #
5 # Copyright (c) 2007 Lars Hjemli
6
7 dashless=$(basename "$0" | sed -e 's/-/ /')
8 USAGE="[--quiet] [--cached]
9    or: $dashless [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
10    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
11    or: $dashless [--quiet] init [--] [<path>...]
12    or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
13    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] [--] [<path>...]
14    or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
15    or: $dashless [--quiet] set-url [--] <path> <newurl>
16    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
17    or: $dashless [--quiet] foreach [--recursive] <command>
18    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
19    or: $dashless [--quiet] absorbgitdirs [--] [<path>...]"
20 OPTIONS_SPEC=
21 SUBDIRECTORY_OK=Yes
22 . git-sh-setup
23 require_work_tree
24 wt_prefix=$(git rev-parse --show-prefix)
25 cd_to_toplevel
26
27 # Tell the rest of git that any URLs we get don't come
28 # directly from the user, so it can apply policy as appropriate.
29 GIT_PROTOCOL_FROM_USER=0
30 export GIT_PROTOCOL_FROM_USER
31
32 command=
33 branch=
34 force=
35 reference=
36 cached=
37 recursive=
38 init=
39 require_init=
40 files=
41 remote=
42 nofetch=
43 update=
44 prefix=
45 custom_name=
46 depth=
47 progress=
48 dissociate=
49 single_branch=
50 jobs=
51 recommend_shallow=
52
53 die_if_unmatched ()
54 {
55         if test "$1" = "#unmatched"
56         then
57                 exit ${2:-1}
58         fi
59 }
60
61 isnumber()
62 {
63         n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
64 }
65
66 # Given a full hex object ID, is this the zero OID?
67 is_zero_oid () {
68         echo "$1" | sane_egrep '^0+$' >/dev/null 2>&1
69 }
70
71 # Sanitize the local git environment for use within a submodule. We
72 # can't simply use clear_local_git_env since we want to preserve some
73 # of the settings from GIT_CONFIG_PARAMETERS.
74 sanitize_submodule_env()
75 {
76         save_config=$GIT_CONFIG_PARAMETERS
77         clear_local_git_env
78         GIT_CONFIG_PARAMETERS=$save_config
79         export GIT_CONFIG_PARAMETERS
80 }
81
82 #
83 # Add a new submodule to the working tree, .gitmodules and the index
84 #
85 # $@ = repo path
86 #
87 # optional branch is stored in global branch variable
88 #
89 cmd_add()
90 {
91         # parse $args after "submodule ... add".
92         reference_path=
93         while test $# -ne 0
94         do
95                 case "$1" in
96                 -b | --branch)
97                         case "$2" in '') usage ;; esac
98                         branch=$2
99                         shift
100                         ;;
101                 -f | --force)
102                         force=$1
103                         ;;
104                 -q|--quiet)
105                         GIT_QUIET=1
106                         ;;
107                 --progress)
108                         progress=1
109                         ;;
110                 --reference)
111                         case "$2" in '') usage ;; esac
112                         reference_path=$2
113                         shift
114                         ;;
115                 --reference=*)
116                         reference_path="${1#--reference=}"
117                         ;;
118                 --dissociate)
119                         dissociate=1
120                         ;;
121                 --name)
122                         case "$2" in '') usage ;; esac
123                         custom_name=$2
124                         shift
125                         ;;
126                 --depth)
127                         case "$2" in '') usage ;; esac
128                         depth="--depth=$2"
129                         shift
130                         ;;
131                 --depth=*)
132                         depth=$1
133                         ;;
134                 --)
135                         shift
136                         break
137                         ;;
138                 -*)
139                         usage
140                         ;;
141                 *)
142                         break
143                         ;;
144                 esac
145                 shift
146         done
147
148         if ! git submodule--helper config --check-writeable >/dev/null 2>&1
149         then
150                  die "$(eval_gettext "please make sure that the .gitmodules file is in the working tree")"
151         fi
152
153         if test -n "$reference_path"
154         then
155                 is_absolute_path "$reference_path" ||
156                 reference_path="$wt_prefix$reference_path"
157
158                 reference="--reference=$reference_path"
159         fi
160
161         repo=$1
162         sm_path=$2
163
164         if test -z "$sm_path"; then
165                 sm_path=$(printf '%s\n' "$repo" |
166                         sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
167         fi
168
169         if test -z "$repo" || test -z "$sm_path"; then
170                 usage
171         fi
172
173         is_absolute_path "$sm_path" || sm_path="$wt_prefix$sm_path"
174
175         # assure repo is absolute or relative to parent
176         case "$repo" in
177         ./*|../*)
178                 test -z "$wt_prefix" ||
179                 die "$(gettext "Relative path can only be used from the toplevel of the working tree")"
180
181                 # dereference source url relative to parent's url
182                 realrepo=$(git submodule--helper resolve-relative-url "$repo") || exit
183                 ;;
184         *:*|/*)
185                 # absolute url
186                 realrepo=$repo
187                 ;;
188         *)
189                 die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
190         ;;
191         esac
192
193         # normalize path:
194         # multiple //; leading ./; /./; /../; trailing /
195         sm_path=$(printf '%s/\n' "$sm_path" |
196                 sed -e '
197                         s|//*|/|g
198                         s|^\(\./\)*||
199                         s|/\(\./\)*|/|g
200                         :start
201                         s|\([^/]*\)/\.\./||
202                         tstart
203                         s|/*$||
204                 ')
205         if test -z "$force"
206         then
207                 git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
208                 die "$(eval_gettext "'\$sm_path' already exists in the index")"
209         else
210                 git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
211                 die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
212         fi
213
214         if test -d "$sm_path" &&
215                 test -z $(git -C "$sm_path" rev-parse --show-cdup 2>/dev/null)
216         then
217             git -C "$sm_path" rev-parse --verify -q HEAD >/dev/null ||
218             die "$(eval_gettext "'\$sm_path' does not have a commit checked out")"
219         fi
220
221         if test -z "$force"
222         then
223             dryerr=$(git add --dry-run --ignore-missing --no-warn-embedded-repo "$sm_path" 2>&1 >/dev/null)
224             res=$?
225             if test $res -ne 0
226             then
227                  echo >&2 "$dryerr"
228                  exit $res
229             fi
230         fi
231
232         if test -n "$custom_name"
233         then
234                 sm_name="$custom_name"
235         else
236                 sm_name="$sm_path"
237         fi
238
239         if ! git submodule--helper check-name "$sm_name"
240         then
241                 die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
242         fi
243
244         git submodule--helper add-clone ${GIT_QUIET:+--quiet} ${force:+"--force"} ${progress:+"--progress"} ${branch:+--branch "$branch"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
245         git submodule--helper add-config ${force:+--force} ${branch:+--branch "$branch"} --url "$repo" --resolved-url "$realrepo" --path "$sm_path" --name "$sm_name"
246 }
247
248 #
249 # Execute an arbitrary command sequence in each checked out
250 # submodule
251 #
252 # $@ = command to execute
253 #
254 cmd_foreach()
255 {
256         # parse $args after "submodule ... foreach".
257         while test $# -ne 0
258         do
259                 case "$1" in
260                 -q|--quiet)
261                         GIT_QUIET=1
262                         ;;
263                 --recursive)
264                         recursive=1
265                         ;;
266                 -*)
267                         usage
268                         ;;
269                 *)
270                         break
271                         ;;
272                 esac
273                 shift
274         done
275
276         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
277 }
278
279 #
280 # Register submodules in .git/config
281 #
282 # $@ = requested paths (default to all)
283 #
284 cmd_init()
285 {
286         # parse $args after "submodule ... init".
287         while test $# -ne 0
288         do
289                 case "$1" in
290                 -q|--quiet)
291                         GIT_QUIET=1
292                         ;;
293                 --)
294                         shift
295                         break
296                         ;;
297                 -*)
298                         usage
299                         ;;
300                 *)
301                         break
302                         ;;
303                 esac
304                 shift
305         done
306
307         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper init ${GIT_QUIET:+--quiet} -- "$@"
308 }
309
310 #
311 # Unregister submodules from .git/config and remove their work tree
312 #
313 cmd_deinit()
314 {
315         # parse $args after "submodule ... deinit".
316         deinit_all=
317         while test $# -ne 0
318         do
319                 case "$1" in
320                 -f|--force)
321                         force=$1
322                         ;;
323                 -q|--quiet)
324                         GIT_QUIET=1
325                         ;;
326                 --all)
327                         deinit_all=t
328                         ;;
329                 --)
330                         shift
331                         break
332                         ;;
333                 -*)
334                         usage
335                         ;;
336                 *)
337                         break
338                         ;;
339                 esac
340                 shift
341         done
342
343         git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} ${force:+--force} ${deinit_all:+--all} -- "$@"
344 }
345
346 is_tip_reachable () (
347         sanitize_submodule_env &&
348         cd "$1" &&
349         rev=$(git rev-list -n 1 "$2" --not --all 2>/dev/null) &&
350         test -z "$rev"
351 )
352
353 # usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]
354 # Because arguments are positional, use an empty string to omit <depth>
355 # but include <sha1>.
356 fetch_in_submodule () (
357         sanitize_submodule_env &&
358         cd "$1" &&
359         if test $# -eq 3
360         then
361                 echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"}
362         else
363                 git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"}
364         fi
365 )
366
367 #
368 # Update each submodule path to correct revision, using clone and checkout as needed
369 #
370 # $@ = requested paths (default to all)
371 #
372 cmd_update()
373 {
374         # parse $args after "submodule ... update".
375         while test $# -ne 0
376         do
377                 case "$1" in
378                 -q|--quiet)
379                         GIT_QUIET=1
380                         ;;
381                 -v)
382                         unset GIT_QUIET
383                         ;;
384                 --progress)
385                         progress=1
386                         ;;
387                 -i|--init)
388                         init=1
389                         ;;
390                 --require-init)
391                         init=1
392                         require_init=1
393                         ;;
394                 --remote)
395                         remote=1
396                         ;;
397                 -N|--no-fetch)
398                         nofetch=1
399                         ;;
400                 -f|--force)
401                         force=$1
402                         ;;
403                 -r|--rebase)
404                         update="rebase"
405                         ;;
406                 --reference)
407                         case "$2" in '') usage ;; esac
408                         reference="--reference=$2"
409                         shift
410                         ;;
411                 --reference=*)
412                         reference="$1"
413                         ;;
414                 --dissociate)
415                         dissociate=1
416                         ;;
417                 -m|--merge)
418                         update="merge"
419                         ;;
420                 --recursive)
421                         recursive=1
422                         ;;
423                 --checkout)
424                         update="checkout"
425                         ;;
426                 --recommend-shallow)
427                         recommend_shallow="--recommend-shallow"
428                         ;;
429                 --no-recommend-shallow)
430                         recommend_shallow="--no-recommend-shallow"
431                         ;;
432                 --depth)
433                         case "$2" in '') usage ;; esac
434                         depth="--depth=$2"
435                         shift
436                         ;;
437                 --depth=*)
438                         depth=$1
439                         ;;
440                 -j|--jobs)
441                         case "$2" in '') usage ;; esac
442                         jobs="--jobs=$2"
443                         shift
444                         ;;
445                 --jobs=*)
446                         jobs=$1
447                         ;;
448                 --single-branch)
449                         single_branch="--single-branch"
450                         ;;
451                 --no-single-branch)
452                         single_branch="--no-single-branch"
453                         ;;
454                 --)
455                         shift
456                         break
457                         ;;
458                 -*)
459                         usage
460                         ;;
461                 *)
462                         break
463                         ;;
464                 esac
465                 shift
466         done
467
468         if test -n "$init"
469         then
470                 cmd_init "--" "$@" || return
471         fi
472
473         {
474         git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
475                 ${progress:+"--progress"} \
476                 ${wt_prefix:+--prefix "$wt_prefix"} \
477                 ${prefix:+--recursive-prefix "$prefix"} \
478                 ${update:+--update "$update"} \
479                 ${reference:+"$reference"} \
480                 ${dissociate:+"--dissociate"} \
481                 ${depth:+--depth "$depth"} \
482                 ${require_init:+--require-init} \
483                 $single_branch \
484                 $recommend_shallow \
485                 $jobs \
486                 -- \
487                 "$@" || echo "#unmatched" $?
488         } | {
489         err=
490         while read -r quickabort sha1 just_cloned sm_path
491         do
492                 die_if_unmatched "$quickabort" "$sha1"
493
494                 git submodule--helper ensure-core-worktree "$sm_path" || exit 1
495
496                 update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update)
497
498                 displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
499
500                 if test $just_cloned -eq 1
501                 then
502                         subsha1=
503                 else
504                         subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
505                                 git rev-parse --verify HEAD) ||
506                         die "$(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")"
507                 fi
508
509                 if test -n "$remote"
510                 then
511                         branch=$(git submodule--helper remote-branch "$sm_path")
512                         if test -z "$nofetch"
513                         then
514                                 # Fetch remote before determining tracking $sha1
515                                 fetch_in_submodule "$sm_path" $depth ||
516                                 die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
517                         fi
518                         remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote)
519                         sha1=$(sanitize_submodule_env; cd "$sm_path" &&
520                                 git rev-parse --verify "${remote_name}/${branch}") ||
521                         die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
522                 fi
523
524                 if test "$subsha1" != "$sha1" || test -n "$force"
525                 then
526                         subforce=$force
527                         # If we don't already have a -f flag and the submodule has never been checked out
528                         if test -z "$subsha1" && test -z "$force"
529                         then
530                                 subforce="-f"
531                         fi
532
533                         if test -z "$nofetch"
534                         then
535                                 # Run fetch only if $sha1 isn't present or it
536                                 # is not reachable from a ref.
537                                 is_tip_reachable "$sm_path" "$sha1" ||
538                                 fetch_in_submodule "$sm_path" $depth ||
539                                 say "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'; trying to directly fetch \$sha1:")"
540
541                                 # Now we tried the usual fetch, but $sha1 may
542                                 # not be reachable from any of the refs
543                                 is_tip_reachable "$sm_path" "$sha1" ||
544                                 fetch_in_submodule "$sm_path" "$depth" "$sha1" ||
545                                 die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")"
546                         fi
547
548                         must_die_on_failure=
549                         case "$update_module" in
550                         checkout)
551                                 command="git checkout $subforce -q"
552                                 die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")"
553                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")"
554                                 ;;
555                         rebase)
556                                 command="git rebase ${GIT_QUIET:+--quiet}"
557                                 die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")"
558                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': rebased into '\$sha1'")"
559                                 must_die_on_failure=yes
560                                 ;;
561                         merge)
562                                 command="git merge ${GIT_QUIET:+--quiet}"
563                                 die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$displaypath'")"
564                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")"
565                                 must_die_on_failure=yes
566                                 ;;
567                         !*)
568                                 command="${update_module#!}"
569                                 die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$displaypath'")"
570                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': '\$command \$sha1'")"
571                                 must_die_on_failure=yes
572                                 ;;
573                         *)
574                                 die "$(eval_gettext "Invalid update mode '$update_module' for submodule path '$path'")"
575                         esac
576
577                         if (sanitize_submodule_env; cd "$sm_path" && $command "$sha1")
578                         then
579                                 say "$say_msg"
580                         elif test -n "$must_die_on_failure"
581                         then
582                                 die_with_status 2 "$die_msg"
583                         else
584                                 err="${err};$die_msg"
585                                 continue
586                         fi
587                 fi
588
589                 # Cache a pointer to the superproject's gitdir. This may have
590                 # changed, so rewrite it unconditionally. Writes it to worktree
591                 # if applicable, otherwise to local.
592                 relative_gitdir="$(git rev-parse --path-format=relative \
593                                                  --prefix "${sm_path}" \
594                                                  --git-dir)"
595
596                 git -C "$sm_path" config --worktree \
597                         submodule.superprojectgitdir "$relative_gitdir"
598
599                 if test -n "$recursive"
600                 then
601                         (
602                                 prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix")
603                                 wt_prefix=
604                                 sanitize_submodule_env
605                                 cd "$sm_path" &&
606                                 eval cmd_update
607                         )
608                         res=$?
609                         if test $res -gt 0
610                         then
611                                 die_msg="$(eval_gettext "Failed to recurse into submodule path '\$displaypath'")"
612                                 if test $res -ne 2
613                                 then
614                                         err="${err};$die_msg"
615                                         continue
616                                 else
617                                         die_with_status $res "$die_msg"
618                                 fi
619                         fi
620                 fi
621         done
622
623         if test -n "$err"
624         then
625                 OIFS=$IFS
626                 IFS=';'
627                 for e in $err
628                 do
629                         if test -n "$e"
630                         then
631                                 echo >&2 "$e"
632                         fi
633                 done
634                 IFS=$OIFS
635                 exit 1
636         fi
637         }
638 }
639
640 #
641 # Configures a submodule's default branch
642 #
643 # $@ = requested path
644 #
645 cmd_set_branch() {
646         default=
647         branch=
648
649         while test $# -ne 0
650         do
651                 case "$1" in
652                 -q|--quiet)
653                         # we don't do anything with this but we need to accept it
654                         ;;
655                 -d|--default)
656                         default=1
657                         ;;
658                 -b|--branch)
659                         case "$2" in '') usage ;; esac
660                         branch=$2
661                         shift
662                         ;;
663                 --)
664                         shift
665                         break
666                         ;;
667                 -*)
668                         usage
669                         ;;
670                 *)
671                         break
672                         ;;
673                 esac
674                 shift
675         done
676
677         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper set-branch ${GIT_QUIET:+--quiet} ${branch:+--branch "$branch"} ${default:+--default} -- "$@"
678 }
679
680 #
681 # Configures a submodule's remote url
682 #
683 # $@ = requested path, requested url
684 #
685 cmd_set_url() {
686         while test $# -ne 0
687         do
688                 case "$1" in
689                 -q|--quiet)
690                         GIT_QUIET=1
691                         ;;
692                 --)
693                         shift
694                         break
695                         ;;
696                 -*)
697                         usage
698                         ;;
699                 *)
700                         break
701                         ;;
702                 esac
703                 shift
704         done
705
706         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper set-url ${GIT_QUIET:+--quiet} -- "$@"
707 }
708
709 #
710 # Show commit summary for submodules in index or working tree
711 #
712 # If '--cached' is given, show summary between index and given commit,
713 # or between working tree and given commit
714 #
715 # $@ = [commit (default 'HEAD'),] requested paths (default all)
716 #
717 cmd_summary() {
718         summary_limit=-1
719         for_status=
720         diff_cmd=diff-index
721
722         # parse $args after "submodule ... summary".
723         while test $# -ne 0
724         do
725                 case "$1" in
726                 --cached)
727                         cached="$1"
728                         ;;
729                 --files)
730                         files="$1"
731                         ;;
732                 --for-status)
733                         for_status="$1"
734                         ;;
735                 -n|--summary-limit)
736                         summary_limit="$2"
737                         isnumber "$summary_limit" || usage
738                         shift
739                         ;;
740                 --summary-limit=*)
741                         summary_limit="${1#--summary-limit=}"
742                         isnumber "$summary_limit" || usage
743                         ;;
744                 --)
745                         shift
746                         break
747                         ;;
748                 -*)
749                         usage
750                         ;;
751                 *)
752                         break
753                         ;;
754                 esac
755                 shift
756         done
757
758         git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${prefix:+--prefix "$prefix"} ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
759 }
760 #
761 # List all submodules, prefixed with:
762 #  - submodule not initialized
763 #  + different revision checked out
764 #
765 # If --cached was specified the revision in the index will be printed
766 # instead of the currently checked out revision.
767 #
768 # $@ = requested paths (default to all)
769 #
770 cmd_status()
771 {
772         # parse $args after "submodule ... status".
773         while test $# -ne 0
774         do
775                 case "$1" in
776                 -q|--quiet)
777                         GIT_QUIET=1
778                         ;;
779                 --cached)
780                         cached=1
781                         ;;
782                 --recursive)
783                         recursive=1
784                         ;;
785                 --)
786                         shift
787                         break
788                         ;;
789                 -*)
790                         usage
791                         ;;
792                 *)
793                         break
794                         ;;
795                 esac
796                 shift
797         done
798
799         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} -- "$@"
800 }
801 #
802 # Sync remote urls for submodules
803 # This makes the value for remote.$remote.url match the value
804 # specified in .gitmodules.
805 #
806 cmd_sync()
807 {
808         while test $# -ne 0
809         do
810                 case "$1" in
811                 -q|--quiet)
812                         GIT_QUIET=1
813                         shift
814                         ;;
815                 --recursive)
816                         recursive=1
817                         shift
818                         ;;
819                 --)
820                         shift
821                         break
822                         ;;
823                 -*)
824                         usage
825                         ;;
826                 *)
827                         break
828                         ;;
829                 esac
830         done
831
832         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper sync ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
833 }
834
835 cmd_absorbgitdirs()
836 {
837         git submodule--helper absorb-git-dirs --prefix "$wt_prefix" "$@"
838 }
839
840 # This loop parses the command line arguments to find the
841 # subcommand name to dispatch.  Parsing of the subcommand specific
842 # options are primarily done by the subcommand implementations.
843 # Subcommand specific options such as --branch and --cached are
844 # parsed here as well, for backward compatibility.
845
846 while test $# != 0 && test -z "$command"
847 do
848         case "$1" in
849         add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
850                 command=$1
851                 ;;
852         -q|--quiet)
853                 GIT_QUIET=1
854                 ;;
855         -b|--branch)
856                 case "$2" in
857                 '')
858                         usage
859                         ;;
860                 esac
861                 branch="$2"; shift
862                 ;;
863         --cached)
864                 cached="$1"
865                 ;;
866         --)
867                 break
868                 ;;
869         -*)
870                 usage
871                 ;;
872         *)
873                 break
874                 ;;
875         esac
876         shift
877 done
878
879 # No command word defaults to "status"
880 if test -z "$command"
881 then
882     if test $# = 0
883     then
884         command=status
885     else
886         usage
887     fi
888 fi
889
890 # "-b branch" is accepted only by "add" and "set-branch"
891 if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
892 then
893         usage
894 fi
895
896 # "--cached" is accepted only by "status" and "summary"
897 if test -n "$cached" && test "$command" != status && test "$command" != summary
898 then
899         usage
900 fi
901
902 "cmd_$(echo $command | sed -e s/-/_/g)" "$@"