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