commit df1660cb6e65b4a211b8f5c8f547293ec65664d0 from: Jelmer Vernooij via: GitHub date: Wed Mar 29 21:19:09 2023 UTC Merge pull request #1163 from pmrowla/clone-detached-head clone: fix cloning repo with detached head commit - 2c9cf9de8266aee2b966fb1f89eb6c55fbcc7a23 commit + df1660cb6e65b4a211b8f5c8f547293ec65664d0 blob - dbd46653ab6fbb07609c2f1a2b1bf7312887de2e blob + 6295b0472fed5a8188ce18a1ea420bd0d7c97171 --- dulwich/client.py +++ dulwich/client.py @@ -711,17 +711,18 @@ class GitClient: if origin_sha and not origin_head: # set detached HEAD target.refs[b"HEAD"] = origin_sha - - _set_origin_head(target.refs, origin.encode('utf-8'), origin_head) - head_ref = _set_default_branch( - target.refs, origin.encode('utf-8'), origin_head, branch, ref_message - ) - - # Update target head - if head_ref: - head = _set_head(target.refs, head_ref, ref_message) + head = origin_sha else: - head = None + _set_origin_head(target.refs, origin.encode('utf-8'), origin_head) + head_ref = _set_default_branch( + target.refs, origin.encode('utf-8'), origin_head, branch, ref_message + ) + + # Update target head + if head_ref: + head = _set_head(target.refs, head_ref, ref_message) + else: + head = None if checkout and head is not None: target.reset_index() blob - f16c847baa1bffa22e2dbad42380c885e3745525 blob + a64b496fe81447b9a5fdfb50c6bd7e04ea7839f2 --- dulwich/repo.py +++ dulwich/repo.py @@ -1485,18 +1485,18 @@ class Repo(BaseRepo): if origin_sha and not origin_head: # set detached HEAD target.refs[b"HEAD"] = origin_sha - - _set_origin_head(target.refs, origin, origin_head) - head_ref = _set_default_branch( - target.refs, origin, origin_head, branch, ref_message - ) - - # Update target head - if head_ref: - head = _set_head(target.refs, head_ref, ref_message) else: - head = None + _set_origin_head(target.refs, origin, origin_head) + head_ref = _set_default_branch( + target.refs, origin, origin_head, branch, ref_message + ) + # Update target head + if head_ref: + head = _set_head(target.refs, head_ref, ref_message) + else: + head = None + if checkout and head is not None: target.reset_index() except BaseException: blob - 05d363f7871bde3415031a82a9e3283b693130ee blob + ea6f5fb9b8458b87156457f4b484c2fc789daf67 --- dulwich/tests/test_porcelain.py +++ dulwich/tests/test_porcelain.py @@ -850,7 +850,28 @@ class CloneTests(PorcelainTestCase): target_repo.refs.get_symrefs(), ) + def test_detached_head(self): + f1_1 = make_object(Blob, data=b"f1") + commit_spec = [[1], [2, 1], [3, 1, 2]] + trees = { + 1: [(b"f1", f1_1), (b"f2", f1_1)], + 2: [(b"f1", f1_1), (b"f2", f1_1)], + 3: [(b"f1", f1_1), (b"f2", f1_1)], + } + c1, c2, c3 = build_commit_graph(self.repo.object_store, commit_spec, trees) + self.repo.refs[b"refs/heads/master"] = c2.id + self.repo.refs.remove_if_equals(b"HEAD", None) + self.repo.refs[b"HEAD"] = c3.id + target_path = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, target_path) + errstream = porcelain.NoneStream() + with porcelain.clone( + self.repo.path, target_path, checkout=True, errstream=errstream + ) as r: + self.assertEqual(c3.id, r.refs[b"HEAD"]) + + class InitTests(TestCase): def test_non_bare(self): repo_dir = tempfile.mkdtemp()