Merge branch 'ag/edit-todo-drop-check'
[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] [--] [<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 . git-parse-remote
24 require_work_tree
25 wt_prefix=$(git rev-parse --show-prefix)
26 cd_to_toplevel
27
28 # Tell the rest of git that any URLs we get don't come
29 # directly from the user, so it can apply policy as appropriate.
30 GIT_PROTOCOL_FROM_USER=0
31 export GIT_PROTOCOL_FROM_USER
32
33 command=
34 branch=
35 force=
36 reference=
37 cached=
38 recursive=
39 init=
40 require_init=
41 files=
42 remote=
43 nofetch=
44 update=
45 prefix=
46 custom_name=
47 depth=
48 progress=
49 dissociate=
50
51 die_if_unmatched ()
52 {
53         if test "$1" = "#unmatched"
54         then
55                 exit ${2:-1}
56         fi
57 }
58
59 #
60 # Print a submodule configuration setting
61 #
62 # $1 = submodule name
63 # $2 = option name
64 # $3 = default value
65 #
66 # Checks in the usual git-config places first (for overrides),
67 # otherwise it falls back on .gitmodules.  This allows you to
68 # distribute project-wide defaults in .gitmodules, while still
69 # customizing individual repositories if necessary.  If the option is
70 # not in .gitmodules either, print a default value.
71 #
72 get_submodule_config () {
73         name="$1"
74         option="$2"
75         default="$3"
76         value=$(git config submodule."$name"."$option")
77         if test -z "$value"
78         then
79                 value=$(git submodule--helper config submodule."$name"."$option")
80         fi
81         printf '%s' "${value:-$default}"
82 }
83
84 isnumber()
85 {
86         n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
87 }
88
89 # Given a full hex object ID, is this the zero OID?
90 is_zero_oid () {
91         echo "$1" | sane_egrep '^0+$' >/dev/null 2>&1
92 }
93
94 # Sanitize the local git environment for use within a submodule. We
95 # can't simply use clear_local_git_env since we want to preserve some
96 # of the settings from GIT_CONFIG_PARAMETERS.
97 sanitize_submodule_env()
98 {
99         save_config=$GIT_CONFIG_PARAMETERS
100         clear_local_git_env
101         GIT_CONFIG_PARAMETERS=$save_config
102         export GIT_CONFIG_PARAMETERS
103 }
104
105 #
106 # Add a new submodule to the working tree, .gitmodules and the index
107 #
108 # $@ = repo path
109 #
110 # optional branch is stored in global branch variable
111 #
112 cmd_add()
113 {
114         # parse $args after "submodule ... add".
115         reference_path=
116         while test $# -ne 0
117         do
118                 case "$1" in
119                 -b | --branch)
120                         case "$2" in '') usage ;; esac
121                         branch=$2
122                         shift
123                         ;;
124                 -f | --force)
125                         force=$1
126                         ;;
127                 -q|--quiet)
128                         GIT_QUIET=1
129                         ;;
130                 --progress)
131                         progress=1
132                         ;;
133                 --reference)
134                         case "$2" in '') usage ;; esac
135                         reference_path=$2
136                         shift
137                         ;;
138                 --reference=*)
139                         reference_path="${1#--reference=}"
140                         ;;
141                 --dissociate)
142                         dissociate=1
143                         ;;
144                 --name)
145                         case "$2" in '') usage ;; esac
146                         custom_name=$2
147                         shift
148                         ;;
149                 --depth)
150                         case "$2" in '') usage ;; esac
151                         depth="--depth=$2"
152                         shift
153                         ;;
154                 --depth=*)
155                         depth=$1
156                         ;;
157                 --)
158                         shift
159                         break
160                         ;;
161                 -*)
162                         usage
163                         ;;
164                 *)
165                         break
166                         ;;
167                 esac
168                 shift
169         done
170
171         if ! git submodule--helper config --check-writeable >/dev/null 2>&1
172         then
173                  die "$(eval_gettext "please make sure that the .gitmodules file is in the working tree")"
174         fi
175
176         if test -n "$reference_path"
177         then
178                 is_absolute_path "$reference_path" ||
179                 reference_path="$wt_prefix$reference_path"
180
181                 reference="--reference=$reference_path"
182         fi
183
184         repo=$1
185         sm_path=$2
186
187         if test -z "$sm_path"; then
188                 sm_path=$(printf '%s\n' "$repo" |
189                         sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
190         fi
191
192         if test -z "$repo" || test -z "$sm_path"; then
193                 usage
194         fi
195
196         is_absolute_path "$sm_path" || sm_path="$wt_prefix$sm_path"
197
198         # assure repo is absolute or relative to parent
199         case "$repo" in
200         ./*|../*)
201                 test -z "$wt_prefix" ||
202                 die "$(gettext "Relative path can only be used from the toplevel of the working tree")"
203
204                 # dereference source url relative to parent's url
205                 realrepo=$(git submodule--helper resolve-relative-url "$repo") || exit
206                 ;;
207         *:*|/*)
208                 # absolute url
209                 realrepo=$repo
210                 ;;
211         *)
212                 die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
213         ;;
214         esac
215
216         # normalize path:
217         # multiple //; leading ./; /./; /../; trailing /
218         sm_path=$(printf '%s/\n' "$sm_path" |
219                 sed -e '
220                         s|//*|/|g
221                         s|^\(\./\)*||
222                         s|/\(\./\)*|/|g
223                         :start
224                         s|\([^/]*\)/\.\./||
225                         tstart
226                         s|/*$||
227                 ')
228         if test -z "$force"
229         then
230                 git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
231                 die "$(eval_gettext "'\$sm_path' already exists in the index")"
232         else
233                 git ls-files -s "$sm_path" | sane_grep -v "^160000" > /dev/null 2>&1 &&
234                 die "$(eval_gettext "'\$sm_path' already exists in the index and is not a submodule")"
235         fi
236
237         if test -d "$sm_path" &&
238                 test -z $(git -C "$sm_path" rev-parse --show-cdup 2>/dev/null)
239         then
240             git -C "$sm_path" rev-parse --verify -q HEAD >/dev/null ||
241             die "$(eval_gettext "'\$sm_path' does not have a commit checked out")"
242         fi
243
244         if test -z "$force"
245         then
246             dryerr=$(git add --dry-run --ignore-missing --no-warn-embedded-repo "$sm_path" 2>&1 >/dev/null)
247             res=$?
248             if test $res -ne 0
249             then
250                  echo >&2 "$dryerr"
251                  exit $res
252             fi
253         fi
254
255         if test -n "$custom_name"
256         then
257                 sm_name="$custom_name"
258         else
259                 sm_name="$sm_path"
260         fi
261
262         if ! git submodule--helper check-name "$sm_name"
263         then
264                 die "$(eval_gettext "'$sm_name' is not a valid submodule name")"
265         fi
266
267         # perhaps the path exists and is already a git repo, else clone it
268         if test -e "$sm_path"
269         then
270                 if test -d "$sm_path"/.git || test -f "$sm_path"/.git
271                 then
272                         eval_gettextln "Adding existing repo at '\$sm_path' to the index"
273                 else
274                         die "$(eval_gettext "'\$sm_path' already exists and is not a valid git repo")"
275                 fi
276
277         else
278                 if test -d ".git/modules/$sm_name"
279                 then
280                         if test -z "$force"
281                         then
282                                 eval_gettextln >&2 "A git directory for '\$sm_name' is found locally with remote(s):"
283                                 GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^,"  ", -e s,' (fetch)',, >&2
284                                 die "$(eval_gettextln "\
285 If you want to reuse this local git directory instead of cloning again from
286   \$realrepo
287 use the '--force' option. If the local git directory is not the correct repo
288 or you are unsure what this means choose another name with the '--name' option.")"
289                         else
290                                 eval_gettextln "Reactivating local git directory for submodule '\$sm_name'."
291                         fi
292                 fi
293                 git submodule--helper clone ${GIT_QUIET:+--quiet} ${progress:+"--progress"} --prefix "$wt_prefix" --path "$sm_path" --name "$sm_name" --url "$realrepo" ${reference:+"$reference"} ${dissociate:+"--dissociate"} ${depth:+"$depth"} || exit
294                 (
295                         sanitize_submodule_env
296                         cd "$sm_path" &&
297                         # ash fails to wordsplit ${branch:+-b "$branch"...}
298                         case "$branch" in
299                         '') git checkout -f -q ;;
300                         ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
301                         esac
302                 ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
303         fi
304         git config submodule."$sm_name".url "$realrepo"
305
306         git add --no-warn-embedded-repo $force "$sm_path" ||
307         die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
308
309         git submodule--helper config submodule."$sm_name".path "$sm_path" &&
310         git submodule--helper config submodule."$sm_name".url "$repo" &&
311         if test -n "$branch"
312         then
313                 git submodule--helper config submodule."$sm_name".branch "$branch"
314         fi &&
315         git add --force .gitmodules ||
316         die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
317
318         # NEEDSWORK: In a multi-working-tree world, this needs to be
319         # set in the per-worktree config.
320         if git config --get submodule.active >/dev/null
321         then
322                 # If the submodule being adding isn't already covered by the
323                 # current configured pathspec, set the submodule's active flag
324                 if ! git submodule--helper is-active "$sm_path"
325                 then
326                         git config submodule."$sm_name".active "true"
327                 fi
328         else
329                 git config submodule."$sm_name".active "true"
330         fi
331 }
332
333 #
334 # Execute an arbitrary command sequence in each checked out
335 # submodule
336 #
337 # $@ = command to execute
338 #
339 cmd_foreach()
340 {
341         # parse $args after "submodule ... foreach".
342         while test $# -ne 0
343         do
344                 case "$1" in
345                 -q|--quiet)
346                         GIT_QUIET=1
347                         ;;
348                 --recursive)
349                         recursive=1
350                         ;;
351                 -*)
352                         usage
353                         ;;
354                 *)
355                         break
356                         ;;
357                 esac
358                 shift
359         done
360
361         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
362 }
363
364 #
365 # Register submodules in .git/config
366 #
367 # $@ = requested paths (default to all)
368 #
369 cmd_init()
370 {
371         # parse $args after "submodule ... init".
372         while test $# -ne 0
373         do
374                 case "$1" in
375                 -q|--quiet)
376                         GIT_QUIET=1
377                         ;;
378                 --)
379                         shift
380                         break
381                         ;;
382                 -*)
383                         usage
384                         ;;
385                 *)
386                         break
387                         ;;
388                 esac
389                 shift
390         done
391
392         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper init ${GIT_QUIET:+--quiet} -- "$@"
393 }
394
395 #
396 # Unregister submodules from .git/config and remove their work tree
397 #
398 cmd_deinit()
399 {
400         # parse $args after "submodule ... deinit".
401         deinit_all=
402         while test $# -ne 0
403         do
404                 case "$1" in
405                 -f|--force)
406                         force=$1
407                         ;;
408                 -q|--quiet)
409                         GIT_QUIET=1
410                         ;;
411                 --all)
412                         deinit_all=t
413                         ;;
414                 --)
415                         shift
416                         break
417                         ;;
418                 -*)
419                         usage
420                         ;;
421                 *)
422                         break
423                         ;;
424                 esac
425                 shift
426         done
427
428         git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} ${force:+--force} ${deinit_all:+--all} -- "$@"
429 }
430
431 is_tip_reachable () (
432         sanitize_submodule_env &&
433         cd "$1" &&
434         rev=$(git rev-list -n 1 "$2" --not --all 2>/dev/null) &&
435         test -z "$rev"
436 )
437
438 fetch_in_submodule () (
439         sanitize_submodule_env &&
440         cd "$1" &&
441         case "$2" in
442         '')
443                 git fetch ;;
444         *)
445                 shift
446                 git fetch $(get_default_remote) "$@" ;;
447         esac
448 )
449
450 #
451 # Update each submodule path to correct revision, using clone and checkout as needed
452 #
453 # $@ = requested paths (default to all)
454 #
455 cmd_update()
456 {
457         # parse $args after "submodule ... update".
458         while test $# -ne 0
459         do
460                 case "$1" in
461                 -q|--quiet)
462                         GIT_QUIET=1
463                         ;;
464                 -v)
465                         GIT_QUIET=0
466                         ;;
467                 --progress)
468                         progress=1
469                         ;;
470                 -i|--init)
471                         init=1
472                         ;;
473                 --require-init)
474                         init=1
475                         require_init=1
476                         ;;
477                 --remote)
478                         remote=1
479                         ;;
480                 -N|--no-fetch)
481                         nofetch=1
482                         ;;
483                 -f|--force)
484                         force=$1
485                         ;;
486                 -r|--rebase)
487                         update="rebase"
488                         ;;
489                 --reference)
490                         case "$2" in '') usage ;; esac
491                         reference="--reference=$2"
492                         shift
493                         ;;
494                 --reference=*)
495                         reference="$1"
496                         ;;
497                 --dissociate)
498                         dissociate=1
499                         ;;
500                 -m|--merge)
501                         update="merge"
502                         ;;
503                 --recursive)
504                         recursive=1
505                         ;;
506                 --checkout)
507                         update="checkout"
508                         ;;
509                 --recommend-shallow)
510                         recommend_shallow="--recommend-shallow"
511                         ;;
512                 --no-recommend-shallow)
513                         recommend_shallow="--no-recommend-shallow"
514                         ;;
515                 --depth)
516                         case "$2" in '') usage ;; esac
517                         depth="--depth=$2"
518                         shift
519                         ;;
520                 --depth=*)
521                         depth=$1
522                         ;;
523                 -j|--jobs)
524                         case "$2" in '') usage ;; esac
525                         jobs="--jobs=$2"
526                         shift
527                         ;;
528                 --jobs=*)
529                         jobs=$1
530                         ;;
531                 --)
532                         shift
533                         break
534                         ;;
535                 -*)
536                         usage
537                         ;;
538                 *)
539                         break
540                         ;;
541                 esac
542                 shift
543         done
544
545         if test -n "$init"
546         then
547                 cmd_init "--" "$@" || return
548         fi
549
550         {
551         git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
552                 ${progress:+"--progress"} \
553                 ${wt_prefix:+--prefix "$wt_prefix"} \
554                 ${prefix:+--recursive-prefix "$prefix"} \
555                 ${update:+--update "$update"} \
556                 ${reference:+"$reference"} \
557                 ${dissociate:+"--dissociate"} \
558                 ${depth:+--depth "$depth"} \
559                 ${require_init:+--require-init} \
560                 $recommend_shallow \
561                 $jobs \
562                 -- \
563                 "$@" || echo "#unmatched" $?
564         } | {
565         err=
566         while read -r quickabort sha1 just_cloned sm_path
567         do
568                 die_if_unmatched "$quickabort" "$sha1"
569
570                 git submodule--helper ensure-core-worktree "$sm_path" || exit 1
571
572                 update_module=$(git submodule--helper update-module-mode $just_cloned "$sm_path" $update)
573
574                 displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
575
576                 if test $just_cloned -eq 1
577                 then
578                         subsha1=
579                 else
580                         subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
581                                 git rev-parse --verify HEAD) ||
582                         die "$(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")"
583                 fi
584
585                 if test -n "$remote"
586                 then
587                         branch=$(git submodule--helper remote-branch "$sm_path")
588                         if test -z "$nofetch"
589                         then
590                                 # Fetch remote before determining tracking $sha1
591                                 fetch_in_submodule "$sm_path" $depth ||
592                                 die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
593                         fi
594                         remote_name=$(sanitize_submodule_env; cd "$sm_path" && get_default_remote)
595                         sha1=$(sanitize_submodule_env; cd "$sm_path" &&
596                                 git rev-parse --verify "${remote_name}/${branch}") ||
597                         die "$(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
598                 fi
599
600                 if test "$subsha1" != "$sha1" || test -n "$force"
601                 then
602                         subforce=$force
603                         # If we don't already have a -f flag and the submodule has never been checked out
604                         if test -z "$subsha1" && test -z "$force"
605                         then
606                                 subforce="-f"
607                         fi
608
609                         if test -z "$nofetch"
610                         then
611                                 # Run fetch only if $sha1 isn't present or it
612                                 # is not reachable from a ref.
613                                 is_tip_reachable "$sm_path" "$sha1" ||
614                                 fetch_in_submodule "$sm_path" $depth ||
615                                 say "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'; trying to directly fetch \$sha1:")"
616
617                                 # Now we tried the usual fetch, but $sha1 may
618                                 # not be reachable from any of the refs
619                                 is_tip_reachable "$sm_path" "$sha1" ||
620                                 fetch_in_submodule "$sm_path" $depth "$sha1" ||
621                                 die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")"
622                         fi
623
624                         must_die_on_failure=
625                         case "$update_module" in
626                         checkout)
627                                 command="git checkout $subforce -q"
628                                 die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")"
629                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")"
630                                 ;;
631                         rebase)
632                                 command="git rebase"
633                                 die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")"
634                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': rebased into '\$sha1'")"
635                                 must_die_on_failure=yes
636                                 ;;
637                         merge)
638                                 command="git merge"
639                                 die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$displaypath'")"
640                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")"
641                                 must_die_on_failure=yes
642                                 ;;
643                         !*)
644                                 command="${update_module#!}"
645                                 die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$displaypath'")"
646                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': '\$command \$sha1'")"
647                                 must_die_on_failure=yes
648                                 ;;
649                         *)
650                                 die "$(eval_gettext "Invalid update mode '$update_module' for submodule path '$path'")"
651                         esac
652
653                         if (sanitize_submodule_env; cd "$sm_path" && $command "$sha1")
654                         then
655                                 say "$say_msg"
656                         elif test -n "$must_die_on_failure"
657                         then
658                                 die_with_status 2 "$die_msg"
659                         else
660                                 err="${err};$die_msg"
661                                 continue
662                         fi
663                 fi
664
665                 if test -n "$recursive"
666                 then
667                         (
668                                 prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix")
669                                 wt_prefix=
670                                 sanitize_submodule_env
671                                 cd "$sm_path" &&
672                                 eval cmd_update
673                         )
674                         res=$?
675                         if test $res -gt 0
676                         then
677                                 die_msg="$(eval_gettext "Failed to recurse into submodule path '\$displaypath'")"
678                                 if test $res -ne 2
679                                 then
680                                         err="${err};$die_msg"
681                                         continue
682                                 else
683                                         die_with_status $res "$die_msg"
684                                 fi
685                         fi
686                 fi
687         done
688
689         if test -n "$err"
690         then
691                 OIFS=$IFS
692                 IFS=';'
693                 for e in $err
694                 do
695                         if test -n "$e"
696                         then
697                                 echo >&2 "$e"
698                         fi
699                 done
700                 IFS=$OIFS
701                 exit 1
702         fi
703         }
704 }
705
706 #
707 # Configures a submodule's default branch
708 #
709 # $@ = requested path
710 #
711 cmd_set_branch() {
712         unset_branch=false
713         branch=
714
715         while test $# -ne 0
716         do
717                 case "$1" in
718                 -q|--quiet)
719                         # we don't do anything with this but we need to accept it
720                         ;;
721                 -d|--default)
722                         unset_branch=true
723                         ;;
724                 -b|--branch)
725                         case "$2" in '') usage ;; esac
726                         branch=$2
727                         shift
728                         ;;
729                 --)
730                         shift
731                         break
732                         ;;
733                 -*)
734                         usage
735                         ;;
736                 *)
737                         break
738                         ;;
739                 esac
740                 shift
741         done
742
743         if test $# -ne 1
744         then
745                 usage
746         fi
747
748         # we can't use `git submodule--helper name` here because internally, it
749         # hashes the path so a trailing slash could lead to an unintentional no match
750         name="$(git submodule--helper list "$1" | cut -f2)"
751         if test -z "$name"
752         then
753                 exit 1
754         fi
755
756         test -n "$branch"; has_branch=$?
757         test "$unset_branch" = true; has_unset_branch=$?
758
759         if test $((!$has_branch != !$has_unset_branch)) -eq 0
760         then
761                 usage
762         fi
763
764         if test $has_branch -eq 0
765         then
766                 git submodule--helper config submodule."$name".branch "$branch"
767         else
768                 git submodule--helper config --unset submodule."$name".branch
769         fi
770 }
771
772 #
773 # Configures a submodule's remote url
774 #
775 # $@ = requested path, requested url
776 #
777 cmd_set_url() {
778         while test $# -ne 0
779         do
780                 case "$1" in
781                 -q|--quiet)
782                         GIT_QUIET=1
783                         ;;
784                 --)
785                         shift
786                         break
787                         ;;
788                 -*)
789                         usage
790                         ;;
791                 *)
792                         break
793                         ;;
794                 esac
795                 shift
796         done
797
798         if test $# -ne 2
799         then
800                 usage
801         fi
802
803         # we can't use `git submodule--helper name` here because internally, it
804         # hashes the path so a trailing slash could lead to an unintentional no match
805         name="$(git submodule--helper list "$1" | cut -f2)"
806         if test -z "$name"
807         then
808                 exit 1
809         fi
810
811         url="$2"
812         if test -z "$url"
813         then
814                 exit 1
815         fi
816
817         git submodule--helper config submodule."$name".url "$url"
818         git submodule--helper sync ${GIT_QUIET:+--quiet} "$name"
819 }
820
821 #
822 # Show commit summary for submodules in index or working tree
823 #
824 # If '--cached' is given, show summary between index and given commit,
825 # or between working tree and given commit
826 #
827 # $@ = [commit (default 'HEAD'),] requested paths (default all)
828 #
829 cmd_summary() {
830         summary_limit=-1
831         for_status=
832         diff_cmd=diff-index
833
834         # parse $args after "submodule ... summary".
835         while test $# -ne 0
836         do
837                 case "$1" in
838                 --cached)
839                         cached="$1"
840                         ;;
841                 --files)
842                         files="$1"
843                         ;;
844                 --for-status)
845                         for_status="$1"
846                         ;;
847                 -n|--summary-limit)
848                         summary_limit="$2"
849                         isnumber "$summary_limit" || usage
850                         shift
851                         ;;
852                 --summary-limit=*)
853                         summary_limit="${1#--summary-limit=}"
854                         isnumber "$summary_limit" || usage
855                         ;;
856                 --)
857                         shift
858                         break
859                         ;;
860                 -*)
861                         usage
862                         ;;
863                 *)
864                         break
865                         ;;
866                 esac
867                 shift
868         done
869
870         test $summary_limit = 0 && return
871
872         if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
873         then
874                 head=$rev
875                 test $# = 0 || shift
876         elif test -z "$1" || test "$1" = "HEAD"
877         then
878                 # before the first commit: compare with an empty tree
879                 head=$(git hash-object -w -t tree --stdin </dev/null)
880                 test -z "$1" || shift
881         else
882                 head="HEAD"
883         fi
884
885         if [ -n "$files" ]
886         then
887                 test -n "$cached" &&
888                 die "$(gettext "The --cached option cannot be used with the --files option")"
889                 diff_cmd=diff-files
890                 head=
891         fi
892
893         cd_to_toplevel
894         eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
895         # Get modified modules cared by user
896         modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
897                 sane_egrep '^:([0-7]* )?160000' |
898                 while read -r mod_src mod_dst sha1_src sha1_dst status sm_path
899                 do
900                         # Always show modules deleted or type-changed (blob<->module)
901                         if test "$status" = D || test "$status" = T
902                         then
903                                 printf '%s\n' "$sm_path"
904                                 continue
905                         fi
906                         # Respect the ignore setting for --for-status.
907                         if test -n "$for_status"
908                         then
909                                 name=$(git submodule--helper name "$sm_path")
910                                 ignore_config=$(get_submodule_config "$name" ignore none)
911                                 test $status != A && test $ignore_config = all && continue
912                         fi
913                         # Also show added or modified modules which are checked out
914                         GIT_DIR="$sm_path/.git" git rev-parse --git-dir >/dev/null 2>&1 &&
915                         printf '%s\n' "$sm_path"
916                 done
917         )
918
919         test -z "$modules" && return
920
921         git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
922         sane_egrep '^:([0-7]* )?160000' |
923         cut -c2- |
924         while read -r mod_src mod_dst sha1_src sha1_dst status name
925         do
926                 if test -z "$cached" &&
927                         is_zero_oid $sha1_dst
928                 then
929                         case "$mod_dst" in
930                         160000)
931                                 sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
932                                 ;;
933                         100644 | 100755 | 120000)
934                                 sha1_dst=$(git hash-object $name)
935                                 ;;
936                         000000)
937                                 ;; # removed
938                         *)
939                                 # unexpected type
940                                 eval_gettextln "unexpected mode \$mod_dst" >&2
941                                 continue ;;
942                         esac
943                 fi
944                 missing_src=
945                 missing_dst=
946
947                 test $mod_src = 160000 &&
948                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_src^0 >/dev/null &&
949                 missing_src=t
950
951                 test $mod_dst = 160000 &&
952                 ! GIT_DIR="$name/.git" git rev-parse -q --verify $sha1_dst^0 >/dev/null &&
953                 missing_dst=t
954
955                 display_name=$(git submodule--helper relative-path "$name" "$wt_prefix")
956
957                 total_commits=
958                 case "$missing_src,$missing_dst" in
959                 t,)
960                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
961                         ;;
962                 ,t)
963                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
964                         ;;
965                 t,t)
966                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")"
967                         ;;
968                 *)
969                         errmsg=
970                         total_commits=$(
971                         if test $mod_src = 160000 && test $mod_dst = 160000
972                         then
973                                 range="$sha1_src...$sha1_dst"
974                         elif test $mod_src = 160000
975                         then
976                                 range=$sha1_src
977                         else
978                                 range=$sha1_dst
979                         fi
980                         GIT_DIR="$name/.git" \
981                         git rev-list --first-parent $range -- | wc -l
982                         )
983                         total_commits=" ($(($total_commits + 0)))"
984                         ;;
985                 esac
986
987                 sha1_abbr_src=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_src 2>/dev/null ||
988                         echo $sha1_src | cut -c1-7)
989                 sha1_abbr_dst=$(GIT_DIR="$name/.git" git rev-parse --short $sha1_dst 2>/dev/null ||
990                         echo $sha1_dst | cut -c1-7)
991
992                 if test $status = T
993                 then
994                         blob="$(gettext "blob")"
995                         submodule="$(gettext "submodule")"
996                         if test $mod_dst = 160000
997                         then
998                                 echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
999                         else
1000                                 echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
1001                         fi
1002                 else
1003                         echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
1004                 fi
1005                 if test -n "$errmsg"
1006                 then
1007                         # Don't give error msg for modification whose dst is not submodule
1008                         # i.e. deleted or changed to blob
1009                         test $mod_dst = 160000 && echo "$errmsg"
1010                 else
1011                         if test $mod_src = 160000 && test $mod_dst = 160000
1012                         then
1013                                 limit=
1014                                 test $summary_limit -gt 0 && limit="-$summary_limit"
1015                                 GIT_DIR="$name/.git" \
1016                                 git log $limit --pretty='format:  %m %s' \
1017                                 --first-parent $sha1_src...$sha1_dst
1018                         elif test $mod_dst = 160000
1019                         then
1020                                 GIT_DIR="$name/.git" \
1021                                 git log --pretty='format:  > %s' -1 $sha1_dst
1022                         else
1023                                 GIT_DIR="$name/.git" \
1024                                 git log --pretty='format:  < %s' -1 $sha1_src
1025                         fi
1026                         echo
1027                 fi
1028                 echo
1029         done
1030 }
1031 #
1032 # List all submodules, prefixed with:
1033 #  - submodule not initialized
1034 #  + different revision checked out
1035 #
1036 # If --cached was specified the revision in the index will be printed
1037 # instead of the currently checked out revision.
1038 #
1039 # $@ = requested paths (default to all)
1040 #
1041 cmd_status()
1042 {
1043         # parse $args after "submodule ... status".
1044         while test $# -ne 0
1045         do
1046                 case "$1" in
1047                 -q|--quiet)
1048                         GIT_QUIET=1
1049                         ;;
1050                 --cached)
1051                         cached=1
1052                         ;;
1053                 --recursive)
1054                         recursive=1
1055                         ;;
1056                 --)
1057                         shift
1058                         break
1059                         ;;
1060                 -*)
1061                         usage
1062                         ;;
1063                 *)
1064                         break
1065                         ;;
1066                 esac
1067                 shift
1068         done
1069
1070         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} -- "$@"
1071 }
1072 #
1073 # Sync remote urls for submodules
1074 # This makes the value for remote.$remote.url match the value
1075 # specified in .gitmodules.
1076 #
1077 cmd_sync()
1078 {
1079         while test $# -ne 0
1080         do
1081                 case "$1" in
1082                 -q|--quiet)
1083                         GIT_QUIET=1
1084                         shift
1085                         ;;
1086                 --recursive)
1087                         recursive=1
1088                         shift
1089                         ;;
1090                 --)
1091                         shift
1092                         break
1093                         ;;
1094                 -*)
1095                         usage
1096                         ;;
1097                 *)
1098                         break
1099                         ;;
1100                 esac
1101         done
1102
1103         git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper sync ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
1104 }
1105
1106 cmd_absorbgitdirs()
1107 {
1108         git submodule--helper absorb-git-dirs --prefix "$wt_prefix" "$@"
1109 }
1110
1111 # This loop parses the command line arguments to find the
1112 # subcommand name to dispatch.  Parsing of the subcommand specific
1113 # options are primarily done by the subcommand implementations.
1114 # Subcommand specific options such as --branch and --cached are
1115 # parsed here as well, for backward compatibility.
1116
1117 while test $# != 0 && test -z "$command"
1118 do
1119         case "$1" in
1120         add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
1121                 command=$1
1122                 ;;
1123         -q|--quiet)
1124                 GIT_QUIET=1
1125                 ;;
1126         -b|--branch)
1127                 case "$2" in
1128                 '')
1129                         usage
1130                         ;;
1131                 esac
1132                 branch="$2"; shift
1133                 ;;
1134         --cached)
1135                 cached="$1"
1136                 ;;
1137         --)
1138                 break
1139                 ;;
1140         -*)
1141                 usage
1142                 ;;
1143         *)
1144                 break
1145                 ;;
1146         esac
1147         shift
1148 done
1149
1150 # No command word defaults to "status"
1151 if test -z "$command"
1152 then
1153     if test $# = 0
1154     then
1155         command=status
1156     else
1157         usage
1158     fi
1159 fi
1160
1161 # "-b branch" is accepted only by "add" and "set-branch"
1162 if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
1163 then
1164         usage
1165 fi
1166
1167 # "--cached" is accepted only by "status" and "summary"
1168 if test -n "$cached" && test "$command" != status && test "$command" != summary
1169 then
1170         usage
1171 fi
1172
1173 "cmd_$(echo $command | sed -e s/-/_/g)" "$@"