From: Junio C Hamano Date: Thu, 27 Aug 2009 23:59:25 +0000 (-0700) Subject: Merge branch 'jh/submodule-foreach' X-Git-Tag: v1.6.5-rc0~32 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/adc542353199bdc0b9b1ed5d03cf881b7efaff6e?ds=inline;hp=-c Merge branch 'jh/submodule-foreach' * jh/submodule-foreach: git clone: Add --recursive to automatically checkout (nested) submodules t7407: Use 'rev-parse --short' rather than bash's substring expansion notation git submodule status: Add --recursive to recurse into nested submodules git submodule update: Introduce --recursive to update nested submodules git submodule foreach: Add --recursive to recurse into nested submodules git submodule foreach: test access to submodule name as '$name' Add selftest for 'git submodule foreach' git submodule: Cleanup usage string and add option parsing to cmd_foreach() git submodule foreach: Provide access to submodule name, as '$name' Conflicts: Documentation/git-submodule.txt git-submodule.sh --- adc542353199bdc0b9b1ed5d03cf881b7efaff6e diff --combined Documentation/git-clone.txt index 2c63a0fbae,5a685ceec9..88ea272ee5 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@@ -12,7 -12,7 +12,7 @@@ SYNOPSI 'git clone' [--template=] [-l] [-s] [--no-hardlinks] [-q] [-n] [--bare] [--mirror] [-o ] [-u ] [--reference ] - [--depth ] [--] [] + [--depth ] [--recursive] [--] [] DESCRIPTION ----------- @@@ -72,16 -72,8 +72,16 @@@ These objects may be removed by normal which automatically call `git gc --auto`. (See linkgit:git-gc[1].) If these objects are removed and were referenced by the cloned repository, then the cloned repository will become corrupt. - - ++ +Note that running `git repack` without the `-l` option in a repository +cloned with `-s` will copy objects from the source repository into a pack +in the cloned repository, removing the disk space savings of `clone -s`. +It is safe, however, to run `git gc`, which uses the `-l` option by +default. ++ +If you want to break the dependency of a repository cloned with `-s` on +its source repository, you can simply run `git repack -a` to copy all +objects from the source repository into a pack in the cloned repository. --reference :: If the reference repository is on the local machine @@@ -147,6 -139,14 +147,14 @@@ with a long history, and would want to send in fixes as patches. + --recursive:: + After the clone is created, initialize all submodules within, + using their default settings. This is equivalent to running + 'git submodule update --init --recursive' immediately after + the clone is finished. This option is ignored if the cloned + repository does not have a worktree/checkout (i.e. if any of + `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) + :: The (possibly remote) repository to clone from. See the <> section below for more information on specifying diff --combined Documentation/git-submodule.txt index bb7d159179,b81c830c28..5ccdd18c89 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@@ -11,12 -11,12 +11,12 @@@ SYNOPSI [verse] 'git submodule' [--quiet] add [-b branch] [--reference ] [--] - 'git submodule' [--quiet] status [--cached] [--] [...] + 'git submodule' [--quiet] status [--cached] [--recursive] [--] [...] 'git submodule' [--quiet] init [--] [...] 'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase] - [--reference ] [--merge] [--] [...] + [--reference ] [--merge] [--recursive] [--] [...] -'git submodule' [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] +'git submodule' [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] - 'git submodule' [--quiet] foreach + 'git submodule' [--quiet] foreach [--recursive] 'git submodule' [--quiet] sync [--] [...] @@@ -100,6 -100,9 +100,9 @@@ status: initialized and `+` if the currently checked out submodule commit does not match the SHA-1 found in the index of the containing repository. This command is the default command for 'git-submodule'. + + + If '--recursive' is specified, this command will recurse into nested + submodules, and show their status as well. init:: Initialize the submodules, i.e. register each submodule name @@@ -122,25 -125,27 +125,31 @@@ update: If the submodule is not yet initialized, and you just want to use the setting as stored in .gitmodules, you can automatically initialize the submodule with the --init option. + + + If '--recursive' is specified, this command will recurse into the + registered submodules, and update any nested submodules within. summary:: Show commit summary between the given commit (defaults to HEAD) and working tree/index. For a submodule in question, a series of commits in the submodule between the given super project commit and the - index or working tree (switched by --cached) are shown. + index or working tree (switched by --cached) are shown. If the option + --files is given, show the series of commits in the submodule between + the index of the super project and the working tree of the submodule + (this option doesn't allow to use the --cached option or to provide an + explicit commit). foreach:: Evaluates an arbitrary shell command in each checked out submodule. - The command has access to the variables $path and $sha1: + The command has access to the variables $name, $path and $sha1: + $name is the name of the relevant submodule section in .gitmodules, $path is the name of the submodule directory relative to the superproject, and $sha1 is the commit as recorded in the superproject. Any submodules defined in the superproject but not checked out are ignored by this command. Unless given --quiet, foreach prints the name of each submodule before evaluating the command. + If --recursive is given, submodules are traversed recursively (i.e. + the given shell command is evaluated in nested submodules as well). A non-zero return from the command in any submodule causes the processing to terminate. This can be overridden by adding '|| :' to the end of the command. @@@ -173,11 -178,6 +182,11 @@@ OPTION commands typically use the commit found in the submodule HEAD, but with this option, the commit stored in the index is used instead. +--files:: + This option is only valid for the summary command. This command + compares the commit in the index with that in the submodule HEAD + when this option is used. + -n:: --summary-limit:: This option is only valid for the summary command. @@@ -218,6 -218,12 +227,12 @@@ *NOTE*: Do *not* use this option unless you have read the note for linkgit:git-clone[1]'s --reference and --shared options carefully. + --recursive:: + This option is only valid for foreach, update and status commands. + Traverse submodules recursively. The operation is performed not + only in the submodules of the current repo, but also + in any nested submodules inside those submodules (and so on). + ...:: Paths to submodule(s). When specified this will restrict the command to only operate on the submodules found at the specified paths. diff --combined git-submodule.sh index 9bdd6ea3d0,446bbc0a10..bfbd36b6f4 --- a/git-submodule.sh +++ b/git-submodule.sh @@@ -4,9 -4,14 +4,14 @@@ # # Copyright (c) 2007 Lars Hjemli - USAGE="[--quiet] [--cached|--files] \ - [add [-b branch] ]|[status|init|update [-i|--init] [-N|--no-fetch] [--rebase|--merge]|summary [-n|--summary-limit ] []] \ - [--] [...]|[foreach ]|[sync [--] [...]]" + dashless=$(basename "$0" | sed -e 's/-/ /') + USAGE="[--quiet] add [-b branch] [--reference ] [--] + or: $dashless [--quiet] status [--cached] [--recursive] [--] [...] + or: $dashless [--quiet] init [--] [...] + or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference ] [--merge] [--recursive] [--] [...] - or: $dashless [--quiet] summary [--cached] [--summary-limit ] [commit] [--] [...] ++ or: $dashless [--quiet] summary [--cached|--files] [--summary-limit ] [commit] [--] [...] + or: $dashless [--quiet] foreach [--recursive] + or: $dashless [--quiet] sync [--] [...]" OPTIONS_SPEC= . git-sh-setup . git-parse-remote @@@ -16,9 -21,9 +21,10 @@@ command branch= reference= cached= +files= nofetch= update= + prefix= # Resolve relative url by appending to parent's url resolve_relative_url () @@@ -238,13 -243,43 +244,43 @@@ cmd_add( # cmd_foreach() { + # parse $args after "submodule ... foreach". + while test $# -ne 0 + do + case "$1" in + -q|--quiet) + GIT_QUIET=1 + ;; + --recursive) + recursive=1 + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + module_list | while read mode sha1 stage path do if test -e "$path"/.git then - say "Entering '$path'" - (cd "$path" && eval "$@") || + say "Entering '$prefix$path'" + name=$(module_name "$path") + ( + prefix="$prefix$path/" + unset GIT_DIR + cd "$path" && + eval "$@" && + if test -n "$recursive" + then + cmd_foreach "--recursive" "$@" + fi + ) || die "Stopping at '$path'; script returned non-zero status." fi done @@@ -317,6 -352,7 +353,7 @@@ cmd_init( cmd_update() { # parse $args after "submodule ... update". + orig_args="$@" while test $# -ne 0 do case "$1" in @@@ -349,6 -385,10 +386,10 @@@ shift update="merge" ;; + --recursive) + shift + recursive=1 + ;; --) shift break @@@ -435,6 -475,12 +476,12 @@@ die "Unable to $action '$sha1' in submodule path '$path'" say "Submodule path '$path': $msg '$sha1'" fi + + if test -n "$recursive" + then + (unset GIT_DIR; cd "$path" && cmd_update $orig_args) || + die "Failed to recurse into submodule path '$path'" + fi done } @@@ -461,7 -507,6 +508,7 @@@ set_name_rev () cmd_summary() { summary_limit=-1 for_status= + diff_cmd=diff-index # parse $args after "submodule ... summary". while test $# -ne 0 @@@ -470,9 -515,6 +517,9 @@@ --cached) cached="$1" ;; + --files) + files="$1" + ;; --for-status) for_status="$1" ;; @@@ -509,17 -551,9 +556,17 @@@ head=HEAD fi + if [ -n "$files" ] + then + test -n "$cached" && + die "--cached cannot be used with --files" + diff_cmd=diff-files + head= + fi + cd_to_toplevel # Get modified modules cared by user - modules=$(git diff-index $cached --raw $head -- "$@" | + modules=$(git $diff_cmd $cached --raw $head -- "$@" | egrep '^:([0-7]* )?160000' | while read mod_src mod_dst sha1_src sha1_dst status name do @@@ -533,7 -567,7 +580,7 @@@ test -z "$modules" && return - git diff-index $cached --raw $head -- $modules | + git $diff_cmd $cached --raw $head -- $modules | egrep '^:([0-7]* )?160000' | cut -c2- | while read mod_src mod_dst sha1_src sha1_dst status name @@@ -656,6 -690,7 +703,7 @@@ cmd_status() { # parse $args after "submodule ... status". + orig_args="$@" while test $# -ne 0 do case "$1" in @@@ -665,6 -700,9 +713,9 @@@ --cached) cached=1 ;; + --recursive) + recursive=1 + ;; --) shift break @@@ -684,22 -722,34 +735,34 @@@ do name=$(module_name "$path") || exit url=$(git config submodule."$name".url) + displaypath="$prefix$path" if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git then - say "-$sha1 $path" + say "-$sha1 $displaypath" continue; fi set_name_rev "$path" "$sha1" if git diff-files --quiet -- "$path" then - say " $sha1 $path$revname" + say " $sha1 $displaypath$revname" else if test -z "$cached" then sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD) set_name_rev "$path" "$sha1" fi - say "+$sha1 $path$revname" + say "+$sha1 $displaypath$revname" + fi + + if test -n "$recursive" + then + ( + prefix="$displaypath/" + unset GIT_DIR + cd "$path" && + cmd_status $orig_args + ) || + die "Failed to recurse into submodule path '$path'" fi done }