Teach "git submodule foreach" a --revision <tree-ish> option. This is useful in combination with $sha1 to perform git commands that take a revision argument. For example: $ git submodule foreach --revision v1.0 'git tag v1.0 $sha1' Previously, this would have required multiple steps: $ git checkout v1.0 $ git submodule update $ git submodule foreach 'git tag v1.0' Signed-off-by: Jay Soffian <jaysoffian@xxxxxxxxx> --- Documentation/git-submodule.txt | 7 ++++++- git-submodule.sh | 27 ++++++++++++++++++++++++--- t/t7407-submodule-foreach.sh | 15 +++++++++++++++ 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index b4683bba1b..6c889f5fd6 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -17,7 +17,8 @@ SYNOPSIS [--reference <repository>] [--merge] [--recursive] [--] [<path>...] 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>] [commit] [--] [<path>...] -'git submodule' [--quiet] foreach [--recursive] <command> +'git submodule' [--quiet] foreach [--recursive] [--revision <tree-ish>] + <command> 'git submodule' [--quiet] sync [--] [<path>...] @@ -180,6 +181,10 @@ foreach:: 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). + If `--revision <tree-ish>` is given, submodules are traversed starting + at the given <tree-ish>. Though this does not alter the submodule check + outs, it may be combined with $sha1 to perform git commands that can + operate on a particular commit, such as linkgit:git-tag[1]. 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. diff --git a/git-submodule.sh b/git-submodule.sh index ab6b1107b6..5e7458e155 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -10,7 +10,7 @@ USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <r or: $dashless [--quiet] init [--] [<path>...] or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...] - or: $dashless [--quiet] foreach [--recursive] <command> + or: $dashless [--quiet] foreach [--recursive] [--revision <tree-ish>] <command> or: $dashless [--quiet] sync [--] [<path>...]" OPTIONS_SPEC= . git-sh-setup @@ -379,6 +379,7 @@ Use -f if you really want to add it." >&2 cmd_foreach() { # parse $args after "submodule ... foreach". + revision= while test $# -ne 0 do case "$1" in @@ -388,6 +389,11 @@ cmd_foreach() --recursive) recursive=1 ;; + --revision) + git rev-parse --quiet --verify "$2" >/dev/null || usage + revision=$2 + shift + ;; -*) usage ;; @@ -404,7 +410,17 @@ cmd_foreach() # command in the subshell (and a recursive call to this function) exec 3<&0 - module_list | + if test -n "$revision" + then + # make ls-tree output look like ls-files output + git ls-tree -r $revision | grep '^160000 ' | + while read mode unused sha1 sm_path + do + echo "$mode $sha1 0 $sm_path" + done + else + module_list + fi | while read mode sha1 stage sm_path do die_if_unmatched "$mode" @@ -421,7 +437,12 @@ cmd_foreach() eval "$@" && if test -n "$recursive" then - cmd_foreach "--recursive" "$@" + if test -n "$revision" + then + cmd_foreach "--recursive" "--revision" "$sha1" "$@" + else + cmd_foreach "--recursive" "$@" + fi fi ) <&3 3<&- || die "$(eval_gettext "Stopping at '\$sm_path'; script returned non-zero status.")" diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 9b69fe2e14..5c798b901b 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -179,6 +179,21 @@ test_expect_success 'test "foreach --quiet --recursive"' ' test_cmp expect actual ' +sha1=$(cd submodule && git rev-parse HEAD~1) +cat > expect <<EOF +sub1 $sha1 +sub2 $sha1 +sub3 $sha1 +EOF + +test_expect_success 'test "foreach --quiet --revision"' ' + ( + cd clone2 && + git submodule foreach -q --revision HEAD~2 "echo \$path \$sha1" > ../actual + ) && + test_cmp expect actual +' + test_expect_success 'use "update --recursive" to checkout all submodules' ' git clone super clone3 && ( -- 1.7.12.2 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html