Makefile: restrict -Wpedantic and -Wno-pedantic-ms-format better
[git/debian.git] / git-submodule.sh
blob27efdc57740fe408d629059cc57a52d0815e55b7
1 #!/bin/sh
3 # git-submodule.sh: add, init, update or list git submodules
5 # Copyright (c) 2007 Lars Hjemli
7 dashless=$(basename "$0" | sed -e 's/-/ /')
8 USAGE="[--quiet] [--cached]
9 or: $dashless [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
10 or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
11 or: $dashless [--quiet] init [--] [<path>...]
12 or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
13 or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] [--] [<path>...]
14 or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
15 or: $dashless [--quiet] set-url [--] <path> <newurl>
16 or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
17 or: $dashless [--quiet] foreach [--recursive] <command>
18 or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
19 or: $dashless [--quiet] absorbgitdirs [--] [<path>...]"
20 OPTIONS_SPEC=
21 SUBDIRECTORY_OK=Yes
22 . git-sh-setup
23 require_work_tree
24 wt_prefix=$(git rev-parse --show-prefix)
25 cd_to_toplevel
27 # Tell the rest of git that any URLs we get don't come
28 # directly from the user, so it can apply policy as appropriate.
29 GIT_PROTOCOL_FROM_USER=0
30 export GIT_PROTOCOL_FROM_USER
32 command=
33 branch=
34 force=
35 reference=
36 cached=
37 recursive=
38 init=
39 require_init=
40 files=
41 remote=
42 nofetch=
43 update=
44 prefix=
45 custom_name=
46 depth=
47 progress=
48 dissociate=
49 single_branch=
50 jobs=
51 recommend_shallow=
53 die_if_unmatched ()
55 if test "$1" = "#unmatched"
56 then
57 exit ${2:-1}
61 isnumber()
63 n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
66 # Given a full hex object ID, is this the zero OID?
67 is_zero_oid () {
68 echo "$1" | sane_egrep '^0+$' >/dev/null 2>&1
71 # Sanitize the local git environment for use within a submodule. We
72 # can't simply use clear_local_git_env since we want to preserve some
73 # of the settings from GIT_CONFIG_PARAMETERS.
74 sanitize_submodule_env()
76 save_config=$GIT_CONFIG_PARAMETERS
77 clear_local_git_env
78 GIT_CONFIG_PARAMETERS=$save_config
79 export GIT_CONFIG_PARAMETERS
83 # Add a new submodule to the working tree, .gitmodules and the index
85 # $@ = repo path
87 # optional branch is stored in global branch variable
89 cmd_add()
91 # parse $args after "submodule ... add".
92 reference_path=
93 while test $# -ne 0
95 case "$1" in
96 -b | --branch)
97 case "$2" in '') usage ;; esac
98 branch=$2
99 shift
101 -f | --force)
102 force=$1
104 -q|--quiet)
105 GIT_QUIET=1
107 --progress)
108 progress=1
110 --reference)
111 case "$2" in '') usage ;; esac
112 reference_path=$2
113 shift
115 --reference=*)
116 reference_path="${1#--reference=}"
118 --dissociate)
119 dissociate=1
121 --name)
122 case "$2" in '') usage ;; esac
123 custom_name=$2
124 shift
126 --depth)
127 case "$2" in '') usage ;; esac
128 depth="--depth=$2"
129 shift
131 --depth=*)
132 depth=$1
135 shift
136 break
139 usage
142 break
144 esac
145 shift
146 done
148 if test -z "$1"
149 then
150 usage
153 git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper add ${GIT_QUIET:+--quiet} ${force:+--force} ${progress:+"--progress"} ${branch:+--branch "$branch"} ${reference_path:+--reference "$reference_path"} ${dissociate:+--dissociate} ${custom_name:+--name "$custom_name"} ${depth:+"$depth"} -- "$@"
157 # Execute an arbitrary command sequence in each checked out
158 # submodule
160 # $@ = command to execute
162 cmd_foreach()
164 # parse $args after "submodule ... foreach".
165 while test $# -ne 0
167 case "$1" in
168 -q|--quiet)
169 GIT_QUIET=1
171 --recursive)
172 recursive=1
175 usage
178 break
180 esac
181 shift
182 done
184 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
188 # Register submodules in .git/config
190 # $@ = requested paths (default to all)
192 cmd_init()
194 # parse $args after "submodule ... init".
195 while test $# -ne 0
197 case "$1" in
198 -q|--quiet)
199 GIT_QUIET=1
202 shift
203 break
206 usage
209 break
211 esac
212 shift
213 done
215 git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper init ${GIT_QUIET:+--quiet} -- "$@"
219 # Unregister submodules from .git/config and remove their work tree
221 cmd_deinit()
223 # parse $args after "submodule ... deinit".
224 deinit_all=
225 while test $# -ne 0
227 case "$1" in
228 -f|--force)
229 force=$1
231 -q|--quiet)
232 GIT_QUIET=1
234 --all)
235 deinit_all=t
238 shift
239 break
242 usage
245 break
247 esac
248 shift
249 done
251 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@"
254 # usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]
255 # Because arguments are positional, use an empty string to omit <depth>
256 # but include <sha1>.
257 fetch_in_submodule () (
258 sanitize_submodule_env &&
259 cd "$1" &&
260 if test $# -eq 3
261 then
262 echo "$3" | git fetch ${GIT_QUIET:+--quiet} --stdin ${2:+"$2"}
263 else
264 git fetch ${GIT_QUIET:+--quiet} ${2:+"$2"}
269 # Update each submodule path to correct revision, using clone and checkout as needed
271 # $@ = requested paths (default to all)
273 cmd_update()
275 # parse $args after "submodule ... update".
276 while test $# -ne 0
278 case "$1" in
279 -q|--quiet)
280 GIT_QUIET=1
283 unset GIT_QUIET
285 --progress)
286 progress=1
288 -i|--init)
289 init=1
291 --require-init)
292 init=1
293 require_init=1
295 --remote)
296 remote=1
298 -N|--no-fetch)
299 nofetch=1
301 -f|--force)
302 force=$1
304 -r|--rebase)
305 update="rebase"
307 --reference)
308 case "$2" in '') usage ;; esac
309 reference="--reference=$2"
310 shift
312 --reference=*)
313 reference="$1"
315 --dissociate)
316 dissociate=1
318 -m|--merge)
319 update="merge"
321 --recursive)
322 recursive=1
324 --checkout)
325 update="checkout"
327 --recommend-shallow)
328 recommend_shallow="--recommend-shallow"
330 --no-recommend-shallow)
331 recommend_shallow="--no-recommend-shallow"
333 --depth)
334 case "$2" in '') usage ;; esac
335 depth="--depth=$2"
336 shift
338 --depth=*)
339 depth=$1
341 -j|--jobs)
342 case "$2" in '') usage ;; esac
343 jobs="--jobs=$2"
344 shift
346 --jobs=*)
347 jobs=$1
349 --single-branch)
350 single_branch="--single-branch"
352 --no-single-branch)
353 single_branch="--no-single-branch"
356 shift
357 break
360 usage
363 break
365 esac
366 shift
367 done
369 if test -n "$init"
370 then
371 cmd_init "--" "$@" || return
375 git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
376 ${progress:+"--progress"} \
377 ${wt_prefix:+--prefix "$wt_prefix"} \
378 ${prefix:+--recursive-prefix "$prefix"} \
379 ${update:+--update "$update"} \
380 ${reference:+"$reference"} \
381 ${dissociate:+"--dissociate"} \
382 ${depth:+--depth "$depth"} \
383 ${require_init:+--require-init} \
384 $single_branch \
385 $recommend_shallow \
386 $jobs \
387 -- \
388 "$@" || echo "#unmatched" $?
389 } | {
390 err=
391 while read -r quickabort sha1 just_cloned sm_path
393 die_if_unmatched "$quickabort" "$sha1"
395 git submodule--helper ensure-core-worktree "$sm_path" || exit 1
397 displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
399 if test $just_cloned -eq 1
400 then
401 subsha1=
402 else
403 just_cloned=
404 subsha1=$(sanitize_submodule_env; cd "$sm_path" &&
405 git rev-parse --verify HEAD) ||
406 die "fatal: $(eval_gettext "Unable to find current revision in submodule path '\$displaypath'")"
409 if test -n "$remote"
410 then
411 branch=$(git submodule--helper remote-branch "$sm_path")
412 if test -z "$nofetch"
413 then
414 # Fetch remote before determining tracking $sha1
415 fetch_in_submodule "$sm_path" $depth ||
416 die "fatal: $(eval_gettext "Unable to fetch in submodule path '\$sm_path'")"
418 remote_name=$(sanitize_submodule_env; cd "$sm_path" && git submodule--helper print-default-remote)
419 sha1=$(sanitize_submodule_env; cd "$sm_path" &&
420 git rev-parse --verify "${remote_name}/${branch}") ||
421 die "fatal: $(eval_gettext "Unable to find current \${remote_name}/\${branch} revision in submodule path '\$sm_path'")"
424 out=$(git submodule--helper run-update-procedure \
425 ${wt_prefix:+--prefix "$wt_prefix"} \
426 ${GIT_QUIET:+--quiet} \
427 ${force:+--force} \
428 ${just_cloned:+--just-cloned} \
429 ${nofetch:+--no-fetch} \
430 ${depth:+"$depth"} \
431 ${update:+--update "$update"} \
432 ${prefix:+--recursive-prefix "$prefix"} \
433 ${sha1:+--oid "$sha1"} \
434 ${subsha1:+--suboid "$subsha1"} \
435 "--" \
436 "$sm_path")
438 # exit codes for run-update-procedure:
439 # 0: update was successful, say command output
440 # 1: update procedure failed, but should not die
441 # 2 or 128: subcommand died during execution
442 # 3: no update procedure was run
443 res="$?"
444 case $res in
446 say "$out"
449 err="${err};fatal: $out"
450 continue
452 2|128)
453 die_with_status $res "fatal: $out"
455 esac
457 if test -n "$recursive"
458 then
460 prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix")
461 wt_prefix=
462 sanitize_submodule_env
463 cd "$sm_path" &&
464 eval cmd_update
466 res=$?
467 if test $res -gt 0
468 then
469 die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")"
470 if test $res -ne 2
471 then
472 err="${err};$die_msg"
473 continue
474 else
475 die_with_status $res "$die_msg"
479 done
481 if test -n "$err"
482 then
483 OIFS=$IFS
484 IFS=';'
485 for e in $err
487 if test -n "$e"
488 then
489 echo >&2 "$e"
491 done
492 IFS=$OIFS
493 exit 1
499 # Configures a submodule's default branch
501 # $@ = requested path
503 cmd_set_branch() {
504 default=
505 branch=
507 while test $# -ne 0
509 case "$1" in
510 -q|--quiet)
511 # we don't do anything with this but we need to accept it
513 -d|--default)
514 default=1
516 -b|--branch)
517 case "$2" in '') usage ;; esac
518 branch=$2
519 shift
522 shift
523 break
526 usage
529 break
531 esac
532 shift
533 done
535 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-branch ${GIT_QUIET:+--quiet} ${branch:+--branch "$branch"} ${default:+--default} -- "$@"
539 # Configures a submodule's remote url
541 # $@ = requested path, requested url
543 cmd_set_url() {
544 while test $# -ne 0
546 case "$1" in
547 -q|--quiet)
548 GIT_QUIET=1
551 shift
552 break
555 usage
558 break
560 esac
561 shift
562 done
564 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-url ${GIT_QUIET:+--quiet} -- "$@"
568 # Show commit summary for submodules in index or working tree
570 # If '--cached' is given, show summary between index and given commit,
571 # or between working tree and given commit
573 # $@ = [commit (default 'HEAD'),] requested paths (default all)
575 cmd_summary() {
576 summary_limit=-1
577 for_status=
578 diff_cmd=diff-index
580 # parse $args after "submodule ... summary".
581 while test $# -ne 0
583 case "$1" in
584 --cached)
585 cached="$1"
587 --files)
588 files="$1"
590 --for-status)
591 for_status="$1"
593 -n|--summary-limit)
594 summary_limit="$2"
595 isnumber "$summary_limit" || usage
596 shift
598 --summary-limit=*)
599 summary_limit="${1#--summary-limit=}"
600 isnumber "$summary_limit" || usage
603 shift
604 break
607 usage
610 break
612 esac
613 shift
614 done
616 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
619 # List all submodules, prefixed with:
620 # - submodule not initialized
621 # + different revision checked out
623 # If --cached was specified the revision in the index will be printed
624 # instead of the currently checked out revision.
626 # $@ = requested paths (default to all)
628 cmd_status()
630 # parse $args after "submodule ... status".
631 while test $# -ne 0
633 case "$1" in
634 -q|--quiet)
635 GIT_QUIET=1
637 --cached)
638 cached=1
640 --recursive)
641 recursive=1
644 shift
645 break
648 usage
651 break
653 esac
654 shift
655 done
657 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} -- "$@"
660 # Sync remote urls for submodules
661 # This makes the value for remote.$remote.url match the value
662 # specified in .gitmodules.
664 cmd_sync()
666 while test $# -ne 0
668 case "$1" in
669 -q|--quiet)
670 GIT_QUIET=1
671 shift
673 --recursive)
674 recursive=1
675 shift
678 shift
679 break
682 usage
685 break
687 esac
688 done
690 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper sync ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
693 cmd_absorbgitdirs()
695 git submodule--helper absorb-git-dirs --prefix "$wt_prefix" "$@"
698 # This loop parses the command line arguments to find the
699 # subcommand name to dispatch. Parsing of the subcommand specific
700 # options are primarily done by the subcommand implementations.
701 # Subcommand specific options such as --branch and --cached are
702 # parsed here as well, for backward compatibility.
704 while test $# != 0 && test -z "$command"
706 case "$1" in
707 add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
708 command=$1
710 -q|--quiet)
711 GIT_QUIET=1
713 -b|--branch)
714 case "$2" in
716 usage
718 esac
719 branch="$2"; shift
721 --cached)
722 cached="$1"
725 break
728 usage
731 break
733 esac
734 shift
735 done
737 # No command word defaults to "status"
738 if test -z "$command"
739 then
740 if test $# = 0
741 then
742 command=status
743 else
744 usage
748 # "-b branch" is accepted only by "add" and "set-branch"
749 if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
750 then
751 usage
754 # "--cached" is accepted only by "status" and "summary"
755 if test -n "$cached" && test "$command" != status && test "$command" != summary
756 then
757 usage
760 "cmd_$(echo $command | sed -e s/-/_/g)" "$@"