Bladeren bron

Fix regression removing untouched refs when pushing over SSH. #441.

Jelmer Vernooij 8 jaren geleden
bovenliggende
commit
ff7b4e9dee
3 gewijzigde bestanden met toevoegingen van 35 en 5 verwijderingen
  1. 5 0
      NEWS
  2. 4 5
      dulwich/client.py
  3. 26 0
      dulwich/tests/test_client.py

+ 5 - 0
NEWS

@@ -1,5 +1,10 @@
 0.15.0	UNRELEASED
 
+ BUG FIXES
+
+  * Fix regression removing untouched refs when pushing over SSH.
+    (Jelmer Vernooij #441)
+
 0.14.0	2016-07-03
 
  BUG FIXES

+ 4 - 5
dulwich/client.py

@@ -345,15 +345,14 @@ class GitClient(object):
         :param proto: Protocol object to read from
         :param capabilities: List of negotiated capabilities
         :param old_refs: Old refs, as received from the server
-        :param new_refs: New refs
+        :param new_refs: Refs to change
         :return: (have, want) tuple
         """
         want = []
         have = [x for x in old_refs.values() if not x == ZERO_SHA]
         sent_capabilities = False
 
-        all_refs = set(new_refs.keys()).union(set(old_refs.keys()))
-        for refname in all_refs:
+        for refname in new_refs:
             if not isinstance(refname, bytes):
                 raise TypeError('refname is not a bytestring: %r' % refname)
             old_sha1 = old_refs.get(refname, ZERO_SHA)
@@ -544,7 +543,7 @@ class TraditionalGitClient(GitClient):
 
             (have, want) = self._handle_receive_pack_head(
                 proto, negotiated_capabilities, old_refs, new_refs)
-            if not want and old_refs == new_refs:
+            if not want and set(new_refs.items()).issubset(set(old_refs.items())):
                 return new_refs
             objects = generate_pack_contents(have, want)
 
@@ -1077,7 +1076,7 @@ class HttpGitClient(GitClient):
         req_proto = Protocol(None, req_data.write)
         (have, want) = self._handle_receive_pack_head(
             req_proto, negotiated_capabilities, old_refs, new_refs)
-        if not want and old_refs == new_refs:
+        if not want and set(new_refs.items()).issubset(set(old_refs.items())):
             return new_refs
         objects = generate_pack_contents(have, want)
         if len(objects) > 0:

+ 26 - 0
dulwich/tests/test_client.py

@@ -190,6 +190,32 @@ class GitClientTests(TestCase):
         self.client.send_pack(b'/', determine_wants, generate_pack_contents)
         self.assertEqual(self.rout.getvalue(), b'0000')
 
+    def test_send_pack_keep_and_delete(self):
+        self.rin.write(
+            b'0063310ca9477129b8586fa2afc779c1f57cf64bba6c '
+            b'refs/heads/master\x00report-status delete-refs ofs-delta\n'
+            b'003f310ca9477129b8586fa2afc779c1f57cf64bba6c refs/heads/keepme\n'
+            b'0000000eunpack ok\n'
+            b'0019ok refs/heads/master\n'
+            b'0000')
+        self.rin.seek(0)
+
+        def determine_wants(refs):
+            return {b'refs/heads/master': b'0' * 40}
+
+        def generate_pack_contents(have, want):
+            return {}
+
+        self.client.send_pack(b'/', determine_wants, generate_pack_contents)
+        self.assertIn(
+            self.rout.getvalue(),
+            [b'007f310ca9477129b8586fa2afc779c1f57cf64bba6c '
+             b'0000000000000000000000000000000000000000 '
+             b'refs/heads/master\x00report-status ofs-delta0000',
+             b'007f310ca9477129b8586fa2afc779c1f57cf64bba6c '
+             b'0000000000000000000000000000000000000000 '
+             b'refs/heads/master\x00ofs-delta report-status0000'])
+
     def test_send_pack_delete_only(self):
         self.rin.write(
             b'0063310ca9477129b8586fa2afc779c1f57cf64bba6c '