[PATCH] submodule: teach "foreach" command a --revision <tree-ish> option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]