submodule: try harder to fetch needed sha1 by direct fetching sha1

When reviewing a change that also updates a submodule in Gerrit, a common review practice is to download and cherry-pick the patch locally to test it. However when testing it locally, the 'git submodule update' may fail fetching the correct submodule sha1 as the corresponding commit in the submodule is not yet part of the project history, but also just a proposed change. If $sha1 was not part of the default fetch, we try to fetch the $sha1 directly. Some servers however do not support direct fetch by sha1, which leads git-fetch to fail quickly. We can fail ourselves here as the still missing sha1 would lead to a failure later in the checkout stage anyway, so failing here is as good as we can get. Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Stefan Beller <sbeller@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Stefan Beller committed Feb 23, 2016 at 19:32 UTC fb43e31f2b43076e7a30c9cd00d0241cb8cf97eb
1 file changed +26 -3
git-submodule.sh
+26 -3
@@ -591,6 +591,24 @@ cmd_deinit()
591 done
592 }
593
594 +is_tip_reachable () (
595 + clear_local_git_env
596 + cd "$1" &&
597 + rev=$(git rev-list -n 1 "$2" --not --all 2>/dev/null) &&
598 + test -z "$rev"
599 +)
600 +
601 +fetch_in_submodule () (
602 + clear_local_git_env
603 + cd "$1" &&
604 + case "$2" in
605 + '')
606 + git fetch ;;
607 + *)
608 + git fetch $(get_default_remote) "$2" ;;
609 + esac
610 +)
611 +
612 #
613 # Update each submodule path to correct revision, using clone and checkout as needed
614 #
@@ -745,10 +763,15 @@ Maybe you want to use 'update --init'?")"
763 then
764 # Run fetch only if $sha1 isn't present or it
765 # is not reachable from a ref.
748 - (clear_local_git_env; cd "$sm_path" &&
749 - ( (rev=$(git rev-list -n 1 $sha1 --not --all 2>/dev/null) &&
750 - test -z "$rev") || git-fetch)) ||
766 + is_tip_reachable "$sm_path" "$sha1" ||
767 + fetch_in_submodule "$sm_path" ||
768 die "$(eval_gettext "Unable to fetch in submodule path '\$displaypath'")"
769 +
770 + # Now we tried the usual fetch, but $sha1 may
771 + # not be reachable from any of the refs
772 + is_tip_reachable "$sm_path" "$sha1" ||
773 + fetch_in_submodule "$sm_path" "$sha1" ||
774 + die "$(eval_gettext "Fetched in submodule path '\$displaypath', but it did not contain $sha1. Direct fetching of that commit failed.")"
775 fi
776
777 # Is this something we just cloned?