]> git.ipfire.org Git - thirdparty/git.git/blame - git-submodule.sh
submodule--helper: allow setting superprefix for init_submodule()
[thirdparty/git.git] / git-submodule.sh
CommitLineData
70c7ac22
LH
1#!/bin/sh
2#
4c8a9db6 3# git-submodule.sh: add, init, update or list git submodules
70c7ac22
LH
4#
5# Copyright (c) 2007 Lars Hjemli
6
1d5bec8b 7dashless=$(basename "$0" | sed -e 's/-/ /')
68cabbfd
DL
8USAGE="[--quiet] [--cached]
9 or: $dashless [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>]
64b19ffe 10 or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
1d5bec8b 11 or: $dashless [--quiet] init [--] [<path>...]
f6a52799 12 or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...)
f05da2b4 13 or: $dashless [--quiet] update [--init [--filter=<filter-spec>]] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] [--] [<path>...]
b57e8119 14 or: $dashless [--quiet] set-branch (--default|--branch <branch>) [--] <path>
26b06100 15 or: $dashless [--quiet] set-url [--] <path> <newurl>
adc54235 16 or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
15fc56a8 17 or: $dashless [--quiet] foreach [--recursive] <command>
c32eaa8a
SB
18 or: $dashless [--quiet] sync [--recursive] [--] [<path>...]
19 or: $dashless [--quiet] absorbgitdirs [--] [<path>...]"
8f321a39 20OPTIONS_SPEC=
091a6eb0 21SUBDIRECTORY_OK=Yes
70c7ac22
LH
22. git-sh-setup
23require_work_tree
091a6eb0
JK
24wt_prefix=$(git rev-parse --show-prefix)
25cd_to_toplevel
70c7ac22 26
f1762d77
BW
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.
29GIT_PROTOCOL_FROM_USER=0
30export GIT_PROTOCOL_FROM_USER
33cfccbb 31
5c08dbbd 32command=
ecda0723 33branch=
d27b876b 34force=
d92a3959 35reference=
70c7ac22 36cached=
48bb3033
GP
37recursive=
38init=
0060fd15 39require_init=
1c244f6e 40files=
06b1abb5 41remote=
31ca3ac3 42nofetch=
32948425 43update=
15fc56a8 44prefix=
73b0898d 45custom_name=
275cd184 46depth=
72c5f883 47progress=
a0ef2934 48dissociate=
132f600b 49single_branch=
65d100c4
LX
50jobs=
51recommend_shallow=
f05da2b4 52filter=
70c7ac22 53
be9d0a3a
HV
54die_if_unmatched ()
55{
56 if test "$1" = "#unmatched"
57 then
c4c02bf1 58 exit ${2:-1}
be9d0a3a
HV
59 fi
60}
61
862ae6cd
RS
62isnumber()
63{
64 n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
65}
66
14111fc4
JK
67# Sanitize the local git environment for use within a submodule. We
68# can't simply use clear_local_git_env since we want to preserve some
69# of the settings from GIT_CONFIG_PARAMETERS.
70sanitize_submodule_env()
71{
89044baa 72 save_config=$GIT_CONFIG_PARAMETERS
14111fc4 73 clear_local_git_env
89044baa 74 GIT_CONFIG_PARAMETERS=$save_config
860cba61 75 export GIT_CONFIG_PARAMETERS
14111fc4
JK
76}
77
ecda0723
SV
78#
79# Add a new submodule to the working tree, .gitmodules and the index
80#
ec05df35 81# $@ = repo path
ecda0723
SV
82#
83# optional branch is stored in global branch variable
84#
23a485e3 85cmd_add()
ecda0723 86{
5c08dbbd 87 # parse $args after "submodule ... add".
091a6eb0 88 reference_path=
5c08dbbd
JH
89 while test $# -ne 0
90 do
91 case "$1" in
92 -b | --branch)
93 case "$2" in '') usage ;; esac
94 branch=$2
95 shift
96 ;;
d27b876b
JL
97 -f | --force)
98 force=$1
99 ;;
5c08dbbd 100 -q|--quiet)
2e6a30ef 101 GIT_QUIET=1
5c08dbbd 102 ;;
6d33e1c2
CF
103 --progress)
104 progress=1
105 ;;
d92a3959
MT
106 --reference)
107 case "$2" in '') usage ;; esac
091a6eb0 108 reference_path=$2
d92a3959
MT
109 shift
110 ;;
111 --reference=*)
091a6eb0 112 reference_path="${1#--reference=}"
d92a3959 113 ;;
a0ef2934
CF
114 --dissociate)
115 dissociate=1
116 ;;
73b0898d
JL
117 --name)
118 case "$2" in '') usage ;; esac
119 custom_name=$2
120 shift
121 ;;
275cd184
FG
122 --depth)
123 case "$2" in '') usage ;; esac
124 depth="--depth=$2"
125 shift
126 ;;
127 --depth=*)
128 depth=$1
129 ;;
5c08dbbd
JH
130 --)
131 shift
132 break
133 ;;
134 -*)
135 usage
136 ;;
137 *)
138 break
139 ;;
140 esac
141 shift
142 done
143
a6226fd7 144 if test -z "$1"
76e9bdc4 145 then
ecda0723
SV
146 usage
147 fi
148
a6226fd7 149 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"} -- "$@"
ecda0723
SV
150}
151
19a31f9c
ML
152#
153# Execute an arbitrary command sequence in each checked out
154# submodule
155#
156# $@ = command to execute
157#
158cmd_foreach()
159{
1d5bec8b
JH
160 # parse $args after "submodule ... foreach".
161 while test $# -ne 0
162 do
163 case "$1" in
164 -q|--quiet)
165 GIT_QUIET=1
166 ;;
15fc56a8
JH
167 --recursive)
168 recursive=1
169 ;;
1d5bec8b
JH
170 -*)
171 usage
172 ;;
173 *)
174 break
175 ;;
176 esac
177 shift
178 done
179
1cf823d8 180 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
19a31f9c
ML
181}
182
70c7ac22 183#
211b7f19 184# Register submodules in .git/config
70c7ac22
LH
185#
186# $@ = requested paths (default to all)
187#
23a485e3 188cmd_init()
70c7ac22 189{
5c08dbbd
JH
190 # parse $args after "submodule ... init".
191 while test $# -ne 0
192 do
193 case "$1" in
194 -q|--quiet)
2e6a30ef 195 GIT_QUIET=1
5c08dbbd
JH
196 ;;
197 --)
198 shift
199 break
200 ;;
201 -*)
202 usage
203 ;;
204 *)
205 break
206 ;;
207 esac
208 shift
209 done
210
a282f5a9 211 git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper init ${GIT_QUIET:+--quiet} -- "$@"
70c7ac22
LH
212}
213
cf419828
JL
214#
215# Unregister submodules from .git/config and remove their work tree
216#
cf419828
JL
217cmd_deinit()
218{
219 # parse $args after "submodule ... deinit".
f6a52799 220 deinit_all=
cf419828
JL
221 while test $# -ne 0
222 do
223 case "$1" in
224 -f|--force)
225 force=$1
226 ;;
227 -q|--quiet)
228 GIT_QUIET=1
229 ;;
f6a52799
SB
230 --all)
231 deinit_all=t
232 ;;
cf419828
JL
233 --)
234 shift
235 break
236 ;;
237 -*)
238 usage
239 ;;
240 *)
241 break
242 ;;
243 esac
244 shift
245 done
246
1cf823d8 247 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@"
cf419828
JL
248}
249
70c7ac22 250#
211b7f19 251# Update each submodule path to correct revision, using clone and checkout as needed
70c7ac22
LH
252#
253# $@ = requested paths (default to all)
254#
23a485e3 255cmd_update()
70c7ac22 256{
5c08dbbd
JH
257 # parse $args after "submodule ... update".
258 while test $# -ne 0
259 do
260 case "$1" in
261 -q|--quiet)
2e6a30ef 262 GIT_QUIET=1
5c08dbbd 263 ;;
e84c3cf3 264 -v)
3ad0401e 265 unset GIT_QUIET
e84c3cf3 266 ;;
72c5f883 267 --progress)
c7199e3a 268 progress=1
72c5f883 269 ;;
be4d2c83 270 -i|--init)
d92a3959 271 init=1
be4d2c83 272 ;;
0060fd15
JS
273 --require-init)
274 init=1
275 require_init=1
276 ;;
06b1abb5
TK
277 --remote)
278 remote=1
279 ;;
31ca3ac3 280 -N|--no-fetch)
31ca3ac3
FF
281 nofetch=1
282 ;;
9db31bdf
NMC
283 -f|--force)
284 force=$1
285 ;;
ca2cedba 286 -r|--rebase)
32948425 287 update="rebase"
ca2cedba 288 ;;
d92a3959
MT
289 --reference)
290 case "$2" in '') usage ;; esac
291 reference="--reference=$2"
98dbe63d 292 shift
d92a3959
MT
293 ;;
294 --reference=*)
295 reference="$1"
d92a3959 296 ;;
a0ef2934
CF
297 --dissociate)
298 dissociate=1
299 ;;
42b49178 300 -m|--merge)
42b49178
JH
301 update="merge"
302 ;;
b13fd5c1 303 --recursive)
b13fd5c1
JH
304 recursive=1
305 ;;
efc5fb6a
JH
306 --checkout)
307 update="checkout"
308 ;;
abed000a
SB
309 --recommend-shallow)
310 recommend_shallow="--recommend-shallow"
311 ;;
312 --no-recommend-shallow)
313 recommend_shallow="--no-recommend-shallow"
314 ;;
275cd184
FG
315 --depth)
316 case "$2" in '') usage ;; esac
317 depth="--depth=$2"
318 shift
319 ;;
320 --depth=*)
321 depth=$1
322 ;;
2335b870
SB
323 -j|--jobs)
324 case "$2" in '') usage ;; esac
325 jobs="--jobs=$2"
326 shift
327 ;;
328 --jobs=*)
329 jobs=$1
330 ;;
132f600b
ES
331 --single-branch)
332 single_branch="--single-branch"
333 ;;
334 --no-single-branch)
335 single_branch="--no-single-branch"
336 ;;
f05da2b4
JS
337 --filter)
338 case "$2" in '') usage ;; esac
339 filter="--filter=$2"
340 shift
341 ;;
342 --filter=*)
343 filter="$1"
344 ;;
5c08dbbd
JH
345 --)
346 shift
347 break
348 ;;
349 -*)
350 usage
351 ;;
352 *)
353 break
354 ;;
355 esac
98dbe63d 356 shift
5c08dbbd
JH
357 done
358
f05da2b4
JS
359 if test -n "$filter" && test "$init" != "1"
360 then
361 usage
362 fi
363
d92a3959
MT
364 if test -n "$init"
365 then
366 cmd_init "--" "$@" || return
367 fi
368
48308681
SB
369 {
370 git submodule--helper update-clone ${GIT_QUIET:+--quiet} \
c7199e3a 371 ${progress:+"--progress"} \
48308681
SB
372 ${wt_prefix:+--prefix "$wt_prefix"} \
373 ${prefix:+--recursive-prefix "$prefix"} \
374 ${update:+--update "$update"} \
5f50f33e 375 ${reference:+"$reference"} \
a0ef2934 376 ${dissociate:+"--dissociate"} \
48308681 377 ${depth:+--depth "$depth"} \
0060fd15 378 ${require_init:+--require-init} \
132f600b 379 $single_branch \
c7199e3a
CF
380 $recommend_shallow \
381 $jobs \
f05da2b4 382 $filter \
a282f5a9 383 -- \
c4c02bf1 384 "$@" || echo "#unmatched" $?
48308681 385 } | {
15ffb7cd 386 err=
9eca701f 387 while read -r quickabort sha1 just_cloned sm_path
70c7ac22 388 do
9eca701f 389 die_if_unmatched "$quickabort" "$sha1"
48308681 390
5d124f41 391 git submodule--helper ensure-core-worktree "$sm_path" || exit 1
74d4731d 392
44431df0 393 displaypath=$(git submodule--helper relative-path "$prefix$sm_path" "$wt_prefix")
091a6eb0 394
e4419665 395 if test $just_cloned -eq 0
d851ffb9 396 then
c51f8f94 397 just_cloned=
70c7ac22 398 fi
211b7f19 399
c51f8f94
AR
400 out=$(git submodule--helper run-update-procedure \
401 ${wt_prefix:+--prefix "$wt_prefix"} \
402 ${GIT_QUIET:+--quiet} \
403 ${force:+--force} \
404 ${just_cloned:+--just-cloned} \
405 ${nofetch:+--no-fetch} \
406 ${depth:+"$depth"} \
407 ${update:+--update "$update"} \
408 ${prefix:+--recursive-prefix "$prefix"} \
409 ${sha1:+--oid "$sha1"} \
1012a5cb 410 ${remote:+--remote} \
c51f8f94
AR
411 "--" \
412 "$sm_path")
413
414 # exit codes for run-update-procedure:
415 # 0: update was successful, say command output
416 # 1: update procedure failed, but should not die
417 # 2 or 128: subcommand died during execution
418 # 3: no update procedure was run
419 res="$?"
420 case $res in
421 0)
422 say "$out"
423 ;;
424 1)
425 err="${err};fatal: $out"
426 continue
427 ;;
428 2|128)
429 die_with_status $res "fatal: $out"
430 ;;
431 esac
b13fd5c1
JH
432
433 if test -n "$recursive"
434 then
75bf5e60 435 (
44431df0 436 prefix=$(git submodule--helper relative-path "$prefix$sm_path/" "$wt_prefix")
3604242f 437 wt_prefix=
14111fc4 438 sanitize_submodule_env
75bf5e60 439 cd "$sm_path" &&
36141282 440 eval cmd_update
75bf5e60 441 )
15ffb7cd
FG
442 res=$?
443 if test $res -gt 0
444 then
0008d122 445 die_msg="fatal: $(eval_gettext "Failed to recurse into submodule path '\$displaypath'")"
bb9d91b4 446 if test $res -ne 2
15ffb7cd 447 then
ff968f03 448 err="${err};$die_msg"
15ffb7cd
FG
449 continue
450 else
ff968f03 451 die_with_status $res "$die_msg"
15ffb7cd
FG
452 fi
453 fi
b13fd5c1 454 fi
70c7ac22 455 done
15ffb7cd
FG
456
457 if test -n "$err"
458 then
459 OIFS=$IFS
460 IFS=';'
461 for e in $err
462 do
463 if test -n "$e"
464 then
465 echo >&2 "$e"
466 fi
467 done
468 IFS=$OIFS
469 exit 1
470 fi
471 }
70c7ac22
LH
472}
473
b57e8119
DL
474#
475# Configures a submodule's default branch
476#
477# $@ = requested path
478#
479cmd_set_branch() {
2964d6e5 480 default=
b57e8119
DL
481 branch=
482
483 while test $# -ne 0
484 do
485 case "$1" in
486 -q|--quiet)
487 # we don't do anything with this but we need to accept it
488 ;;
489 -d|--default)
2964d6e5 490 default=1
b57e8119
DL
491 ;;
492 -b|--branch)
493 case "$2" in '') usage ;; esac
494 branch=$2
495 shift
496 ;;
497 --)
498 shift
499 break
500 ;;
501 -*)
502 usage
503 ;;
504 *)
505 break
506 ;;
507 esac
508 shift
509 done
510
1cf823d8 511 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-branch ${GIT_QUIET:+--quiet} ${branch:+--branch "$branch"} ${default:+--default} -- "$@"
b57e8119
DL
512}
513
26b06100
DL
514#
515# Configures a submodule's remote url
516#
517# $@ = requested path, requested url
518#
519cmd_set_url() {
520 while test $# -ne 0
521 do
522 case "$1" in
523 -q|--quiet)
524 GIT_QUIET=1
525 ;;
526 --)
527 shift
528 break
529 ;;
530 -*)
531 usage
532 ;;
533 *)
534 break
535 ;;
536 esac
537 shift
538 done
539
1cf823d8 540 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-url ${GIT_QUIET:+--quiet} -- "$@"
26b06100
DL
541}
542
28f9af5d
PY
543#
544# Show commit summary for submodules in index or working tree
545#
546# If '--cached' is given, show summary between index and given commit,
547# or between working tree and given commit
548#
549# $@ = [commit (default 'HEAD'),] requested paths (default all)
550#
551cmd_summary() {
f2dc06a3 552 summary_limit=-1
d0f64dd4 553 for_status=
1c244f6e 554 diff_cmd=diff-index
f2dc06a3 555
28f9af5d
PY
556 # parse $args after "submodule ... summary".
557 while test $# -ne 0
558 do
559 case "$1" in
560 --cached)
561 cached="$1"
562 ;;
1c244f6e
JL
563 --files)
564 files="$1"
565 ;;
d0f64dd4
PY
566 --for-status)
567 for_status="$1"
568 ;;
f2dc06a3 569 -n|--summary-limit)
862ae6cd
RS
570 summary_limit="$2"
571 isnumber "$summary_limit" || usage
f2dc06a3
PY
572 shift
573 ;;
862ae6cd
RS
574 --summary-limit=*)
575 summary_limit="${1#--summary-limit=}"
576 isnumber "$summary_limit" || usage
577 ;;
28f9af5d
PY
578 --)
579 shift
580 break
581 ;;
582 -*)
583 usage
584 ;;
585 *)
586 break
587 ;;
588 esac
589 shift
590 done
bffe71f4 591
1cf823d8 592 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
28f9af5d 593}
70c7ac22 594#
941987a5 595# List all submodules, prefixed with:
70c7ac22
LH
596# - submodule not initialized
597# + different revision checked out
598#
599# If --cached was specified the revision in the index will be printed
600# instead of the currently checked out revision.
601#
602# $@ = requested paths (default to all)
603#
23a485e3 604cmd_status()
70c7ac22 605{
5c08dbbd
JH
606 # parse $args after "submodule ... status".
607 while test $# -ne 0
608 do
609 case "$1" in
610 -q|--quiet)
2e6a30ef 611 GIT_QUIET=1
5c08dbbd
JH
612 ;;
613 --cached)
614 cached=1
615 ;;
64b19ffe
JH
616 --recursive)
617 recursive=1
618 ;;
5c08dbbd
JH
619 --)
620 shift
621 break
622 ;;
623 -*)
624 usage
625 ;;
626 *)
627 break
628 ;;
629 esac
630 shift
631 done
632
1cf823d8 633 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} -- "$@"
70c7ac22 634}
2327f61e
DA
635#
636# Sync remote urls for submodules
637# This makes the value for remote.$remote.url match the value
638# specified in .gitmodules.
639#
640cmd_sync()
641{
642 while test $# -ne 0
643 do
644 case "$1" in
645 -q|--quiet)
2e6a30ef 646 GIT_QUIET=1
2327f61e
DA
647 shift
648 ;;
82f49f29
PH
649 --recursive)
650 recursive=1
651 shift
652 ;;
2327f61e
DA
653 --)
654 shift
655 break
656 ;;
657 -*)
658 usage
659 ;;
660 *)
661 break
662 ;;
663 esac
664 done
e7849a96 665
1cf823d8 666 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper sync ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
2327f61e 667}
70c7ac22 668
f6f85861
SB
669cmd_absorbgitdirs()
670{
671 git submodule--helper absorb-git-dirs --prefix "$wt_prefix" "$@"
672}
673
5c08dbbd
JH
674# This loop parses the command line arguments to find the
675# subcommand name to dispatch. Parsing of the subcommand specific
676# options are primarily done by the subcommand implementations.
677# Subcommand specific options such as --branch and --cached are
678# parsed here as well, for backward compatibility.
679
680while test $# != 0 && test -z "$command"
70c7ac22
LH
681do
682 case "$1" in
26b06100 683 add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
5c08dbbd 684 command=$1
70c7ac22
LH
685 ;;
686 -q|--quiet)
2e6a30ef 687 GIT_QUIET=1
70c7ac22 688 ;;
ecda0723
SV
689 -b|--branch)
690 case "$2" in
691 '')
692 usage
693 ;;
694 esac
695 branch="$2"; shift
696 ;;
70c7ac22 697 --cached)
28f9af5d 698 cached="$1"
70c7ac22
LH
699 ;;
700 --)
701 break
702 ;;
703 -*)
704 usage
705 ;;
706 *)
707 break
708 ;;
709 esac
710 shift
711done
712
5c08dbbd 713# No command word defaults to "status"
af9c9f97
RR
714if test -z "$command"
715then
716 if test $# = 0
717 then
718 command=status
719 else
720 usage
721 fi
722fi
5c08dbbd 723
b57e8119
DL
724# "-b branch" is accepted only by "add" and "set-branch"
725if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
5c08dbbd 726then
ecda0723 727 usage
5c08dbbd
JH
728fi
729
28f9af5d 730# "--cached" is accepted only by "status" and "summary"
496eeeb1 731if test -n "$cached" && test "$command" != status && test "$command" != summary
5c08dbbd 732then
70c7ac22 733 usage
5c08dbbd
JH
734fi
735
b57e8119 736"cmd_$(echo $command | sed -e s/-/_/g)" "$@"