Skip to content

Commit be9d0a3

Browse files
hvoigtgitster
authored andcommitted
Let submodule command exit with error status if path does not exist
Various subcommands of the "git submodule" command exited with 0 status even though the path given by the user did not exist. The reason behind that was that they all pipe the output of module_list into the while loop which then does the action on the paths specified by the commandline. Since the exit code of the command on the upstream side of the pipe is ignored by the shell, the status code of "ls-files --error-unmatch" nor "module_list" was not propagated. In case ls-files returns with an error code, we write a special string that is not possible in non error situations, and no other output, so that the downstream can detect the error and die with an error code. The error message that there is an unmatched pathspec comes through stderr directly from ls-files. So the user still gets a hint whats going on. Signed-off-by: Heiko Voigt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent b17a01d commit be9d0a3

File tree

2 files changed

+52
-7
lines changed

2 files changed

+52
-7
lines changed

git-submodule.sh

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,26 +73,48 @@ resolve_relative_url ()
7373
#
7474
module_list()
7575
{
76-
git ls-files --error-unmatch --stage -- "$@" |
76+
(
77+
git ls-files --error-unmatch --stage -- "$@" ||
78+
echo "unmatched pathspec exists"
79+
) |
7780
perl -e '
7881
my %unmerged = ();
7982
my ($null_sha1) = ("0" x 40);
83+
my @out = ();
84+
my $unmatched = 0;
8085
while (<STDIN>) {
86+
if (/^unmatched pathspec/) {
87+
$unmatched = 1;
88+
next;
89+
}
8190
chomp;
8291
my ($mode, $sha1, $stage, $path) =
8392
/^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
8493
next unless $mode eq "160000";
8594
if ($stage ne "0") {
8695
if (!$unmerged{$path}++) {
87-
print "$mode $null_sha1 U\t$path\n";
96+
push @out, "$mode $null_sha1 U\t$path\n";
8897
}
8998
next;
9099
}
91-
print "$_\n";
100+
push @out, "$_\n";
101+
}
102+
if ($unmatched) {
103+
print "#unmatched\n";
104+
} else {
105+
print for (@out);
92106
}
93107
'
94108
}
95109

110+
die_if_unmatched ()
111+
{
112+
if test "$1" = "#unmatched"
113+
then
114+
exit 1
115+
fi
116+
}
117+
96118
#
97119
# Map submodule path to submodule name
98120
#
@@ -346,6 +368,7 @@ cmd_foreach()
346368
module_list |
347369
while read mode sha1 stage sm_path
348370
do
371+
die_if_unmatched "$mode"
349372
if test -e "$sm_path"/.git
350373
then
351374
say "$(eval_gettext "Entering '\$prefix\$sm_path'")"
@@ -398,6 +421,7 @@ cmd_init()
398421
module_list "$@" |
399422
while read mode sha1 stage sm_path
400423
do
424+
die_if_unmatched "$mode"
401425
name=$(module_name "$sm_path") || exit
402426

403427
# Copy url setting when it is not set yet
@@ -498,6 +522,7 @@ cmd_update()
498522
err=
499523
while read mode sha1 stage sm_path
500524
do
525+
die_if_unmatched "$mode"
501526
if test "$stage" = U
502527
then
503528
echo >&2 "Skipping unmerged submodule $sm_path"
@@ -893,6 +918,7 @@ cmd_status()
893918
module_list "$@" |
894919
while read mode sha1 stage sm_path
895920
do
921+
die_if_unmatched "$mode"
896922
name=$(module_name "$sm_path") || exit
897923
url=$(git config submodule."$name".url)
898924
displaypath="$prefix$sm_path"
@@ -961,6 +987,7 @@ cmd_sync()
961987
module_list "$@" |
962988
while read mode sha1 stage sm_path
963989
do
990+
die_if_unmatched "$mode"
964991
name=$(module_name "$sm_path")
965992
url=$(git config -f .gitmodules --get submodule."$name".url)
966993

t/t7400-submodule-basic.sh

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,27 @@ test_expect_success 'init should register submodule url in .git/config' '
258258
test_cmp expect url
259259
'
260260

261+
test_failure_with_unknown_submodule () {
262+
test_must_fail git submodule $1 no-such-submodule 2>output.err &&
263+
grep "^error: .*no-such-submodule" output.err
264+
}
265+
266+
test_expect_success 'init should fail with unknown submodule' '
267+
test_failure_with_unknown_submodule init
268+
'
269+
270+
test_expect_success 'update should fail with unknown submodule' '
271+
test_failure_with_unknown_submodule update
272+
'
273+
274+
test_expect_success 'status should fail with unknown submodule' '
275+
test_failure_with_unknown_submodule status
276+
'
277+
278+
test_expect_success 'sync should fail with unknown submodule' '
279+
test_failure_with_unknown_submodule sync
280+
'
281+
261282
test_expect_success 'update should fail when path is used by a file' '
262283
echo hello >expect &&
263284
@@ -418,10 +439,7 @@ test_expect_success 'moving to a commit without submodule does not leave empty d
418439
'
419440

420441
test_expect_success 'submodule <invalid-path> warns' '
421-
422-
git submodule no-such-submodule 2> output.err &&
423-
grep "^error: .*no-such-submodule" output.err
424-
442+
test_failure_with_unknown_submodule
425443
'
426444

427445
test_expect_success 'add submodules without specifying an explicit path' '

0 commit comments

Comments
 (0)