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