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 <jaysoff...@gmail.com>
---
 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to