changeset 38:f0daee676e10

successful push to an upstream git server - BOOYAH!
author Scott Chacon <schacon@gmail.com>
date Tue, 28 Apr 2009 14:28:27 -0700
parents 7046d792dfcd
children 173e738d0da4 b9c6871c939e
files dulwich/client.py dulwich/protocol.py dulwich/repo.py git_handler.py
diffstat 4 files changed, 52 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/dulwich/client.py
+++ b/dulwich/client.py
@@ -26,6 +26,7 @@
 import socket
 import subprocess
 import copy
+import tempfile
 
 from protocol import (
     Protocol,
@@ -112,15 +113,12 @@
         :param generate_pack_contents: Function that can return the shas of the 
             objects to upload.
         """
-        print 'SEND PACK'
         refs, server_capabilities = self.read_refs()
         changed_refs = get_changed_refs(refs)
         if not changed_refs:
-            print 'got here - nooo'
+            print 'nothing changed'
             self.proto.write_pkt_line(None)
             return
-        print 'got here - yay'
-        print changed_refs
         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 = []
@@ -131,7 +129,15 @@
                 have.append(changed_ref[0])
         self.proto.write_pkt_line(None)
         shas = generate_pack_contents(want, have)
-        #write_pack_data(self.write, shas, len(shas))
+            
+        (fd, tmppath) = tempfile.mkstemp(suffix=".pack")
+        f = os.fdopen(fd, 'w')        
+        (entries, sha) = write_pack_data(f, shas, len(shas))
+
+        f = open(tmppath, "r")
+        self.proto.write_file(f)
+        self.proto.write(sha)
+        f.close()
 
     def fetch_pack(self, path, determine_wants, graph_walker, pack_data, progress):
         """Retrieve a pack from a git smart server.
--- a/dulwich/protocol.py
+++ b/dulwich/protocol.py
@@ -79,6 +79,13 @@
             yield pkt
             pkt = self.read_pkt_line()
 
+    def write_file(self, f):
+        try:
+            for line in f:
+                self.write(line)
+        finally:
+            f.close()
+        
     def write_pkt_line(self, line):
         """
         Sends a 'pkt line' to the remote git process
--- a/dulwich/repo.py
+++ b/dulwich/repo.py
@@ -361,7 +361,6 @@
         commit_data += 'committer ' + commit['committer'] + "\n"
         commit_data += "\n"
         commit_data += commit['message']
-        print commit_data
         sha = self.write_object('commit', commit_data)
         return sha
 
--- a/git_handler.py
+++ b/git_handler.py
@@ -2,12 +2,19 @@
 import dulwich
 from dulwich.repo import Repo
 from dulwich.client import SimpleFetchGraphWalker
-from dulwich.objects import hex_to_sha
 from hgext import bookmarks
 from mercurial.i18n import _
 from mercurial.node import bin, hex, nullid
 from mercurial import hg, util, context, error
-
+from dulwich.objects import (
+    Blob,
+    Commit,
+    ShaFile,
+    Tag,
+    Tree,
+    hex_to_sha
+    )
+    
 import math
 
 def seconds_to_offset(time):
@@ -277,8 +284,6 @@
             if parts[0] == 'refs': # strip off 'refs/heads'
                 if parts[1] == 'heads':
                     head = "/".join([v for v in parts[2:]])
-                    print ref_name
-                    print head
                     local_ref = self.git.ref(ref_name)
                     if local_ref: 
                         if not local_ref == refs[ref_name]:
@@ -297,7 +302,31 @@
             else:
                 shas.append(next)
             next = graph_walker.next()
-        return shas
+            
+        # so now i have the shas, need to turn them into a list of 
+        # tuples (sha, path) for ALL the objects i'm sending
+        # TODO : don't send blobs or trees they already have
+        def get_objects(tree, path):
+            changes = list()
+            changes.append((tree, path))
+            for (mode, name, sha) in tree.entries():
+                if mode == 57344: # TODO : properly handle submodules
+                    continue
+                obj = self.git.get_object(sha)
+                if isinstance (obj, Blob):
+                    changes.append((obj, path + name))
+                elif isinstance(obj, Tree):
+                    changes.extend (get_objects (obj, path + name + '/'))
+            return changes
+            
+        objects = []
+        for commit_sha in shas:
+            commit = self.git.commit(commit_sha)
+            objects.append((commit, 'commit'))
+            tree = self.git.get_object(commit.tree)
+            objects.extend( get_objects(tree, '/') )
+            
+        return objects
         
     def fetch_pack(self, remote_name):
         git_url = self.remote_name_to_url(remote_name)