Skip to content

Commit 66d36b9

Browse files
peffgitster
authored andcommitted
submodule: fix fetch_in_submodule logic
Commit 1c15180 (submodule: use "fetch" logic instead of custom remote discovery, 2020-11-14) rewrote the logic in fetch_in_submodule to do: elif test "$2" -ne "" But this is nonsense in shell: -ne is for numeric comparisons. This should be "=" or more idiomatically: elif test -n "$2" But once we fix that, many tests start failing. Because that commit introduced another problem. The caller that passes 3 arguments looks like this: fetch_in_submodule "$sm_path" $depth "$sha1" Note the unquoted $depth parameter. When it isn't set, the function will see only 2 arguments, and the function has no idea if what it sees in $2 is an option to go on the command line, or a refspec to pass on stdin. In the old code before that commit: fetch_in_submodule () ( sanitize_submodule_env && cd "$1" && - case "$2" in - '') - git fetch ;; - *) - shift - git fetch $(get_default_remote) "$@" ;; - esac we treated those the same, so it didn't matter. But in the new logic (with my fix above): + if test $# -eq 3 + then + echo "$3" | git fetch --stdin "$2" + elif test -n "$n" + then + git fetch "$2" + else + git fetch + fi we use the number of parameters to distinguish the two. Let's insist that the caller pass an empty string for positional parameter two if they want to have a third parameter after it. But that still leaves one problem. In the --stdin block, we unconditionally pass "$2" to git-fetch, even if it's the empty string. Rather than add another conditional, we can use :+ parameter expansion to include it only if it's non-empty. In fact, we can do the same for the elif, too, simplifying it further. Technically this is overkill, since we know the --depth parameter will not have whitespace (and indeed, most callers do not bother quoting it), but it doesn't hurt for the function to be careful. It's somewhat amazing that no tests were failing. I think what happened is that: - the 3-arg form rarely triggered; any call with a non-empty $depth and a $sha1 would work, but one with an empty $depth would only have 2 arguments - because of the wrong arguments to "test", the shell would complain and exit non-zero. So we never ran the middle conditional at all - that left every call running "git fetch" with no arguments. A well-written test could have detected the distinction here, but in practice omitting --depth just means fetching more commits, and fetching everything (rather than a single sha1) works as long as the commit in question is reachable Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a89a2fb commit 66d36b9

File tree

1 file changed

+6
-6
lines changed

1 file changed

+6
-6
lines changed

git-submodule.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -412,17 +412,17 @@ is_tip_reachable () (
412412
test -z "$rev"
413413
)
414414

415+
# usage: fetch_in_submodule <module_path> [<depth>] [<sha1>]
416+
# Because arguments are positional, use an empty string to omit <depth>
417+
# but include <sha1>.
415418
fetch_in_submodule () (
416419
sanitize_submodule_env &&
417420
cd "$1" &&
418421
if test $# -eq 3
419422
then
420-
echo "$3" | git fetch --stdin "$2"
421-
elif test "$2" -ne ""
422-
then
423-
git fetch "$2"
423+
echo "$3" | git fetch --stdin ${2:+"$2"}
424424
else
425-
git fetch
425+
git fetch ${2:+"$2"}
426426
fi
427427
)
428428

@@ -603,7 +603,7 @@ cmd_update()
603603
# Now we tried the usual fetch, but $sha1 may
604604
# not be reachable from any of the refs
605605
is_tip_reachable "$sm_path" "$sha1" ||
606-
fetch_in_submodule "$sm_path" $depth "$sha1" ||
606+
fetch_in_submodule "$sm_path" "$depth" "$sha1" ||
607607
die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain \$sha1. Direct fetching of that commit failed.")"
608608
fi
609609

0 commit comments

Comments
 (0)