changeset 12:227b11d75844

updates bookmarks and beginnings of seperate remotes support
author Scott Chacon <schacon@gmail.com>
date Sun, 26 Apr 2009 14:49:38 -0700
parents f2826f7b1ae5
children 01f28d40cb6a
files TODO.txt __init__.py dulwich/repo.py git_handler.py
diffstat 4 files changed, 54 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/TODO.txt
+++ b/TODO.txt
@@ -5,7 +5,7 @@
 * update/add bookmarks
 * checkout the tip
 * limit to HEAD branch? (gh-pages makes weird import)
-* some sort of remote management
+  - possibly also add bookmarks on the same development line
 
 * tag conversion
 
@@ -13,12 +13,14 @@
 ===========
 
 * gfetch command
+* some sort of remote management
 
 PUSH
 ==========
 
 * get a list of all the hg changesets not yet mapped
 * create git objects from each changeset (incl trees/blobs)
+  - add metadata to commits (branch names, explicit file names)
 * update mapfile with new changeset/commit mapping
 * connect to server pushing to
   - figure out needs (use heads/bookmarks for haves)
--- a/__init__.py
+++ b/__init__.py
@@ -42,7 +42,8 @@
     
     # fetch the initial git data
     git = GitHandler(dest_repo, ui)
-    git.fetch(git_url)
+    git.remote_add('origin', git_url)
+    git.fetch('origin')
     
     # checkout the tip
     hg.update(dest_repo, None)
--- a/dulwich/repo.py
+++ b/dulwich/repo.py
@@ -231,11 +231,25 @@
         finally:
             f.close()
 
+    # takes refs passed from remote and renames them
+    def set_remote_refs(self, refs, remote_name):
+        keys = refs.keys()
+        if not keys:
+            return None
+        for k in keys[0:]:
+            ref_name = k
+            parts = k.split('/')
+            if parts[0] == 'refs': # strip off 'refs/heads'
+                ref_name = "/".join([v for v in parts[2:]])
+            self.set_ref('refs/remotes/' + remote_name + '/' + ref_name, refs[k])
+        
     def set_refs(self, refs):
         keys = refs.keys()
-        if keys:
-            for k in keys[0:]:
-                self.set_ref(k, refs[k])
+        if not keys:
+            return None
+        for k in keys[0:]:
+            self.set_ref(k, refs[k])
+                    
         
     def set_ref(self, name, value):
         file = os.path.join(self.controldir(), name)
@@ -270,6 +284,13 @@
                 ret[name] = self._get_ref(os.path.join(root, name))
         return ret
 
+    def remote_refs(self, remote_name):
+        ret = {}
+        for root, dirs, files in os.walk(os.path.join(self.controldir(), 'refs', 'remotes', remote_name)):
+            for name in files:
+                ret[name] = self._get_ref(os.path.join(root, name))
+        return ret
+
     def head(self):
         return self.ref('HEAD')
 
--- a/git_handler.py
+++ b/git_handler.py
@@ -2,6 +2,7 @@
 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
@@ -32,14 +33,22 @@
             file.write("%s %s\n" % (gitsha, hgsha))
         file.close()
 
-    def fetch(self, git_url):
-        self.ui.status(_("fetching from git url: " + git_url + "\n"))
+    def fetch(self, remote_name):
+        self.ui.status(_("fetching from : " + remote_name + "\n"))
         self.export_git_objects()
-        self.fetch_pack(git_url)
-        self.import_git_objects()
+        self.fetch_pack(remote_name)
+        self.import_git_objects(remote_name)
         self.save_map()
 
-    def fetch_pack(self, git_url):
+    # TODO: make these actually save and recall
+    def remote_add(self, remote_name, git_url):
+        self._git_url = git_url
+        
+    def remote_name_to_url(self, remote_name):
+        return self._git_url
+        
+    def fetch_pack(self, remote_name):
+        git_url = self.remote_name_to_url(remote_name)
         client, path = self.get_transport_and_path(git_url)
         graphwalker = SimpleFetchGraphWalker(self.git.heads().values(), self.git.get_parents)
         f, commit = self.git.object_store.add_pack()
@@ -48,12 +57,12 @@
             refs = client.fetch_pack(path, determine_wants, graphwalker, f.write, sys.stdout.write)
             f.close()
             commit()
-            self.git.set_refs(refs)
+            self.git.set_remote_refs(refs, remote_name)
         except:
             f.close()
             raise    
 
-    def import_git_objects(self):
+    def import_git_objects(self, remote_name):
         self.ui.status(_("importing Git objects into Hg\n"))
         # import heads as remote references
         todo = []
@@ -61,7 +70,7 @@
         convert_list = {}
         
         # get a list of all the head shas
-        for head, sha in self.git.heads().iteritems():
+        for head, sha in self.git.remote_refs(remote_name).iteritems():
             todo.append(sha)
         
         # traverse the heads getting a list of all the unique commits
@@ -83,9 +92,15 @@
         for csha in commits:
             commit = convert_list[csha]
             self.import_git_commit(commit)
-    
+        
         # TODO : update Hg bookmarks
-        print bookmarks.parse(self.repo)
+        bms = {}
+        for head, sha in self.git.remote_refs(remote_name).iteritems():
+            hgsha = hex_to_sha(self._map[sha])
+            bms[head] = hgsha
+            
+        print bms    
+        bookmarks.write(self.repo, bms)
 
     def import_git_commit(self, commit):
         print "importing: " + commit.id