Browse Source

Add support for prune/prune_tags arguments to porcelain.fetch.

Jelmer Vernooij 6 năm trước cách đây
mục cha
commit
d8a1bed443
4 tập tin đã thay đổi với 49 bổ sung4 xóa
  1. 3 0
      NEWS
  2. 8 3
      dulwich/porcelain.py
  3. 12 1
      dulwich/refs.py
  4. 26 0
      dulwich/tests/test_refs.py

+ 3 - 0
NEWS

@@ -4,6 +4,9 @@
 
  * Add support for short ids in parse_commit. (Jelmer Vernooij)
 
+ * Add support for ``prune`` and ``prune_tags`` arguments
+   to ``porcelain.fetch``. (Jelmer Vernooij, #681)
+
 0.19.10	2018-01-15
 
  IMPROVEMENTS

+ 8 - 3
dulwich/porcelain.py

@@ -1098,7 +1098,7 @@ def branch_list(repo):
 
 def fetch(repo, remote_location, remote_name=b'origin', outstream=sys.stdout,
           errstream=default_bytes_err_stream, message=None, depth=None,
-          **kwargs):
+          prune=False, prune_tags=False, **kwargs):
     """Fetch objects from a remote server.
 
     :param repo: Path to the repository
@@ -1108,6 +1108,8 @@ def fetch(repo, remote_location, remote_name=b'origin', outstream=sys.stdout,
     :param errstream: Error stream (defaults to stderr)
     :param message: Reflog message (defaults to b"fetch: from <remote_name>")
     :param depth: Depth to fetch at
+    :param prune: Prune remote removed refs
+    :param prune_tags: Prune reomte removed tags
     :return: Dictionary with refs on the remote
     """
     if message is None:
@@ -1122,12 +1124,15 @@ def fetch(repo, remote_location, remote_name=b'origin', outstream=sys.stdout,
             n[len(b'refs/heads/'):]: v for (n, v) in stripped_refs.items()
             if n.startswith(b'refs/heads/')}
         r.refs.import_refs(
-            b'refs/remotes/' + remote_name, branches, message=message)
+            b'refs/remotes/' + remote_name, branches, message=message,
+            prune=prune)
         tags = {
             n[len(b'refs/tags/'):]: v for (n, v) in stripped_refs.items()
             if n.startswith(b'refs/tags/') and
             not n.endswith(ANNOTATED_TAG_SUFFIX)}
-        r.refs.import_refs(b'refs/tags', tags, message=message)
+        r.refs.import_refs(
+            b'refs/tags', tags, message=message,
+            prune=prune_tags)
     return fetch_result.refs
 
 

+ 12 - 1
dulwich/refs.py

@@ -138,10 +138,21 @@ class RefsContainer(object):
         return None
 
     def import_refs(self, base, other, committer=None, timestamp=None,
-                    timezone=None, message=None):
+                    timezone=None, message=None, prune=False):
+        if prune:
+            to_delete = set(self.subkeys(base))
+        else:
+            to_delete = set()
         for name, value in other.items():
             self.set_if_equals(b'/'.join((base, name)), None, value,
                                message=message)
+            if to_delete:
+                try:
+                    to_delete.remove(name)
+                except KeyError:
+                    pass
+        for ref in to_delete:
+            self.remove_if_equals(b'/'.join((base, ref)), None)
 
     def allkeys(self):
         """All refs present in this container."""

+ 26 - 0
dulwich/tests/test_refs.py

@@ -288,6 +288,32 @@ class RefsContainerTests(object):
             b'refs/tags/refs-0.2', ZERO_SHA))
         self.assertFalse(b'refs/tags/refs-0.2' in self._refs)
 
+    def test_import_refs_name(self):
+        self._refs[b'refs/remotes/origin/other'] = (
+            b'48d01bd4b77fed026b154d16493e5deab78f02ec')
+        self._refs.import_refs(
+            b'refs/remotes/origin',
+            {b'master': b'42d06bd4b77fed026b154d16493e5deab78f02ec'})
+        self.assertEqual(
+            b'42d06bd4b77fed026b154d16493e5deab78f02ec',
+            self._refs[b'refs/remotes/origin/master'])
+        self.assertEqual(
+            b'48d01bd4b77fed026b154d16493e5deab78f02ec',
+            self._refs[b'refs/remotes/origin/other'])
+
+    def test_import_refs_name_prune(self):
+        self._refs[b'refs/remotes/origin/other'] = (
+            b'48d01bd4b77fed026b154d16493e5deab78f02ec')
+        self._refs.import_refs(
+            b'refs/remotes/origin',
+            {b'master': b'42d06bd4b77fed026b154d16493e5deab78f02ec'},
+            prune=True)
+        self.assertEqual(
+            b'42d06bd4b77fed026b154d16493e5deab78f02ec',
+            self._refs[b'refs/remotes/origin/master'])
+        self.assertNotIn(
+            b'refs/remotes/origin/other', self._refs)
+
 
 class DictRefsContainerTests(RefsContainerTests, TestCase):