Skip to content

Commit 64b19ff

Browse files
jherlandgitster
authored andcommitted
git submodule status: Add --recursive to recurse into nested submodules
In very large and hierarchically structured projects, one may encounter nested submodules. In these situations, it is valuable to not only show status for all the submodules in the current repo (which is what is currently done by 'git submodule status'), but also to show status for all submodules at all levels (i.e. recursing into nested submodules as well). This patch teaches the new --recursive option to the 'git submodule status' command. The patch also includes documentation and selftests. Signed-off-by: Johan Herland <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b13fd5c commit 64b19ff

File tree

3 files changed

+51
-6
lines changed

3 files changed

+51
-6
lines changed

Documentation/git-submodule.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SYNOPSIS
1111
[verse]
1212
'git submodule' [--quiet] add [-b branch]
1313
[--reference <repository>] [--] <repository> <path>
14-
'git submodule' [--quiet] status [--cached] [--] [<path>...]
14+
'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...]
1515
'git submodule' [--quiet] init [--] [<path>...]
1616
'git submodule' [--quiet] update [--init] [-N|--no-fetch] [--rebase]
1717
[--reference <repository>] [--merge] [--recursive] [--] [<path>...]
@@ -100,6 +100,9 @@ status::
100100
initialized and `+` if the currently checked out submodule commit
101101
does not match the SHA-1 found in the index of the containing
102102
repository. This command is the default command for 'git-submodule'.
103+
+
104+
If '--recursive' is specified, this command will recurse into nested
105+
submodules, and show their status as well.
103106

104107
init::
105108
Initialize the submodules, i.e. register each submodule name
@@ -216,7 +219,7 @@ OPTIONS
216219
for linkgit:git-clone[1]'s --reference and --shared options carefully.
217220

218221
--recursive::
219-
This option is only valid for foreach and update commands.
222+
This option is only valid for foreach, update and status commands.
220223
Traverse submodules recursively. The operation is performed not
221224
only in the submodules of the current repo, but also
222225
in any nested submodules inside those submodules (and so on).

git-submodule.sh

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
dashless=$(basename "$0" | sed -e 's/-/ /')
88
USAGE="[--quiet] add [-b branch] [--reference <repository>] [--] <repository> <path>
9-
or: $dashless [--quiet] status [--cached] [--] [<path>...]
9+
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
1010
or: $dashless [--quiet] init [--] [<path>...]
1111
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
1212
or: $dashless [--quiet] summary [--cached] [--summary-limit <n>] [commit] [--] [<path>...]
@@ -690,6 +690,7 @@ cmd_summary() {
690690
cmd_status()
691691
{
692692
# parse $args after "submodule ... status".
693+
orig_args="$@"
693694
while test $# -ne 0
694695
do
695696
case "$1" in
@@ -699,6 +700,9 @@ cmd_status()
699700
--cached)
700701
cached=1
701702
;;
703+
--recursive)
704+
recursive=1
705+
;;
702706
--)
703707
shift
704708
break
@@ -718,22 +722,34 @@ cmd_status()
718722
do
719723
name=$(module_name "$path") || exit
720724
url=$(git config submodule."$name".url)
725+
displaypath="$prefix$path"
721726
if test -z "$url" || ! test -d "$path"/.git -o -f "$path"/.git
722727
then
723-
say "-$sha1 $path"
728+
say "-$sha1 $displaypath"
724729
continue;
725730
fi
726731
set_name_rev "$path" "$sha1"
727732
if git diff-files --quiet -- "$path"
728733
then
729-
say " $sha1 $path$revname"
734+
say " $sha1 $displaypath$revname"
730735
else
731736
if test -z "$cached"
732737
then
733738
sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD)
734739
set_name_rev "$path" "$sha1"
735740
fi
736-
say "+$sha1 $path$revname"
741+
say "+$sha1 $displaypath$revname"
742+
fi
743+
744+
if test -n "$recursive"
745+
then
746+
(
747+
prefix="$displaypath/"
748+
unset GIT_DIR
749+
cd "$path" &&
750+
cmd_status $orig_args
751+
) ||
752+
die "Failed to recurse into submodule path '$path'"
737753
fi
738754
done
739755
}

t/t7407-submodule-foreach.sh

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,4 +194,30 @@ test_expect_success 'use "update --recursive" to checkout all submodules' '
194194
)
195195
'
196196

197+
nested1sha1=$(cd clone3/nested1 && git rev-parse HEAD)
198+
nested2sha1=$(cd clone3/nested1/nested2 && git rev-parse HEAD)
199+
nested3sha1=$(cd clone3/nested1/nested2/nested3 && git rev-parse HEAD)
200+
submodulesha1=$(cd clone3/nested1/nested2/nested3/submodule && git rev-parse HEAD)
201+
sub1sha1=$(cd clone3/sub1 && git rev-parse HEAD)
202+
sub2sha1=$(cd clone3/sub2 && git rev-parse HEAD)
203+
sub3sha1=$(cd clone3/sub3 && git rev-parse HEAD)
204+
205+
cat > expect <<EOF
206+
$nested1sha1 nested1 (heads/master)
207+
$nested2sha1 nested1/nested2 (heads/master)
208+
$nested3sha1 nested1/nested2/nested3 (heads/master)
209+
$submodulesha1 nested1/nested2/nested3/submodule (heads/master)
210+
$sub1sha1 sub1 (${sub1sha1:0:7})
211+
$sub2sha1 sub2 (${sub1sha1:0:7})
212+
$sub3sha1 sub3 (heads/master)
213+
EOF
214+
215+
test_expect_success 'test "status --recursive"' '
216+
(
217+
cd clone3 &&
218+
git submodule status --recursive > ../actual
219+
) &&
220+
test_cmp expect actual
221+
'
222+
197223
test_done

0 commit comments

Comments
 (0)