commit ba40d01131a94614deca71197688d61ec9052529 from: Antoine Lambert date: Mon Feb 26 13:48:49 2024 UTC dumb: Handle HEAD file legacy format Some dumb git servers can send a HEAD file in a legacy format that contains a commit id instead of the string: "ref: ". So handle that edge case to avoid an error when loading such repository. commit - b7d16897c24c7d5a0e28d952b027401b37417f92 commit + ba40d01131a94614deca71197688d61ec9052529 blob - 6e3006e035fa06720e40ef205e8e7ef151f1863e blob + e372fa28d82e4ff65cdf6292701e454bf6a4e43a --- swh/loader/git/dumb.py +++ swh/loader/git/dumb.py @@ -195,7 +195,13 @@ class GitObjectsFetcher: def _get_head(self) -> Dict[bytes, HexBytes]: head_resp_bytes = self._http_get("HEAD") - _, head_target = head_resp_bytes.readline().replace(b"\n", b"").split(b" ") + head_split = head_resp_bytes.readline().replace(b"\n", b"").split(b" ") + head_target = head_split[1] if len(head_split) > 1 else head_split[0] + # handle HEAD legacy format containing a commit id instead of a ref name + for ref_name, ret_target in self.refs.items(): + if ret_target == head_target: + head_target = ref_name + break return {b"HEAD": head_target} def _get_pack_data(self, pack_name: str) -> Callable[[], PackData]: blob - 1858a71402a362f799ebe7a8390325d4dca7a6f2 blob + c38c9efca9cce23733ee2eb12bac100936febf8e --- swh/loader/git/tests/test_loader.py +++ swh/loader/git/tests/test_loader.py @@ -944,8 +944,20 @@ class DumbGitLoaderTestBase(FullGitLoaderTests): "skipped_content": 0, "snapshot": 1, } + + def test_load_head_legacy_format(self, requests_mock): + # mock a single request and let the others pass through as real ones + requests_mock.real_http = True + requests_mock.get( + self.repo_url + "/HEAD", content=self.repo.refs[b"refs/heads/master"] + ) + res = self.loader.load() + assert res == {"status": "eventful"} + assert b"HEAD" in self.loader.snapshot.branches + assert self.loader.snapshot.branches[b"HEAD"].target == b"refs/heads/master" + class TestDumbGitLoaderWithPack(DumbGitLoaderTestBase): @classmethod def setup_class(cls):