Skip to content

Commit

Permalink
Let submodule command exit with error status if path does not exist
Browse files Browse the repository at this point in the history
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 <hvoigt@hvoigt.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Heiko Voigt authored and Junio C Hamano committed Aug 14, 2012
1 parent b17a01d commit be9d0a3
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 7 deletions.
33 changes: 30 additions & 3 deletions git-submodule.sh
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,48 @@ resolve_relative_url ()
#
module_list()
{
git ls-files --error-unmatch --stage -- "$@" |
(
git ls-files --error-unmatch --stage -- "$@" ||
echo "unmatched pathspec exists"
) |
perl -e '
my %unmerged = ();
my ($null_sha1) = ("0" x 40);
my @out = ();
my $unmatched = 0;
while (<STDIN>) {
if (/^unmatched pathspec/) {
$unmatched = 1;
next;
}
chomp;
my ($mode, $sha1, $stage, $path) =
/^([0-7]+) ([0-9a-f]{40}) ([0-3])\t(.*)$/;
next unless $mode eq "160000";
if ($stage ne "0") {
if (!$unmerged{$path}++) {
print "$mode $null_sha1 U\t$path\n";
push @out, "$mode $null_sha1 U\t$path\n";
}
next;
}
print "$_\n";
push @out, "$_\n";
}
if ($unmatched) {
print "#unmatched\n";
} else {
print for (@out);
}
'
}

die_if_unmatched ()
{
if test "$1" = "#unmatched"
then
exit 1
fi
}

#
# Map submodule path to submodule name
#
Expand Down Expand Up @@ -346,6 +368,7 @@ cmd_foreach()
module_list |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
if test -e "$sm_path"/.git
then
say "$(eval_gettext "Entering '\$prefix\$sm_path'")"
Expand Down Expand Up @@ -398,6 +421,7 @@ cmd_init()
module_list "$@" |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
name=$(module_name "$sm_path") || exit

# Copy url setting when it is not set yet
Expand Down Expand Up @@ -498,6 +522,7 @@ cmd_update()
err=
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
if test "$stage" = U
then
echo >&2 "Skipping unmerged submodule $sm_path"
Expand Down Expand Up @@ -893,6 +918,7 @@ cmd_status()
module_list "$@" |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
name=$(module_name "$sm_path") || exit
url=$(git config submodule."$name".url)
displaypath="$prefix$sm_path"
Expand Down Expand Up @@ -961,6 +987,7 @@ cmd_sync()
module_list "$@" |
while read mode sha1 stage sm_path
do
die_if_unmatched "$mode"
name=$(module_name "$sm_path")
url=$(git config -f .gitmodules --get submodule."$name".url)

Expand Down
26 changes: 22 additions & 4 deletions t/t7400-submodule-basic.sh
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,27 @@ test_expect_success 'init should register submodule url in .git/config' '
test_cmp expect url
'

test_failure_with_unknown_submodule () {
test_must_fail git submodule $1 no-such-submodule 2>output.err &&
grep "^error: .*no-such-submodule" output.err
}

test_expect_success 'init should fail with unknown submodule' '
test_failure_with_unknown_submodule init
'

test_expect_success 'update should fail with unknown submodule' '
test_failure_with_unknown_submodule update
'

test_expect_success 'status should fail with unknown submodule' '
test_failure_with_unknown_submodule status
'

test_expect_success 'sync should fail with unknown submodule' '
test_failure_with_unknown_submodule sync
'

test_expect_success 'update should fail when path is used by a file' '
echo hello >expect &&
Expand Down Expand Up @@ -418,10 +439,7 @@ test_expect_success 'moving to a commit without submodule does not leave empty d
'

test_expect_success 'submodule <invalid-path> warns' '
git submodule no-such-submodule 2> output.err &&
grep "^error: .*no-such-submodule" output.err
test_failure_with_unknown_submodule
'

test_expect_success 'add submodules without specifying an explicit path' '
Expand Down

0 comments on commit be9d0a3

Please sign in to comment.