changeset 127:695a90e72e4f

merge from ian dees
author Scott Chacon <schacon@gmail.com>
date Tue, 19 May 2009 09:33:46 -0700
parents 76a0e1ee7cf7 (current diff) 705b88c9f3d1 (diff)
children 8cabda8ae1c6
files dulwich/repo.py git_handler.py
diffstat 4 files changed, 50 insertions(+), 12 deletions(-) [+]
line wrap: on
line diff
--- a/dulwich/object_store.py	Tue May 19 22:21:31 2009 +0900
+++ b/dulwich/object_store.py	Tue May 19 09:33:46 2009 -0700
@@ -22,6 +22,7 @@
 
 import itertools
 import os
+import shutil
 import stat
 import tempfile
 import urllib2
@@ -248,7 +249,12 @@
         basename = os.path.join(self.pack_dir, 
             "pack-%s" % iter_sha1(entry[0] for entry in entries))
         write_pack_index_v2(basename+".idx", entries, p.get_stored_checksum())
-        os.rename(path, basename + ".pack")
+        try:
+            os.rename(path, basename + ".pack")
+        except OSError:
+            # Hack for Windows access denied error.
+            # TODO: mark the original for deletion later.
+            shutil.copyfile(path, basename + ".pack")
         self._add_known_pack(basename)
 
     def add_thin_pack(self):
--- a/dulwich/pack.py	Tue May 19 22:21:31 2009 +0900
+++ b/dulwich/pack.py	Tue May 19 09:33:46 2009 -0700
@@ -128,7 +128,7 @@
 
 
 def load_pack_index(filename):
-    f = open(filename, 'r')
+    f = open(filename, 'rb')
     if f.read(4) == '\377tOc':
         version = struct.unpack(">L", f.read(4))[0]
         if version == 2:
@@ -181,7 +181,7 @@
         # ensure that it hasn't changed.
         self._size = os.path.getsize(filename)
         if file is None:
-            self._file = open(filename, 'r')
+            self._file = open(filename, 'rb')
         else:
             self._file = file
         self._contents, map_offset = simple_mmap(self._file, 0, self._size)
@@ -733,7 +733,7 @@
     :param objects: Iterable over (object, path) tuples to write
     :param num_objects: Number of objects to write
     """
-    f = open(filename + ".pack", 'w')
+    f = open(filename + ".pack", 'wb')
     try:
         entries, data_sum = write_pack_data(f, objects, num_objects)
     finally:
@@ -797,7 +797,7 @@
             crc32_checksum.
     :param pack_checksum: Checksum of the pack file.
     """
-    f = open(filename, 'w')
+    f = open(filename, 'wb')
     f = SHA1Writer(f)
     fan_out_table = defaultdict(lambda: 0)
     for (name, offset, entry_checksum) in entries:
@@ -945,7 +945,7 @@
             crc32_checksum.
     :param pack_checksum: Checksum of the pack file.
     """
-    f = open(filename, 'w')
+    f = open(filename, 'wb')
     f = SHA1Writer(f)
     f.write('\377tOc') # Magic!
     f.write(struct.pack(">L", 2))
--- a/dulwich/repo.py	Tue May 19 22:21:31 2009 +0900
+++ b/dulwich/repo.py	Tue May 19 09:33:46 2009 -0700
@@ -173,14 +173,12 @@
     def _get_ref(self, file):
         f = open(file, 'rb')
         try:
-            contents = f.read()
+            contents = f.read().strip()
             if contents.startswith(SYMREF):
                 ref = contents[len(SYMREF):]
-                if ref[-1] == '\n':
-                    ref = ref[:-1]
                 return self.ref(ref)
-            assert len(contents) == 41, 'Invalid ref in %s' % file
-            return contents[:-1]
+            assert len(contents) == 40, 'Invalid ref in %s' % file
+            return contents
         finally:
             f.close()
 
--- a/git_handler.py	Tue May 19 22:21:31 2009 +0900
+++ b/git_handler.py	Tue May 19 09:33:46 2009 -0700
@@ -124,6 +124,7 @@
     def push(self, remote_name):
         self.ui.status(_("pushing to : %s\n") % remote_name)
         self.export()
+        self.update_remote_references(remote_name)
         self.upload_pack(remote_name)
 
     def remote_add(self, remote_name, git_url):
@@ -154,10 +155,36 @@
         return self._config['remote.' + remote_name + '.url']
 
     def update_references(self):
-        # TODO : if bookmarks exist, add them as git branches
+        try:
+            # We only care about bookmarks of the form 'name',
+            # not 'remote/name'.
+            def is_local_ref(item): return item[0].count('/') == 0
+            bms = bookmarks.parse(self.repo)
+            bms = dict(filter(is_local_ref, bms.items()))
+
+            # Create a local Git branch name for each
+            # Mercurial bookmark.
+            for key in bms:
+                hg_sha  = hex(bms[key])
+                git_sha = self.map_git_get(hg_sha)
+                self.git.set_ref('refs/heads/' + key, git_sha)
+        except AttributeError:
+            # No bookmarks extension
+            pass
+
         c = self.map_git_get(hex(self.repo.changelog.tip()))
         self.git.set_ref('refs/heads/master', c)
 
+    # Make sure there's a refs/remotes/remote_name/name
+    #           for every refs/heads/name
+    def update_remote_references(self, remote_name):
+        self.git.set_remote_refs(self.local_heads(), remote_name)
+
+    def local_heads(self):
+        def is_local_head(item): return item[0].startswith('refs/heads')
+        refs = self.git.get_refs()
+        return dict(filter(is_local_head, refs.items()))
+
     def export_git_objects(self):
         self.ui.status(_("exporting git objects\n"))
         total = len(self.repo.changelog)
@@ -370,6 +397,13 @@
                     if local_ref:
                         if not local_ref == refs[ref_name]:
                             changed[ref_name] = local_ref
+        
+        # Also push any local branches not on the server yet
+        for head in self.local_heads():
+            if not head in refs:
+                ref = self.git.ref(head)
+                changed[head] = ref
+
         return changed
 
     # takes a list of shas the server wants and shas the server has