submodule: drop the top-level requirement
[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] [--] <path>...
12    or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--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 OPTIONS_SPEC=
17 SUBDIRECTORY_OK=Yes
18 . git-sh-setup
19 . git-sh-i18n
20 . git-parse-remote
21 require_work_tree
22 wt_prefix=$(git rev-parse --show-prefix)
23 cd_to_toplevel
24
25 command=
26 branch=
27 force=
28 reference=
29 cached=
30 recursive=
31 init=
32 files=
33 remote=
34 nofetch=
35 update=
36 prefix=
37 custom_name=
38
39 # The function takes at most 2 arguments. The first argument is the
40 # URL that navigates to the submodule origin repo. When relative, this URL
41 # is relative to the superproject origin URL repo. The second up_path
42 # argument, if specified, is the relative path that navigates
43 # from the submodule working tree to the superproject working tree.
44 #
45 # The output of the function is the origin URL of the submodule.
46 #
47 # The output will either be an absolute URL or filesystem path (if the
48 # superproject origin URL is an absolute URL or filesystem path,
49 # respectively) or a relative file system path (if the superproject
50 # origin URL is a relative file system path).
51 #
52 # When the output is a relative file system path, the path is either
53 # relative to the submodule working tree, if up_path is specified, or to
54 # the superproject working tree otherwise.
55 resolve_relative_url ()
56 {
57         remote=$(get_default_remote)
58         remoteurl=$(git config "remote.$remote.url") ||
59                 remoteurl=$(pwd) # the repository is its own authoritative upstream
60         url="$1"
61         remoteurl=${remoteurl%/}
62         sep=/
63         up_path="$2"
64
65         case "$remoteurl" in
66         *:*|/*)
67                 is_relative=
68                 ;;
69         ./*|../*)
70                 is_relative=t
71                 ;;
72         *)
73                 is_relative=t
74                 remoteurl="./$remoteurl"
75                 ;;
76         esac
77
78         while test -n "$url"
79         do
80                 case "$url" in
81                 ../*)
82                         url="${url#../}"
83                         case "$remoteurl" in
84                         */*)
85                                 remoteurl="${remoteurl%/*}"
86                                 ;;
87                         *:*)
88                                 remoteurl="${remoteurl%:*}"
89                                 sep=:
90                                 ;;
91                         *)
92                                 if test -z "$is_relative" || test "." = "$remoteurl"
93                                 then
94                                         die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")"
95                                 else
96                                         remoteurl=.
97                                 fi
98                                 ;;
99                         esac
100                         ;;
101                 ./*)
102                         url="${url#./}"
103                         ;;
104                 *)
105                         break;;
106                 esac
107         done
108         remoteurl="$remoteurl$sep${url%/}"
109         echo "${is_relative:+${up_path}}${remoteurl#./}"
110 }
111
112 # Resolve a path to be relative to another path.  This is intended for
113 # converting submodule paths when git-submodule is run in a subdirectory
114 # and only handles paths where the directory separator is '/'.
115 #
116 # The output is the first argument as a path relative to the second argument,
117 # which defaults to $wt_prefix if it is omitted.
118 relative_path ()
119 {
120         local target curdir result
121         target=$1
122         curdir=${2-$wt_prefix}
123         curdir=${curdir%/}
124         result=
125
126         while test -n "$curdir"
127         do
128                 case "$target" in
129                 "$curdir/"*)
130                         target=${target#"$curdir"/}
131                         break
132                         ;;
133                 esac
134
135                 result="${result}../"
136                 if test "$curdir" = "${curdir%/*}"
137                 then
138                         curdir=
139                 else
140                         curdir="${curdir%/*}"
141                 fi
142         done
143
144         echo "$result$target"
145 }
146
147 #
148 # Get submodule info for registered submodules
149 # $@ = path to limit submodule list
150 #
151 module_list()
152 {
153         eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
154         (
155                 git ls-files --error-unmatch --stage -- "$@" ||
156                 echo "unmatched pathspec exists"
157         ) |
158         perl -e '
159         my %unmerged = ();
160         my ($null_sha1) = ("0" x 40);
161         my @out = ();
162         my $unmatched = 0;
163         while (<STDIN>) {
164                 if (/^unmatched pathspec/) {
165                         $unmatched = 1;
166                         next;
167                 }
168                 chomp;
169                 my ($mode, $sha1, $stage, $path) =
170                         /^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
171                 next unless $mode eq "160000";
172                 if ($stage ne "0") {
173                         if (!$unmerged{$path}++) {
174                                 push @out, "$mode $null_sha1 U\t$path\n";
175                         }
176                         next;
177                 }
178                 push @out, "$_\n";
179         }
180         if ($unmatched) {
181                 print "#unmatched\n";
182         } else {
183                 print for (@out);
184         }
185         '
186 }
187
188 die_if_unmatched ()
189 {
190         if test "$1" = "#unmatched"
191         then
192                 exit 1
193         fi
194 }
195
196 #
197 # Print a submodule configuration setting
198 #
199 # $1 = submodule name
200 # $2 = option name
201 # $3 = default value
202 #
203 # Checks in the usual git-config places first (for overrides),
204 # otherwise it falls back on .gitmodules.  This allows you to
205 # distribute project-wide defaults in .gitmodules, while still
206 # customizing individual repositories if necessary.  If the option is
207 # not in .gitmodules either, print a default value.
208 #
209 get_submodule_config () {
210         name="$1"
211         option="$2"
212         default="$3"
213         value=$(git config submodule."$name"."$option")
214         if test -z "$value"
215         then
216                 value=$(git config -f .gitmodules submodule."$name"."$option")
217         fi
218         printf '%s' "${value:-$default}"
219 }
220
221
222 #
223 # Map submodule path to submodule name
224 #
225 # $1 = path
226 #
227 module_name()
228 {
229         # Do we have "submodule.<something>.path = $1" defined in .gitmodules file?
230         sm_path="$1"
231         re=$(printf '%s\n' "$1" | sed -e 's/[].[^$\\*]/\\&/g')
232         name=$( git config -f .gitmodules --get-regexp '^submodule\..*\.path$' |
233                 sed -n -e 's|^submodule\.\(.*\)\.path '"$re"'$|\1|p' )
234         test -z "$name" &&
235         die "$(eval_gettext "No submodule mapping found in .gitmodules for path '\$sm_path'")"
236         echo "$name"
237 }
238
239 #
240 # Clone a submodule
241 #
242 # Prior to calling, cmd_update checks that a possibly existing
243 # path is not a git repository.
244 # Likewise, cmd_add checks that path does not exist at all,
245 # since it is the location of a new submodule.
246 #
247 module_clone()
248 {
249         sm_path=$1
250         name=$2
251         url=$3
252         reference="$4"
253         quiet=
254         if test -n "$GIT_QUIET"
255         then
256                 quiet=-q
257         fi
258
259         gitdir=
260         gitdir_base=
261         base_name=$(dirname "$name")
262
263         gitdir=$(git rev-parse --git-dir)
264         gitdir_base="$gitdir/modules/$base_name"
265         gitdir="$gitdir/modules/$name"
266
267         if test -d "$gitdir"
268         then
269                 mkdir -p "$sm_path"
270                 rm -f "$gitdir/index"
271         else
272                 mkdir -p "$gitdir_base"
273                 (
274                         clear_local_git_env
275                         git clone $quiet -n ${reference:+"$reference"} \
276                                 --separate-git-dir "$gitdir" "$url" "$sm_path"
277                 ) ||
278                 die "$(eval_gettext "Clone of '\$url' into submodule path '\$sm_path' failed")"
279         fi
280
281         # We already are at the root of the work tree but cd_to_toplevel will
282         # resolve any symlinks that might be present in $PWD
283         a=$(cd_to_toplevel && cd "$gitdir" && pwd)/
284         b=$(cd_to_toplevel && cd "$sm_path" && pwd)/
285         # normalize Windows-style absolute paths to POSIX-style absolute paths
286         case $a in [a-zA-Z]:/*) a=/${a%%:*}${a#*:} ;; esac
287         case $b in [a-zA-Z]:/*) b=/${b%%:*}${b#*:} ;; esac
288         # Remove all common leading directories after a sanity check
289         if test "${a#$b}" != "$a" || test "${b#$a}" != "$b"; then
290                 die "$(eval_gettext "Gitdir '\$a' is part of the submodule path '\$b' or vice versa")"
291         fi
292         while test "${a%%/*}" = "${b%%/*}"
293         do
294                 a=${a#*/}
295                 b=${b#*/}
296         done
297         # Now chop off the trailing '/'s that were added in the beginning
298         a=${a%/}
299         b=${b%/}
300
301         # Turn each leading "*/" component into "../"
302         rel=$(echo $b | sed -e 's|[^/][^/]*|..|g')
303         echo "gitdir: $rel/$a" >"$sm_path/.git"
304
305         rel=$(echo $a | sed -e 's|[^/][^/]*|..|g')
306         (clear_local_git_env; cd "$sm_path" && GIT_WORK_TREE=. git config core.worktree "$rel/$b")
307 }
308
309 isnumber()
310 {
311         n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
312 }
313
314 #
315 # Add a new submodule to the working tree, .gitmodules and the index
316 #
317 # $@ = repo path
318 #
319 # optional branch is stored in global branch variable
320 #
321 cmd_add()
322 {
323         # parse $args after "submodule ... add".
324         reference_path=
325         while test $# -ne 0
326         do
327                 case "$1" in
328                 -b | --branch)
329                         case "$2" in '') usage ;; esac
330                         branch=$2
331                         shift
332                         ;;
333                 -f | --force)
334                         force=$1
335                         ;;
336                 -q|--quiet)
337                         GIT_QUIET=1
338                         ;;
339                 --reference)
340                         case "$2" in '') usage ;; esac
341                         reference_path=$2
342                         shift
343                         ;;
344                 --reference=*)
345                         reference_path="${1#--reference=}"
346                         ;;
347                 --name)
348                         case "$2" in '') usage ;; esac
349                         custom_name=$2
350                         shift
351                         ;;
352                 --)
353                         shift
354                         break
355                         ;;
356                 -*)
357                         usage
358                         ;;
359                 *)
360                         break
361                         ;;
362                 esac
363                 shift
364         done
365
366         if test -n "$reference_path"
367         then
368                 is_absolute_path "$reference_path" ||
369                 reference_path="$wt_prefix$reference_path"
370
371                 reference="--reference=$reference_path"
372         fi
373
374         repo=$1
375         sm_path=$2
376
377         if test -z "$sm_path"; then
378                 sm_path=$(echo "$repo" |
379                         sed -e 's|/$||' -e 's|:*/*\.git$||' -e 's|.*[/:]||g')
380         fi
381
382         if test -z "$repo" -o -z "$sm_path"; then
383                 usage
384         fi
385
386         is_absolute_path "$sm_path" || sm_path="$wt_prefix$sm_path"
387
388         # assure repo is absolute or relative to parent
389         case "$repo" in
390         ./*|../*)
391                 test -z "$wt_prefix" ||
392                 die "$(gettext "Relative path can only be used from the toplevel of the working tree")"
393
394                 # dereference source url relative to parent's url
395                 realrepo=$(resolve_relative_url "$repo") || exit
396                 ;;
397         *:*|/*)
398                 # absolute url
399                 realrepo=$repo
400                 ;;
401         *)
402                 die "$(eval_gettext "repo URL: '\$repo' must be absolute or begin with ./|../")"
403         ;;
404         esac
405
406         # normalize path:
407         # multiple //; leading ./; /./; /../; trailing /
408         sm_path=$(printf '%s/\n' "$sm_path" |
409                 sed -e '
410                         s|//*|/|g
411                         s|^\(\./\)*||
412                         s|/\./|/|g
413                         :start
414                         s|\([^/]*\)/\.\./||
415                         tstart
416                         s|/*$||
417                 ')
418         git ls-files --error-unmatch "$sm_path" > /dev/null 2>&1 &&
419         die "$(eval_gettext "'\$sm_path' already exists in the index")"
420
421         if test -z "$force" && ! git add --dry-run --ignore-missing "$sm_path" > /dev/null 2>&1
422         then
423                 eval_gettextln "The following path is ignored by one of your .gitignore files:
424 \$sm_path
425 Use -f if you really want to add it." >&2
426                 exit 1
427         fi
428
429         if test -n "$custom_name"
430         then
431                 sm_name="$custom_name"
432         else
433                 sm_name="$sm_path"
434         fi
435
436         # perhaps the path exists and is already a git repo, else clone it
437         if test -e "$sm_path"
438         then
439                 if test -d "$sm_path"/.git -o -f "$sm_path"/.git
440                 then
441                         eval_gettextln "Adding existing repo at '\$sm_path' to the index"
442                 else
443                         die "$(eval_gettext "'\$sm_path' already exists and is not a valid git repo")"
444                 fi
445
446         else
447                 if test -d ".git/modules/$sm_name"
448                 then
449                         if test -z "$force"
450                         then
451                                 echo >&2 "$(eval_gettext "A git directory for '\$sm_name' is found locally with remote(s):")"
452                                 GIT_DIR=".git/modules/$sm_name" GIT_WORK_TREE=. git remote -v | grep '(fetch)' | sed -e s,^,"  ", -e s,' (fetch)',, >&2
453                                 echo >&2 "$(eval_gettext "If you want to reuse this local git directory instead of cloning again from")"
454                                 echo >&2 "  $realrepo"
455                                 echo >&2 "$(eval_gettext "use the '--force' option. If the local git directory is not the correct repo")"
456                                 die "$(eval_gettext "or you are unsure what this means choose another name with the '--name' option.")"
457                         else
458                                 echo "$(eval_gettext "Reactivating local git directory for submodule '\$sm_name'.")"
459                         fi
460                 fi
461                 module_clone "$sm_path" "$sm_name" "$realrepo" "$reference" || exit
462                 (
463                         clear_local_git_env
464                         cd "$sm_path" &&
465                         # ash fails to wordsplit ${branch:+-b "$branch"...}
466                         case "$branch" in
467                         '') git checkout -f -q ;;
468                         ?*) git checkout -f -q -B "$branch" "origin/$branch" ;;
469                         esac
470                 ) || die "$(eval_gettext "Unable to checkout submodule '\$sm_path'")"
471         fi
472         git config submodule."$sm_name".url "$realrepo"
473
474         git add $force "$sm_path" ||
475         die "$(eval_gettext "Failed to add submodule '\$sm_path'")"
476
477         git config -f .gitmodules submodule."$sm_name".path "$sm_path" &&
478         git config -f .gitmodules submodule."$sm_name".url "$repo" &&
479         if test -n "$branch"
480         then
481                 git config -f .gitmodules submodule."$sm_name".branch "$branch"
482         fi &&
483         git add --force .gitmodules ||
484         die "$(eval_gettext "Failed to register submodule '\$sm_path'")"
485 }
486
487 #
488 # Execute an arbitrary command sequence in each checked out
489 # submodule
490 #
491 # $@ = command to execute
492 #
493 cmd_foreach()
494 {
495         # parse $args after "submodule ... foreach".
496         while test $# -ne 0
497         do
498                 case "$1" in
499                 -q|--quiet)
500                         GIT_QUIET=1
501                         ;;
502                 --recursive)
503                         recursive=1
504                         ;;
505                 -*)
506                         usage
507                         ;;
508                 *)
509                         break
510                         ;;
511                 esac
512                 shift
513         done
514
515         toplevel=$(pwd)
516
517         # dup stdin so that it can be restored when running the external
518         # command in the subshell (and a recursive call to this function)
519         exec 3<&0
520
521         module_list |
522         while read mode sha1 stage sm_path
523         do
524                 die_if_unmatched "$mode"
525                 if test -e "$sm_path"/.git
526                 then
527                         displaypath=$(relative_path "$sm_path")
528                         say "$(eval_gettext "Entering '\$prefix\$displaypath'")"
529                         name=$(module_name "$sm_path")
530                         (
531                                 prefix="$prefix$sm_path/"
532                                 clear_local_git_env
533                                 cd "$sm_path" &&
534                                 sm_path=$(relative_path "$sm_path") &&
535                                 # we make $path available to scripts ...
536                                 path=$sm_path &&
537                                 eval "$@" &&
538                                 if test -n "$recursive"
539                                 then
540                                         cmd_foreach "--recursive" "$@"
541                                 fi
542                         ) <&3 3<&- ||
543                         die "$(eval_gettext "Stopping at '\$prefix\$displaypath'; script returned non-zero status.")"
544                 fi
545         done
546 }
547
548 #
549 # Register submodules in .git/config
550 #
551 # $@ = requested paths (default to all)
552 #
553 cmd_init()
554 {
555         # parse $args after "submodule ... init".
556         while test $# -ne 0
557         do
558                 case "$1" in
559                 -q|--quiet)
560                         GIT_QUIET=1
561                         ;;
562                 --)
563                         shift
564                         break
565                         ;;
566                 -*)
567                         usage
568                         ;;
569                 *)
570                         break
571                         ;;
572                 esac
573                 shift
574         done
575
576         module_list "$@" |
577         while read mode sha1 stage sm_path
578         do
579                 die_if_unmatched "$mode"
580                 name=$(module_name "$sm_path") || exit
581
582                 displaypath=$(relative_path "$sm_path")
583
584                 # Copy url setting when it is not set yet
585                 if test -z "$(git config "submodule.$name.url")"
586                 then
587                         url=$(git config -f .gitmodules submodule."$name".url)
588                         test -z "$url" &&
589                         die "$(eval_gettext "No url found for submodule path '\$displaypath' in .gitmodules")"
590
591                         # Possibly a url relative to parent
592                         case "$url" in
593                         ./*|../*)
594                                 url=$(resolve_relative_url "$url") || exit
595                                 ;;
596                         esac
597                         git config submodule."$name".url "$url" ||
598                         die "$(eval_gettext "Failed to register url for submodule path '\$displaypath'")"
599
600                         say "$(eval_gettext "Submodule '\$name' (\$url) registered for path '\$displaypath'")"
601                 fi
602
603                 # Copy "update" setting when it is not set yet
604                 upd="$(git config -f .gitmodules submodule."$name".update)"
605                 test -z "$upd" ||
606                 test -n "$(git config submodule."$name".update)" ||
607                 git config submodule."$name".update "$upd" ||
608                 die "$(eval_gettext "Failed to register update mode for submodule path '\$displaypath'")"
609         done
610 }
611
612 #
613 # Unregister submodules from .git/config and remove their work tree
614 #
615 # $@ = requested paths (use '.' to deinit all submodules)
616 #
617 cmd_deinit()
618 {
619         # parse $args after "submodule ... deinit".
620         while test $# -ne 0
621         do
622                 case "$1" in
623                 -f|--force)
624                         force=$1
625                         ;;
626                 -q|--quiet)
627                         GIT_QUIET=1
628                         ;;
629                 --)
630                         shift
631                         break
632                         ;;
633                 -*)
634                         usage
635                         ;;
636                 *)
637                         break
638                         ;;
639                 esac
640                 shift
641         done
642
643         if test $# = 0
644         then
645                 die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")"
646         fi
647
648         module_list "$@" |
649         while read mode sha1 stage sm_path
650         do
651                 die_if_unmatched "$mode"
652                 name=$(module_name "$sm_path") || exit
653
654                 displaypath=$(relative_path "$sm_path")
655
656                 # Remove the submodule work tree (unless the user already did it)
657                 if test -d "$sm_path"
658                 then
659                         # Protect submodules containing a .git directory
660                         if test -d "$sm_path/.git"
661                         then
662                                 echo >&2 "$(eval_gettext "Submodule work tree '\$displaypath' contains a .git directory")"
663                                 die "$(eval_gettext "(use 'rm -rf' if you really want to remove it including all of its history)")"
664                         fi
665
666                         if test -z "$force"
667                         then
668                                 git rm -qn "$sm_path" ||
669                                 die "$(eval_gettext "Submodule work tree '\$displaypath' contains local modifications; use '-f' to discard them")"
670                         fi
671                         rm -rf "$sm_path" &&
672                         say "$(eval_gettext "Cleared directory '\$displaypath'")" ||
673                         say "$(eval_gettext "Could not remove submodule work tree '\$displaypath'")"
674                 fi
675
676                 mkdir "$sm_path" || say "$(eval_gettext "Could not create empty submodule directory '\$displaypath'")"
677
678                 # Remove the .git/config entries (unless the user already did it)
679                 if test -n "$(git config --get-regexp submodule."$name\.")"
680                 then
681                         # Remove the whole section so we have a clean state when
682                         # the user later decides to init this submodule again
683                         url=$(git config submodule."$name".url)
684                         git config --remove-section submodule."$name" 2>/dev/null &&
685                         say "$(eval_gettext "Submodule '\$name' (\$url) unregistered for path '\$displaypath'")"
686                 fi
687         done
688 }
689
690 #
691 # Update each submodule path to correct revision, using clone and checkout as needed
692 #
693 # $@ = requested paths (default to all)
694 #
695 cmd_update()
696 {
697         # parse $args after "submodule ... update".
698         orig_flags=
699         while test $# -ne 0
700         do
701                 case "$1" in
702                 -q|--quiet)
703                         GIT_QUIET=1
704                         ;;
705                 -i|--init)
706                         init=1
707                         ;;
708                 --remote)
709                         remote=1
710                         ;;
711                 -N|--no-fetch)
712                         nofetch=1
713                         ;;
714                 -f|--force)
715                         force=$1
716                         ;;
717                 -r|--rebase)
718                         update="rebase"
719                         ;;
720                 --reference)
721                         case "$2" in '') usage ;; esac
722                         reference="--reference=$2"
723                         orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
724                         shift
725                         ;;
726                 --reference=*)
727                         reference="$1"
728                         ;;
729                 -m|--merge)
730                         update="merge"
731                         ;;
732                 --recursive)
733                         recursive=1
734                         ;;
735                 --checkout)
736                         update="checkout"
737                         ;;
738                 --)
739                         shift
740                         break
741                         ;;
742                 -*)
743                         usage
744                         ;;
745                 *)
746                         break
747                         ;;
748                 esac
749                 orig_flags="$orig_flags $(git rev-parse --sq-quote "$1")"
750                 shift
751         done
752
753         if test -n "$init"
754         then
755                 cmd_init "--" "$@" || return
756         fi
757
758         cloned_modules=
759         module_list "$@" | {
760         err=
761         while read mode sha1 stage sm_path
762         do
763                 die_if_unmatched "$mode"
764                 if test "$stage" = U
765                 then
766                         echo >&2 "Skipping unmerged submodule $prefix$sm_path"
767                         continue
768                 fi
769                 name=$(module_name "$sm_path") || exit
770                 url=$(git config submodule."$name".url)
771                 branch=$(get_submodule_config "$name" branch master)
772                 if ! test -z "$update"
773                 then
774                         update_module=$update
775                 else
776                         update_module=$(git config submodule."$name".update)
777                 fi
778
779                 displaypath=$(relative_path "$prefix$sm_path")
780
781                 if test "$update_module" = "none"
782                 then
783                         echo "Skipping submodule '$displaypath'"
784                         continue
785                 fi
786
787                 if test -z "$url"
788                 then
789                         # Only mention uninitialized submodules when its
790                         # path have been specified
791                         test "$#" != "0" &&
792                         say "$(eval_gettext "Submodule path '\$displaypath' not initialized
793 Maybe you want to use 'update --init'?")"
794                         continue
795                 fi
796
797                 if ! test -d "$sm_path"/.git -o -f "$sm_path"/.git
798                 then
799                         module_clone "$sm_path" "$name" "$url" "$reference" || exit
800                         cloned_modules="$cloned_modules;$name"
801                         subsha1=
802                 else
803                         subsha1=$(clear_local_git_env; cd "$sm_path" &&
804                                 git rev-parse --verify HEAD) ||
805                         die "$(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")"
806                 fi
807
808                 if test -n "$remote"
809                 then
810                         if test -z "$nofetch"
811                         then
812                                 # Fetch remote before determining tracking $sha1
813                                 (clear_local_git_env; cd "$sm_path" && git-fetch) ||
814                                 die "$(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
815                         fi
816                         remote_name=$(clear_local_git_env; cd "$sm_path" && get_default_remote)
817                         sha1=$(clear_local_git_env; cd "$sm_path" &&
818                                 git rev-parse --verify "${remote_name}/${branch}") ||
819                         die "$(eval_gettext "Unable to find current ${remote_name}/${branch} revision in submodule path '\$sm_path'")"
820                 fi
821
822                 if test "$subsha1" != "$sha1" -o -n "$force"
823                 then
824                         subforce=$force
825                         # If we don't already have a -f flag and the submodule has never been checked out
826                         if test -z "$subsha1" -a -z "$force"
827                         then
828                                 subforce="-f"
829                         fi
830
831                         if test -z "$nofetch"
832                         then
833                                 # Run fetch only if $sha1 isn't present or it
834                                 # is not reachable from a ref.
835                                 (clear_local_git_env; cd "$sm_path" &&
836                                         ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
837                                          test -z "$rev") || git-fetch)) ||
838                                 die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
839                         fi
840
841                         # Is this something we just cloned?
842                         case ";$cloned_modules;" in
843                         *";$name;"*)
844                                 # then there is no local change to integrate
845                                 update_module= ;;
846                         esac
847
848                         must_die_on_failure=
849                         case "$update_module" in
850                         rebase)
851                                 command="git rebase"
852                                 die_msg="$(eval_gettext "Unable to rebase '\$sha1' in submodule path '\$displaypath'")"
853                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': rebased into '\$sha1'")"
854                                 must_die_on_failure=yes
855                                 ;;
856                         merge)
857                                 command="git merge"
858                                 die_msg="$(eval_gettext "Unable to merge '\$sha1' in submodule path '\$displaypath'")"
859                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")"
860                                 must_die_on_failure=yes
861                                 ;;
862                         *)
863                                 command="git checkout $subforce -q"
864                                 die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")"
865                                 say_msg="$(eval_gettext "Submodule path '\$displaypath': checked out '\$sha1'")"
866                                 ;;
867                         esac
868
869                         if (clear_local_git_env; cd "$sm_path" && $command "$sha1")
870                         then
871                                 say "$say_msg"
872                         elif test -n "$must_die_on_failure"
873                         then
874                                 die_with_status 2 "$die_msg"
875                         else
876                                 err="${err};$die_msg"
877                                 continue
878                         fi
879                 fi
880
881                 if test -n "$recursive"
882                 then
883                         (
884                                 prefix="$prefix$sm_path/"
885                                 clear_local_git_env
886                                 cd "$sm_path" &&
887                                 eval cmd_update "$orig_flags"
888                         )
889                         res=$?
890                         if test $res -gt 0
891                         then
892                                 die_msg="$(eval_gettext "Failed to recurse into submodule path '\$displaypath'")"
893                                 if test $res -eq 1
894                                 then
895                                         err="${err};$die_msg"
896                                         continue
897                                 else
898                                         die_with_status $res "$die_msg"
899                                 fi
900                         fi
901                 fi
902         done
903
904         if test -n "$err"
905         then
906                 OIFS=$IFS
907                 IFS=';'
908                 for e in $err
909                 do
910                         if test -n "$e"
911                         then
912                                 echo >&2 "$e"
913                         fi
914                 done
915                 IFS=$OIFS
916                 exit 1
917         fi
918         }
919 }
920
921 set_name_rev () {
922         revname=$( (
923                 clear_local_git_env
924                 cd "$1" && {
925                         git describe "$2" 2>/dev/null ||
926                         git describe --tags "$2" 2>/dev/null ||
927                         git describe --contains "$2" 2>/dev/null ||
928                         git describe --all --always "$2"
929                 }
930         ) )
931         test -z "$revname" || revname=" ($revname)"
932 }
933 #
934 # Show commit summary for submodules in index or working tree
935 #
936 # If '--cached' is given, show summary between index and given commit,
937 # or between working tree and given commit
938 #
939 # $@ = [commit (default 'HEAD'),] requested paths (default all)
940 #
941 cmd_summary() {
942         summary_limit=-1
943         for_status=
944         diff_cmd=diff-index
945
946         # parse $args after "submodule ... summary".
947         while test $# -ne 0
948         do
949                 case "$1" in
950                 --cached)
951                         cached="$1"
952                         ;;
953                 --files)
954                         files="$1"
955                         ;;
956                 --for-status)
957                         for_status="$1"
958                         ;;
959                 -n|--summary-limit)
960                         summary_limit="$2"
961                         isnumber "$summary_limit" || usage
962                         shift
963                         ;;
964                 --summary-limit=*)
965                         summary_limit="${1#--summary-limit=}"
966                         isnumber "$summary_limit" || usage
967                         ;;
968                 --)
969                         shift
970                         break
971                         ;;
972                 -*)
973                         usage
974                         ;;
975                 *)
976                         break
977                         ;;
978                 esac
979                 shift
980         done
981
982         test $summary_limit = 0 && return
983
984         if rev=$(git rev-parse -q --verify --default HEAD ${1+"$1"})
985         then
986                 head=$rev
987                 test $# = 0 || shift
988         elif test -z "$1" -o "$1" = "HEAD"
989         then
990                 # before the first commit: compare with an empty tree
991                 head=$(git hash-object -w -t tree --stdin </dev/null)
992                 test -z "$1" || shift
993         else
994                 head="HEAD"
995         fi
996
997         if [ -n "$files" ]
998         then
999                 test -n "$cached" &&
1000                 die "$(gettext "The --cached option cannot be used with the --files option")"
1001                 diff_cmd=diff-files
1002                 head=
1003         fi
1004
1005         cd_to_toplevel
1006         eval "set $(git rev-parse --sq --prefix "$wt_prefix" -- "$@")"
1007         # Get modified modules cared by user
1008         modules=$(git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- "$@" |
1009                 sane_egrep '^:([0-7]* )?160000' |
1010                 while read mod_src mod_dst sha1_src sha1_dst status name
1011                 do
1012                         # Always show modules deleted or type-changed (blob<->module)
1013                         test $status = D -o $status = T && echo "$name" && continue
1014                         # Also show added or modified modules which are checked out
1015                         GIT_DIR="$name/.git" git-rev-parse --git-dir >/dev/null 2>&1 &&
1016                         echo "$name"
1017                 done
1018         )
1019
1020         test -z "$modules" && return
1021
1022         git $diff_cmd $cached --ignore-submodules=dirty --raw $head -- $modules |
1023         sane_egrep '^:([0-7]* )?160000' |
1024         cut -c2- |
1025         while read mod_src mod_dst sha1_src sha1_dst status name
1026         do
1027                 if test -z "$cached" &&
1028                         test $sha1_dst = 0000000000000000000000000000000000000000
1029                 then
1030                         case "$mod_dst" in
1031                         160000)
1032                                 sha1_dst=$(GIT_DIR="$name/.git" git rev-parse HEAD)
1033                                 ;;
1034                         100644 | 100755 | 120000)
1035                                 sha1_dst=$(git hash-object $name)
1036                                 ;;
1037                         000000)
1038                                 ;; # removed
1039                         *)
1040                                 # unexpected type
1041                                 eval_gettextln "unexpected mode \$mod_dst" >&2
1042                                 continue ;;
1043                         esac
1044                 fi
1045                 missing_src=
1046                 missing_dst=
1047
1048                 test $mod_src = 160000 &&
1049                 ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_src^0 >/dev/null &&
1050                 missing_src=t
1051
1052                 test $mod_dst = 160000 &&
1053                 ! GIT_DIR="$name/.git" git-rev-parse -q --verify $sha1_dst^0 >/dev/null &&
1054                 missing_dst=t
1055
1056                 display_name=$(relative_path "$name")
1057
1058                 total_commits=
1059                 case "$missing_src,$missing_dst" in
1060                 t,)
1061                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_src")"
1062                         ;;
1063                 ,t)
1064                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commit \$sha1_dst")"
1065                         ;;
1066                 t,t)
1067                         errmsg="$(eval_gettext "  Warn: \$display_name doesn't contain commits \$sha1_src and \$sha1_dst")"
1068                         ;;
1069                 *)
1070                         errmsg=
1071                         total_commits=$(
1072                         if test $mod_src = 160000 -a $mod_dst = 160000
1073                         then
1074                                 range="$sha1_src...$sha1_dst"
1075                         elif test $mod_src = 160000
1076                         then
1077                                 range=$sha1_src
1078                         else
1079                                 range=$sha1_dst
1080                         fi
1081                         GIT_DIR="$name/.git" \
1082                         git rev-list --first-parent $range -- | wc -l
1083                         )
1084                         total_commits=" ($(($total_commits + 0)))"
1085                         ;;
1086                 esac
1087
1088                 sha1_abbr_src=$(echo $sha1_src | cut -c1-7)
1089                 sha1_abbr_dst=$(echo $sha1_dst | cut -c1-7)
1090                 if test $status = T
1091                 then
1092                         blob="$(gettext "blob")"
1093                         submodule="$(gettext "submodule")"
1094                         if test $mod_dst = 160000
1095                         then
1096                                 echo "* $display_name $sha1_abbr_src($blob)->$sha1_abbr_dst($submodule)$total_commits:"
1097                         else
1098                                 echo "* $display_name $sha1_abbr_src($submodule)->$sha1_abbr_dst($blob)$total_commits:"
1099                         fi
1100                 else
1101                         echo "* $display_name $sha1_abbr_src...$sha1_abbr_dst$total_commits:"
1102                 fi
1103                 if test -n "$errmsg"
1104                 then
1105                         # Don't give error msg for modification whose dst is not submodule
1106                         # i.e. deleted or changed to blob
1107                         test $mod_dst = 160000 && echo "$errmsg"
1108                 else
1109                         if test $mod_src = 160000 -a $mod_dst = 160000
1110                         then
1111                                 limit=
1112                                 test $summary_limit -gt 0 && limit="-$summary_limit"
1113                                 GIT_DIR="$name/.git" \
1114                                 git log $limit --pretty='format:  %m %s' \
1115                                 --first-parent $sha1_src...$sha1_dst
1116                         elif test $mod_dst = 160000
1117                         then
1118                                 GIT_DIR="$name/.git" \
1119                                 git log --pretty='format:  > %s' -1 $sha1_dst
1120                         else
1121                                 GIT_DIR="$name/.git" \
1122                                 git log --pretty='format:  < %s' -1 $sha1_src
1123                         fi
1124                         echo
1125                 fi
1126                 echo
1127         done |
1128         if test -n "$for_status"; then
1129                 if [ -n "$files" ]; then
1130                         gettextln "Submodules changed but not updated:" | git stripspace -c
1131                 else
1132                         gettextln "Submodule changes to be committed:" | git stripspace -c
1133                 fi
1134                 printf "\n" | git stripspace -c
1135                 git stripspace -c
1136         else
1137                 cat
1138         fi
1139 }
1140 #
1141 # List all submodules, prefixed with:
1142 #  - submodule not initialized
1143 #  + different revision checked out
1144 #
1145 # If --cached was specified the revision in the index will be printed
1146 # instead of the currently checked out revision.
1147 #
1148 # $@ = requested paths (default to all)
1149 #
1150 cmd_status()
1151 {
1152         # parse $args after "submodule ... status".
1153         while test $# -ne 0
1154         do
1155                 case "$1" in
1156                 -q|--quiet)
1157                         GIT_QUIET=1
1158                         ;;
1159                 --cached)
1160                         cached=1
1161                         ;;
1162                 --recursive)
1163                         recursive=1
1164                         ;;
1165                 --)
1166                         shift
1167                         break
1168                         ;;
1169                 -*)
1170                         usage
1171                         ;;
1172                 *)
1173                         break
1174                         ;;
1175                 esac
1176                 shift
1177         done
1178
1179         module_list "$@" |
1180         while read mode sha1 stage sm_path
1181         do
1182                 die_if_unmatched "$mode"
1183                 name=$(module_name "$sm_path") || exit
1184                 url=$(git config submodule."$name".url)
1185                 displaypath=$(relative_path "$prefix$sm_path")
1186                 if test "$stage" = U
1187                 then
1188                         say "U$sha1 $displaypath"
1189                         continue
1190                 fi
1191                 if test -z "$url" || ! test -d "$sm_path"/.git -o -f "$sm_path"/.git
1192                 then
1193                         say "-$sha1 $displaypath"
1194                         continue;
1195                 fi
1196                 set_name_rev "$sm_path" "$sha1"
1197                 if git diff-files --ignore-submodules=dirty --quiet -- "$sm_path"
1198                 then
1199                         say " $sha1 $displaypath$revname"
1200                 else
1201                         if test -z "$cached"
1202                         then
1203                                 sha1=$(clear_local_git_env; cd "$sm_path" && git rev-parse --verify HEAD)
1204                                 set_name_rev "$sm_path" "$sha1"
1205                         fi
1206                         say "+$sha1 $displaypath$revname"
1207                 fi
1208
1209                 if test -n "$recursive"
1210                 then
1211                         (
1212                                 prefix="$displaypath/"
1213                                 clear_local_git_env
1214                                 cd "$sm_path" &&
1215                                 eval cmd_status
1216                         ) ||
1217                         die "$(eval_gettext "Failed to recurse into submodule path '\$sm_path'")"
1218                 fi
1219         done
1220 }
1221 #
1222 # Sync remote urls for submodules
1223 # This makes the value for remote.$remote.url match the value
1224 # specified in .gitmodules.
1225 #
1226 cmd_sync()
1227 {
1228         while test $# -ne 0
1229         do
1230                 case "$1" in
1231                 -q|--quiet)
1232                         GIT_QUIET=1
1233                         shift
1234                         ;;
1235                 --recursive)
1236                         recursive=1
1237                         shift
1238                         ;;
1239                 --)
1240                         shift
1241                         break
1242                         ;;
1243                 -*)
1244                         usage
1245                         ;;
1246                 *)
1247                         break
1248                         ;;
1249                 esac
1250         done
1251         cd_to_toplevel
1252         module_list "$@" |
1253         while read mode sha1 stage sm_path
1254         do
1255                 die_if_unmatched "$mode"
1256                 name=$(module_name "$sm_path")
1257                 url=$(git config -f .gitmodules --get submodule."$name".url)
1258
1259                 # Possibly a url relative to parent
1260                 case "$url" in
1261                 ./*|../*)
1262                         # rewrite foo/bar as ../.. to find path from
1263                         # submodule work tree to superproject work tree
1264                         up_path="$(echo "$sm_path" | sed "s/[^/][^/]*/../g")" &&
1265                         # guarantee a trailing /
1266                         up_path=${up_path%/}/ &&
1267                         # path from submodule work tree to submodule origin repo
1268                         sub_origin_url=$(resolve_relative_url "$url" "$up_path") &&
1269                         # path from superproject work tree to submodule origin repo
1270                         super_config_url=$(resolve_relative_url "$url") || exit
1271                         ;;
1272                 *)
1273                         sub_origin_url="$url"
1274                         super_config_url="$url"
1275                         ;;
1276                 esac
1277
1278                 if git config "submodule.$name.url" >/dev/null 2>/dev/null
1279                 then
1280                         displaypath=$(relative_path "$prefix$sm_path")
1281                         say "$(eval_gettext "Synchronizing submodule url for '\$displaypath'")"
1282                         git config submodule."$name".url "$super_config_url"
1283
1284                         if test -e "$sm_path"/.git
1285                         then
1286                         (
1287                                 clear_local_git_env
1288                                 cd "$sm_path"
1289                                 remote=$(get_default_remote)
1290                                 git config remote."$remote".url "$sub_origin_url"
1291
1292                                 if test -n "$recursive"
1293                                 then
1294                                         prefix="$prefix$sm_path/"
1295                                         eval cmd_sync
1296                                 fi
1297                         )
1298                         fi
1299                 fi
1300         done
1301 }
1302
1303 # This loop parses the command line arguments to find the
1304 # subcommand name to dispatch.  Parsing of the subcommand specific
1305 # options are primarily done by the subcommand implementations.
1306 # Subcommand specific options such as --branch and --cached are
1307 # parsed here as well, for backward compatibility.
1308
1309 while test $# != 0 && test -z "$command"
1310 do
1311         case "$1" in
1312         add | foreach | init | deinit | update | status | summary | sync)
1313                 command=$1
1314                 ;;
1315         -q|--quiet)
1316                 GIT_QUIET=1
1317                 ;;
1318         -b|--branch)
1319                 case "$2" in
1320                 '')
1321                         usage
1322                         ;;
1323                 esac
1324                 branch="$2"; shift
1325                 ;;
1326         --cached)
1327                 cached="$1"
1328                 ;;
1329         --)
1330                 break
1331                 ;;
1332         -*)
1333                 usage
1334                 ;;
1335         *)
1336                 break
1337                 ;;
1338         esac
1339         shift
1340 done
1341
1342 # No command word defaults to "status"
1343 if test -z "$command"
1344 then
1345     if test $# = 0
1346     then
1347         command=status
1348     else
1349         usage
1350     fi
1351 fi
1352
1353 # "-b branch" is accepted only by "add"
1354 if test -n "$branch" && test "$command" != add
1355 then
1356         usage
1357 fi
1358
1359 # "--cached" is accepted only by "status" and "summary"
1360 if test -n "$cached" && test "$command" != status -a "$command" != summary
1361 then
1362         usage
1363 fi
1364
1365 "cmd_$command" "$@"