Skip to content

Commit 9ebb277

Browse files
committed
git: make shallow clones with explicit commits more reliable
On a shallow clone the fetched tip(s) are only partially cloned. If the scm is configured to use a specific commit it might be possible that the commit was not downloaded if the branch advanced too much. Add a special fallback to re-fetch from the server with the explicit commit id if the initial fetch failed to download the required commit. Note that we cannot just always request the commit explicitly when fetching. Servers are usually configured to *not* hand out arbitrary commits.
1 parent da27c3c commit 9ebb277

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

pym/bob/scm/git.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,22 @@ async def __checkoutTag(self, invoker, fetchCmd, switch):
182182
stdout=False, cwd=self.__dir)
183183
if head or switch:
184184
await invoker.checkCommand(fetchCmd, cwd=self.__dir)
185+
if self.__commit and (self.__shallow is not None):
186+
# Shallow clones might not fetch the requested commit if the
187+
# depth is too small. The problem is that we cannot blindly
188+
# always request the commit explicitly because this is rejected
189+
# by git-upload-pack by default. Instead check here that we got
190+
# the commit and only if this is not the case we fetch a 2nd
191+
# time with the explicit commit.
192+
haveCommit = await invoker.callCommand(["git", "cat-file", "-e",
193+
self.__commit], cwd=self.__dir) == 0
194+
if not haveCommit:
195+
ok = await invoker.callCommand(fetchCmd + [self.__commit],
196+
cwd=self.__dir)
197+
if ok != 0:
198+
self.fail("Plain git-fetch in", self.__dir,
199+
"did not download the requested commit and the explicit fetch failed!",
200+
returncode=ok)
185201
await invoker.checkCommand(["git", "checkout", "-q", "--no-recurse-submodules",
186202
self.__commit if self.__commit else "tags/"+self.__tag], cwd=self.__dir)
187203
# FIXME: will not be called again if interrupted!

0 commit comments

Comments
 (0)