Преглед изворни кода

Merge support for only negotiating capabilities that are also supported by the
server.

Jelmer Vernooij пре 13 година
родитељ
комит
ac150c36d6
3 измењених фајлова са 25 додато и 11 уклоњено
  1. 3 0
      NEWS
  2. 9 11
      dulwich/client.py
  3. 13 0
      dulwich/tests/test_client.py

+ 3 - 0
NEWS

@@ -5,6 +5,9 @@
   * Options on the same line as sections in config files are now supported.
     (Jelmer Vernooij, #920553)
 
+  * Only negotiate capabilities that are also supported by the server.
+    (Rod Cloutier, Risto Kankkunen)
+
  TESTS
 
   * $HOME is now explicitly specified for tests that use it to read

+ 9 - 11
dulwich/client.py

@@ -153,10 +153,10 @@ class GitClient(object):
             activity.
         """
         self._report_activity = report_activity
-        self._fetch_capabilities = list(FETCH_CAPABILITIES)
-        self._send_capabilities = list(SEND_CAPABILITIES)
+        self._fetch_capabilities = set(FETCH_CAPABILITIES)
+        self._send_capabilities = set(SEND_CAPABILITIES)
         if thin_packs:
-            self._fetch_capabilities.append('thin-pack')
+            self._fetch_capabilities.add('thin-pack')
 
     def _read_refs(self, proto):
         server_capabilities = None
@@ -169,7 +169,7 @@ class GitClient(object):
             if server_capabilities is None:
                 (ref, server_capabilities) = extract_capabilities(ref)
             refs[ref] = sha
-        return refs, server_capabilities
+        return refs, set(server_capabilities)
 
     def send_pack(self, path, determine_wants, generate_pack_contents,
                   progress=None):
@@ -438,9 +438,7 @@ class TraditionalGitClient(GitClient):
         """
         proto, unused_can_read = self._connect('receive-pack', path)
         old_refs, server_capabilities = self._read_refs(proto)
-        negotiated_capabilities = list(self._send_capabilities)
-        if 'report-status' not in server_capabilities:
-            negotiated_capabilities.remove('report-status')
+        negotiated_capabilities = self._send_capabilities & server_capabilities
         try:
             new_refs = determine_wants(old_refs)
         except:
@@ -470,8 +468,8 @@ class TraditionalGitClient(GitClient):
         :param progress: Callback for progress reports (strings)
         """
         proto, can_read = self._connect('upload-pack', path)
-        (refs, server_capabilities) = self._read_refs(proto)
-        negotiated_capabilities = list(self._fetch_capabilities)
+        refs, server_capabilities = self._read_refs(proto)
+        negotiated_capabilities = self._fetch_capabilities & server_capabilities
         try:
             wants = determine_wants(refs)
         except:
@@ -708,7 +706,7 @@ class HttpGitClient(GitClient):
         url = self._get_url(path)
         old_refs, server_capabilities = self._discover_references(
             "git-receive-pack", url)
-        negotiated_capabilities = list(self._send_capabilities)
+        negotiated_capabilities = self._send_capabilities & server_capabilities
         new_refs = determine_wants(old_refs)
         if new_refs is None:
             return old_refs
@@ -743,7 +741,7 @@ class HttpGitClient(GitClient):
         url = self._get_url(path)
         refs, server_capabilities = self._discover_references(
             "git-upload-pack", url)
-        negotiated_capabilities = list(server_capabilities)
+        negotiated_capabilities = server_capabilities
         wants = determine_wants(refs)
         if wants is not None:
             wants = [cid for cid in wants if cid != ZERO_SHA]

+ 13 - 0
dulwich/tests/test_client.py

@@ -152,6 +152,19 @@ class GitClientTests(TestCase):
         self.assertTrue(isinstance(client, HttpGitClient))
         self.assertEquals('/jelmer/dulwich', path)
 
+    def test_send_pack_no_sideband64k_with_update_ref_error(self):
+        # No side-bank-64k reported by server shouldn't try to parse
+        # side band data
+        pkts = ['55dcc6bf963f922e1ed5c4bbaaefcfacef57b1d7 capabilities^{}\x00 report-status ofs-delta\n',
+                '',
+                "unpack ok",
+                "ng refs/foo/bar pre-receive hook declined",
+                '']
+        for pkt in pkts:
+            self.rin.write("0000" if pkt == '' else "%04x%s" % (len(pkt)+4, pkt))
+        self.rin.seek(0)
+        self.assertRaises(UpdateRefsError, lambda : self.client.send_pack("blah", lambda x: {} , lambda h,w: []))
+
 
 class SSHGitClientTests(TestCase):