Jelmer Vernooij vor 16 Jahren
Ursprung
Commit
3f289e1cf3
5 geänderte Dateien mit 33 neuen und 17 gelöschten Zeilen
  1. 8 1
      dulwich/client.py
  2. 1 0
      dulwich/pack.py
  3. 4 4
      dulwich/protocol.py
  4. 4 2
      dulwich/repo.py
  5. 16 10
      dulwich/server.py

+ 8 - 1
dulwich/client.py

@@ -75,10 +75,17 @@ class GitClient(object):
             self.proto.write_pkt_line(None)
             return
         self.proto.write_pkt_line("%s %s %s\0%s" % (changed_refs[0][0], changed_refs[0][1], changed_refs[0][2], self.capabilities()))
+        want = []
+        have = []
         for changed_ref in changed_refs[:]:
             self.proto.write_pkt_line("%s %s %s" % changed_refs)
+            want.append(changed_refs[1])
+            if changed_refs[0] != "0"*40:
+                have.append(changed_refs[0])
         self.proto.write_pkt_line(None)
-        # FIXME: Send pack
+        # FIXME: This is implementation specific
+        # shas = generate_pack_contents(want, have, None)
+        # write_pack_data(self.write, shas, len(shas))
 
     def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress):
         """Retrieve a pack from a git smart server.

+ 1 - 0
dulwich/pack.py

@@ -799,3 +799,4 @@ def load_packs(path):
     for name in os.listdir(path):
         if name.startswith("pack-") and name.endswith(".pack"):
             yield Pack(os.path.join(path, name[:-len(".pack")]))
+

+ 4 - 4
dulwich/protocol.py

@@ -80,12 +80,12 @@ class Protocol(object):
         :param channel: int specifying which channel to write to
         :param blob: a blob of data (as a string) to send on this channel
         """
-        # a pktline can be a max of 65535. a sideband line can therefore be
-        # 65535-5 = 65530
+        # a pktline can be a max of 65520. a sideband line can therefore be
+        # 65520-5 = 65515
         # WTF: Why have the len in ASCII, but the channel in binary.
         while blob:
-            self.write_pkt_line("%s%s" % (chr(channel), blob[:65530]))
-            blob = blob[65530:]
+            self.write_pkt_line("%s%s" % (chr(channel), blob[:65515]))
+            blob = blob[65515:]
 
     def send_cmd(self, cmd, *args):
         """

+ 4 - 2
dulwich/repo.py

@@ -84,7 +84,7 @@ class Repo(object):
     :param progress: Simple progress function that will be called with 
         updated progress strings.
     """
-    wants = determine_wants(self.heads())
+    wants = determine_wants(self.get_refs())
     commits_to_send = set(wants)
     sha_done = set()
     ref = graph_walker.next()
@@ -171,7 +171,9 @@ class Repo(object):
         return self._get_ref(file)
 
   def get_refs(self):
-    ret = {"HEAD": self.head()}
+    ret = {}
+    if self.head():
+        ret['HEAD'] = self.head()
     for dir in ["refs/heads", "refs/tags"]:
         for name in os.listdir(os.path.join(self.controldir(), dir)):
           path = os.path.join(self.controldir(), dir, name)

+ 16 - 10
dulwich/server.py

@@ -19,7 +19,7 @@
 import SocketServer
 from dulwich.protocol import Protocol, ProtocolFile, TCP_GIT_PORT, extract_capabilities
 from dulwich.repo import Repo
-from dulwich.pack import PackData, Pack, write_pack_data
+from dulwich.pack import PackData, Pack, write_pack_data, generate_pack_contents
 import os, sha, tempfile
 
 class Backend(object):
@@ -40,7 +40,7 @@ class Backend(object):
         """
         raise NotImplementedError
 
-    def fetch_objects(self, determine_wants, graph_waker, progress):
+    def fetch_objects(self, determine_wants, graph_walker, progress):
         """
         Yield the objects required for a list of commits.
 
@@ -84,6 +84,11 @@ class GitBackend(Backend):
 
         print "pack applied"
 
+    def fetch_objects(self, determine_wants, graph_walker, progress):
+        shas = self.repo.find_missing_objects(determine_wants, graph_walker, progress)
+        for sha in shas:
+            yield self.repo.get_object(sha)
+
 
 class Handler(object):
 
@@ -104,9 +109,9 @@ class UploadPackHandler(Handler):
         def determine_wants(heads):
             keys = heads.keys()
             if keys:
-                self.proto.write_pkt_line("%s %s\x00%s\n" % (keys[0], heads[keys[0]], self.capabilities()))
+                self.proto.write_pkt_line("%s %s\x00%s\n" % ( heads[keys[0]], keys[0], self.capabilities()))
                 for k in keys[1:]:
-                    self.proto.write_pkt_line("%s %s\n" % (k, heads[k]))
+                    self.proto.write_pkt_line("%s %s\n" % (heads[k], k))
 
             # i'm done..
             self.proto.write("0000")
@@ -121,17 +126,17 @@ class UploadPackHandler(Handler):
 
             want_revs = []
             while want and want[:4] == 'want':
-                want_rev = want[5:45]
-                # FIXME: This check probably isnt needed?
-                want_revs.append(want_rev)
+                want_revs.append(want[5:45])
                 want = self.proto.read_pkt_line()
             return want_revs
 
         progress = lambda x: self.proto.write_sideband(2, x)
+        write = lambda x: self.proto.write_sideband(1, x)
 
         class ProtocolGraphWalker(object):
 
-            def __init__(self):
+            def __init__(self, proto):
+                self.proto = proto
                 self._last_sha = None
 
             def ack(self, have_ref):
@@ -142,8 +147,8 @@ class UploadPackHandler(Handler):
                 if have[:4] == 'have':
                     return have[5:45]
 
-                if have[:4] == 'done':
-                    return None
+                #if have[:4] == 'done':
+                #    return None
 
                 if self._last_sha:
                     # Oddness: Git seems to resend the last ACK, without the "continue" statement
@@ -152,6 +157,7 @@ class UploadPackHandler(Handler):
                 # The exchange finishes with a NAK
                 self.proto.write_pkt_line("NAK\n")
 
+        graph_walker = ProtocolGraphWalker(self.proto)
         objects = list(self.backend.fetch_objects(determine_wants, graph_walker, progress))
         progress("dul-daemon says what\n")
         progress("counting objects: %d, done.\n" % len(objects))