]> git.ipfire.org Git - thirdparty/git.git/blob - git-submodule.sh
clone: allow "--bare" with "-o"
[thirdparty/git.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] [--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 [--filter=<filter-spec>]] [--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
26
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
31
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=
52 filter=
53
54 isnumber()
55 {
56 n=$(($1 + 0)) 2>/dev/null && test "$n" = "$1"
57 }
58
59 # Sanitize the local git environment for use within a submodule. We
60 # can't simply use clear_local_git_env since we want to preserve some
61 # of the settings from GIT_CONFIG_PARAMETERS.
62 sanitize_submodule_env()
63 {
64 save_config=$GIT_CONFIG_PARAMETERS
65 clear_local_git_env
66 GIT_CONFIG_PARAMETERS=$save_config
67 export GIT_CONFIG_PARAMETERS
68 }
69
70 #
71 # Add a new submodule to the working tree, .gitmodules and the index
72 #
73 # $@ = repo path
74 #
75 # optional branch is stored in global branch variable
76 #
77 cmd_add()
78 {
79 # parse $args after "submodule ... add".
80 reference_path=
81 while test $# -ne 0
82 do
83 case "$1" in
84 -b | --branch)
85 case "$2" in '') usage ;; esac
86 branch=$2
87 shift
88 ;;
89 -f | --force)
90 force=$1
91 ;;
92 -q|--quiet)
93 GIT_QUIET=1
94 ;;
95 --progress)
96 progress=1
97 ;;
98 --reference)
99 case "$2" in '') usage ;; esac
100 reference_path=$2
101 shift
102 ;;
103 --reference=*)
104 reference_path="${1#--reference=}"
105 ;;
106 --dissociate)
107 dissociate=1
108 ;;
109 --name)
110 case "$2" in '') usage ;; esac
111 custom_name=$2
112 shift
113 ;;
114 --depth)
115 case "$2" in '') usage ;; esac
116 depth="--depth=$2"
117 shift
118 ;;
119 --depth=*)
120 depth=$1
121 ;;
122 --)
123 shift
124 break
125 ;;
126 -*)
127 usage
128 ;;
129 *)
130 break
131 ;;
132 esac
133 shift
134 done
135
136 if test -z "$1"
137 then
138 usage
139 fi
140
141 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"} -- "$@"
142 }
143
144 #
145 # Execute an arbitrary command sequence in each checked out
146 # submodule
147 #
148 # $@ = command to execute
149 #
150 cmd_foreach()
151 {
152 # parse $args after "submodule ... foreach".
153 while test $# -ne 0
154 do
155 case "$1" in
156 -q|--quiet)
157 GIT_QUIET=1
158 ;;
159 --recursive)
160 recursive=1
161 ;;
162 -*)
163 usage
164 ;;
165 *)
166 break
167 ;;
168 esac
169 shift
170 done
171
172 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper foreach ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
173 }
174
175 #
176 # Register submodules in .git/config
177 #
178 # $@ = requested paths (default to all)
179 #
180 cmd_init()
181 {
182 # parse $args after "submodule ... init".
183 while test $# -ne 0
184 do
185 case "$1" in
186 -q|--quiet)
187 GIT_QUIET=1
188 ;;
189 --)
190 shift
191 break
192 ;;
193 -*)
194 usage
195 ;;
196 *)
197 break
198 ;;
199 esac
200 shift
201 done
202
203 git ${wt_prefix:+-C "$wt_prefix"} ${prefix:+--super-prefix "$prefix"} submodule--helper init ${GIT_QUIET:+--quiet} -- "$@"
204 }
205
206 #
207 # Unregister submodules from .git/config and remove their work tree
208 #
209 cmd_deinit()
210 {
211 # parse $args after "submodule ... deinit".
212 deinit_all=
213 while test $# -ne 0
214 do
215 case "$1" in
216 -f|--force)
217 force=$1
218 ;;
219 -q|--quiet)
220 GIT_QUIET=1
221 ;;
222 --all)
223 deinit_all=t
224 ;;
225 --)
226 shift
227 break
228 ;;
229 -*)
230 usage
231 ;;
232 *)
233 break
234 ;;
235 esac
236 shift
237 done
238
239 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit ${GIT_QUIET:+--quiet} ${force:+--force} ${deinit_all:+--all} -- "$@"
240 }
241
242 #
243 # Update each submodule path to correct revision, using clone and checkout as needed
244 #
245 # $@ = requested paths (default to all)
246 #
247 cmd_update()
248 {
249 # parse $args after "submodule ... update".
250 while test $# -ne 0
251 do
252 case "$1" in
253 -q|--quiet)
254 GIT_QUIET=1
255 ;;
256 -v)
257 unset GIT_QUIET
258 ;;
259 --progress)
260 progress=1
261 ;;
262 -i|--init)
263 init=1
264 ;;
265 --require-init)
266 init=1
267 require_init=1
268 ;;
269 --remote)
270 remote=1
271 ;;
272 -N|--no-fetch)
273 nofetch=1
274 ;;
275 -f|--force)
276 force=$1
277 ;;
278 -r|--rebase)
279 update="rebase"
280 ;;
281 --reference)
282 case "$2" in '') usage ;; esac
283 reference="--reference=$2"
284 shift
285 ;;
286 --reference=*)
287 reference="$1"
288 ;;
289 --dissociate)
290 dissociate=1
291 ;;
292 -m|--merge)
293 update="merge"
294 ;;
295 --recursive)
296 recursive=1
297 ;;
298 --checkout)
299 update="checkout"
300 ;;
301 --recommend-shallow)
302 recommend_shallow="--recommend-shallow"
303 ;;
304 --no-recommend-shallow)
305 recommend_shallow="--no-recommend-shallow"
306 ;;
307 --depth)
308 case "$2" in '') usage ;; esac
309 depth="--depth=$2"
310 shift
311 ;;
312 --depth=*)
313 depth=$1
314 ;;
315 -j|--jobs)
316 case "$2" in '') usage ;; esac
317 jobs="--jobs=$2"
318 shift
319 ;;
320 --jobs=*)
321 jobs=$1
322 ;;
323 --single-branch)
324 single_branch="--single-branch"
325 ;;
326 --no-single-branch)
327 single_branch="--no-single-branch"
328 ;;
329 --filter)
330 case "$2" in '') usage ;; esac
331 filter="--filter=$2"
332 shift
333 ;;
334 --filter=*)
335 filter="$1"
336 ;;
337 --)
338 shift
339 break
340 ;;
341 -*)
342 usage
343 ;;
344 *)
345 break
346 ;;
347 esac
348 shift
349 done
350
351 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper update \
352 ${GIT_QUIET:+--quiet} \
353 ${force:+--force} \
354 ${progress:+"--progress"} \
355 ${remote:+--remote} \
356 ${recursive:+--recursive} \
357 ${init:+--init} \
358 ${nofetch:+--no-fetch} \
359 ${wt_prefix:+--prefix "$wt_prefix"} \
360 ${prefix:+--recursive-prefix "$prefix"} \
361 ${update:+--update "$update"} \
362 ${reference:+"$reference"} \
363 ${dissociate:+"--dissociate"} \
364 ${depth:+"$depth"} \
365 ${require_init:+--require-init} \
366 ${dissociate:+"--dissociate"} \
367 $single_branch \
368 $recommend_shallow \
369 $jobs \
370 $filter \
371 -- \
372 "$@"
373 }
374
375 #
376 # Configures a submodule's default branch
377 #
378 # $@ = requested path
379 #
380 cmd_set_branch() {
381 default=
382 branch=
383
384 while test $# -ne 0
385 do
386 case "$1" in
387 -q|--quiet)
388 # we don't do anything with this but we need to accept it
389 ;;
390 -d|--default)
391 default=1
392 ;;
393 -b|--branch)
394 case "$2" in '') usage ;; esac
395 branch=$2
396 shift
397 ;;
398 --)
399 shift
400 break
401 ;;
402 -*)
403 usage
404 ;;
405 *)
406 break
407 ;;
408 esac
409 shift
410 done
411
412 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-branch ${GIT_QUIET:+--quiet} ${branch:+--branch "$branch"} ${default:+--default} -- "$@"
413 }
414
415 #
416 # Configures a submodule's remote url
417 #
418 # $@ = requested path, requested url
419 #
420 cmd_set_url() {
421 while test $# -ne 0
422 do
423 case "$1" in
424 -q|--quiet)
425 GIT_QUIET=1
426 ;;
427 --)
428 shift
429 break
430 ;;
431 -*)
432 usage
433 ;;
434 *)
435 break
436 ;;
437 esac
438 shift
439 done
440
441 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper set-url ${GIT_QUIET:+--quiet} -- "$@"
442 }
443
444 #
445 # Show commit summary for submodules in index or working tree
446 #
447 # If '--cached' is given, show summary between index and given commit,
448 # or between working tree and given commit
449 #
450 # $@ = [commit (default 'HEAD'),] requested paths (default all)
451 #
452 cmd_summary() {
453 summary_limit=-1
454 for_status=
455 diff_cmd=diff-index
456
457 # parse $args after "submodule ... summary".
458 while test $# -ne 0
459 do
460 case "$1" in
461 --cached)
462 cached="$1"
463 ;;
464 --files)
465 files="$1"
466 ;;
467 --for-status)
468 for_status="$1"
469 ;;
470 -n|--summary-limit)
471 summary_limit="$2"
472 isnumber "$summary_limit" || usage
473 shift
474 ;;
475 --summary-limit=*)
476 summary_limit="${1#--summary-limit=}"
477 isnumber "$summary_limit" || usage
478 ;;
479 --)
480 shift
481 break
482 ;;
483 -*)
484 usage
485 ;;
486 *)
487 break
488 ;;
489 esac
490 shift
491 done
492
493 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper summary ${files:+--files} ${cached:+--cached} ${for_status:+--for-status} ${summary_limit:+-n $summary_limit} -- "$@"
494 }
495 #
496 # List all submodules, prefixed with:
497 # - submodule not initialized
498 # + different revision checked out
499 #
500 # If --cached was specified the revision in the index will be printed
501 # instead of the currently checked out revision.
502 #
503 # $@ = requested paths (default to all)
504 #
505 cmd_status()
506 {
507 # parse $args after "submodule ... status".
508 while test $# -ne 0
509 do
510 case "$1" in
511 -q|--quiet)
512 GIT_QUIET=1
513 ;;
514 --cached)
515 cached=1
516 ;;
517 --recursive)
518 recursive=1
519 ;;
520 --)
521 shift
522 break
523 ;;
524 -*)
525 usage
526 ;;
527 *)
528 break
529 ;;
530 esac
531 shift
532 done
533
534 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper status ${GIT_QUIET:+--quiet} ${cached:+--cached} ${recursive:+--recursive} -- "$@"
535 }
536 #
537 # Sync remote urls for submodules
538 # This makes the value for remote.$remote.url match the value
539 # specified in .gitmodules.
540 #
541 cmd_sync()
542 {
543 while test $# -ne 0
544 do
545 case "$1" in
546 -q|--quiet)
547 GIT_QUIET=1
548 shift
549 ;;
550 --recursive)
551 recursive=1
552 shift
553 ;;
554 --)
555 shift
556 break
557 ;;
558 -*)
559 usage
560 ;;
561 *)
562 break
563 ;;
564 esac
565 done
566
567 git ${wt_prefix:+-C "$wt_prefix"} submodule--helper sync ${GIT_QUIET:+--quiet} ${recursive:+--recursive} -- "$@"
568 }
569
570 cmd_absorbgitdirs()
571 {
572 git submodule--helper absorb-git-dirs --prefix "$wt_prefix" "$@"
573 }
574
575 # This loop parses the command line arguments to find the
576 # subcommand name to dispatch. Parsing of the subcommand specific
577 # options are primarily done by the subcommand implementations.
578 # Subcommand specific options such as --branch and --cached are
579 # parsed here as well, for backward compatibility.
580
581 while test $# != 0 && test -z "$command"
582 do
583 case "$1" in
584 add | foreach | init | deinit | update | set-branch | set-url | status | summary | sync | absorbgitdirs)
585 command=$1
586 ;;
587 -q|--quiet)
588 GIT_QUIET=1
589 ;;
590 -b|--branch)
591 case "$2" in
592 '')
593 usage
594 ;;
595 esac
596 branch="$2"; shift
597 ;;
598 --cached)
599 cached="$1"
600 ;;
601 --)
602 break
603 ;;
604 -*)
605 usage
606 ;;
607 *)
608 break
609 ;;
610 esac
611 shift
612 done
613
614 # No command word defaults to "status"
615 if test -z "$command"
616 then
617 if test $# = 0
618 then
619 command=status
620 else
621 usage
622 fi
623 fi
624
625 # "-b branch" is accepted only by "add" and "set-branch"
626 if test -n "$branch" && (test "$command" != add || test "$command" != set-branch)
627 then
628 usage
629 fi
630
631 # "--cached" is accepted only by "status" and "summary"
632 if test -n "$cached" && test "$command" != status && test "$command" != summary
633 then
634 usage
635 fi
636
637 "cmd_$(echo $command | sed -e s/-/_/g)" "$@"