浏览代码

Merge pull request #1163 from pmrowla/clone-detached-head

clone: fix cloning repo with detached head
Jelmer Vernooij 2 年之前
父节点
当前提交
df1660cb6e
共有 3 个文件被更改,包括 42 次插入20 次删除
  1. 11 10
      dulwich/client.py
  2. 10 10
      dulwich/repo.py
  3. 21 0
      dulwich/tests/test_porcelain.py

+ 11 - 10
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()

+ 10 - 10
dulwich/repo.py

@@ -1485,17 +1485,17 @@ 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()

+ 21 - 0
dulwich/tests/test_porcelain.py

@@ -850,6 +850,27 @@ 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):