Jelajahi Sumber

Read MERGE_HEADS.

Jelmer Vernooij 6 tahun lalu
induk
melakukan
df6b22378a
3 mengubah file dengan 53 tambahan dan 3 penghapusan
  1. 4 1
      NEWS
  2. 28 2
      dulwich/repo.py
  3. 21 0
      dulwich/tests/test_repository.py

+ 4 - 1
NEWS

@@ -3,7 +3,10 @@
  IMPROVEMENTS
 
  * Add `dulwich.porcelain.write_tree`.
-  (Jelmer Vernooij)
+   (Jelmer Vernooij)
+
+ * Support reading ``MERGE_HEADS`` in ``Repo.do_commit``.
+   (Jelmer Vernooij)
 
 0.19.9	2018-11-17
 

+ 28 - 2
dulwich/repo.py

@@ -252,6 +252,10 @@ class BaseRepo(object):
         """
         raise NotImplementedError(self._put_named_file)
 
+    def _del_named_file(self, path):
+        """Delete a file in the contrl directory with the given name."""
+        raise NotImplementedError(self._del_named_file)
+
     def open_index(self):
         """Open the index for this repository.
 
@@ -654,6 +658,13 @@ class BaseRepo(object):
         for sha in to_remove:
             del self._graftpoints[sha]
 
+    def _read_heads(self, name):
+        f = self.get_named_file(name)
+        if f is None:
+            return []
+        with f:
+            return f.splitlines()
+
     def do_commit(self, message=None, committer=None,
                   author=None, commit_timestamp=None,
                   commit_timezone=None, author_timestamp=None,
@@ -696,8 +707,7 @@ class BaseRepo(object):
 
         config = self.get_config_stack()
         if merge_heads is None:
-            # FIXME: Read merge heads from .git/MERGE_HEADS
-            merge_heads = []
+            merge_heads = self._read_heads('MERGE_HEADS')
         if committer is None:
             committer = self._get_user_identity(config)
         check_user_identity(committer)
@@ -768,6 +778,8 @@ class BaseRepo(object):
                 # commit and all its objects as garbage.
                 raise CommitError("%s changed during commit" % (ref,))
 
+        self._del_named_file('MERGE_HEADS')
+
         try:
             self.hooks['post-commit'].execute()
         except HookError as e:  # silent failure
@@ -939,6 +951,14 @@ class Repo(BaseRepo):
         with GitFile(os.path.join(self.controldir(), path), 'wb') as f:
             f.write(contents)
 
+    def _del_named_file(self, path):
+        try:
+            os.unlink(os.path.join(self.controldir(), path))
+        except (IOError, OSError) as e:
+            if e.errno == errno.ENOENT:
+                return
+            raise
+
     def get_named_file(self, path, basedir=None):
         """Get a file from the control dir with a specific name.
 
@@ -1283,6 +1303,12 @@ class MemoryRepo(BaseRepo):
         """
         self._named_files[path] = contents
 
+    def _del_named_file(self, path):
+        try:
+            del self._named_files[path]
+        except KeyError:
+            pass
+
     def get_named_file(self, path):
         """Get a file from the control dir with a specific name.
 

+ 21 - 0
dulwich/tests/test_repository.py

@@ -754,6 +754,27 @@ class BuildRepoRootTests(TestCase):
         self.assertTrue(stat.S_ISLNK(b_mode))
         self.assertEqual(b'a', r[b_id].data)
 
+    def test_commit_merge_heads(self):
+        r = self._repo
+        with open('a', 'w') as f:
+            f.write('merged text')
+        with open('.git/MERGE_HEADS', 'w') as f:
+            f.write('c27a2d21dd136312d7fa9e8baabb82561a1727d0')
+        r.stage(['a'])
+        commit_sha = r.do_commit(
+            b'deleted a',
+            committer=b'Test Committer <test@nodomain.com>',
+            author=b'Test Author <test@nodomain.com>',
+            commit_timestamp=12395, commit_timezone=0,
+            author_timestamp=12395, author_timezone=0)
+        self.assertEqual([
+            self._root_commit,
+            b'c27a2d21dd136312d7fa9e8baabb82561a1727d0'],
+            r[commit_sha].parents)
+        self.assertEqual([], list(r.open_index()))
+        tree = r[r[commit_sha].tree]
+        self.assertEqual([], list(tree.iteritems()))
+
     def test_commit_deleted(self):
         r = self._repo
         os.remove(os.path.join(r.path, 'a'))