changeset 165:cb922a0ca22d

almost got everything working
author Scott Chacon <schacon@gmail.com>
date Mon, 01 Jun 2009 14:57:19 -0700
parents 7e98757deadc
children 405a915bf352
files __init__.py git_handler.py hgrepo.py
diffstat 3 files changed, 146 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/__init__.py	Fri May 29 13:10:14 2009 -0700
+++ b/__init__.py	Mon Jun 01 14:57:19 2009 -0700
@@ -20,8 +20,9 @@
 from git_handler import GitHandler
 
 # support for `hg clone git://github.com/defunkt/facebox.git`
-import gitrepo
+import gitrepo, hgrepo
 hg.schemes['git'] = gitrepo
+hg.schemes['file'] = hgrepo
 
 def gclone(ui, git_url, hg_repo_path=None):
     # determine new repo name
@@ -32,6 +33,8 @@
         hg_repo_path += '-hg'
     dest_repo = hg.repository(ui, hg_repo_path, create=True)
 
+    print dest_repo
+
     # fetch the initial git data
     git = GitHandler(dest_repo, ui)
     git.remote_add('origin', git_url)
--- a/git_handler.py	Fri May 29 13:10:14 2009 -0700
+++ b/git_handler.py	Mon Jun 01 14:57:19 2009 -0700
@@ -284,12 +284,13 @@
                 extra_message += "rename : " + oldfile + " => " + newfile + "\n"
 
         for key, value in extra.iteritems():
-            if key in ['committer', 'encoding', 'branch', 'hg-git', 'git']:
+            if key in ['committer', 'encoding', 'branch', 'hg-git']:
                 continue
             else:
                 add_extras = True        
                 extra_message += "extra : " + key + " : " +  urllib.quote(value) + "\n"
 
+
         if add_extras:
             commit['message'] += "\n--HG--\n" + extra_message
 
@@ -635,7 +636,6 @@
         split = message.split("\n\n--HG--\n", 1)
         renames = {}
         extra = {}
-        files = []
         branch = False
         if len(split) == 2:
             message, meta = split
@@ -651,15 +651,13 @@
                     renames[after] = before
                 if command == 'branch':
                     branch = data
-                if command == 'files':
-                    files.append(data)
                 if command == 'extra':
                     before, after = data.split(" : ", 1)
                     extra[before] = urllib.unquote(after)
-        return (message, renames, branch, files, extra)
+        return (message, renames, branch, extra)
 
     def pseudo_import_git_commit(self, commit):
-        (strip_message, hg_renames, hg_branch) = self.extract_hg_metadata(commit.message)
+        (strip_message, hg_renames, hg_branch, extra) = self.extract_hg_metadata(commit.message)
         cs = self.map_hg_get(commit.id)
         p1 = nullid
         p2 = nullid
@@ -685,11 +683,11 @@
         # TODO : Do something less coarse-grained than try/except on the
         #        get_file call for removed files
 
-        (strip_message, hg_renames, hg_branch, files, extra) = self.extract_hg_metadata(commit.message)
+        (strip_message, hg_renames, hg_branch, extra) = self.extract_hg_metadata(commit.message)
         
         # get a list of the changed, added, removed files
         files = self.git.get_files_changed(commit)
-
+        
         date = (commit.author_time, -commit.author_timezone)
         text = strip_message
 
@@ -714,7 +712,7 @@
             def commit_octopus(p1, p2):
                 ctx = context.memctx(self.repo, (p1, p2), text, files, getfilectx,
                                      commit.author, date, {'hg-git': 'octopus'})
-                return hex(self.repo.commitctx(ctx))
+                return hex(self.repo.commitctx(ctx, None))
 
             octopus = len(gparents) > 2
             p2 = gparents.pop()
@@ -725,15 +723,17 @@
         else:
             if gparents:
                 p1 = gparents.pop()
+        
+        files = list(set(files))
 
-        # wierd hack for explicit file renames in first but not second branch
+        pa = None
         if not (p2 == nullid):
-            vals = [item for item in self.renames[p1].values() if not item in self.renames[p2].values()]
-            for removefile in vals:
-                files.remove(removefile)
+            node1 = self.repo.changectx(p1)
+            node2 = self.repo.changectx(p2)
+            pa = node1.ancestor(node2)
+
         author = commit.author
 
-        extra = {}
         if ' <none@none>' in commit.author:
             author = commit.author[:-12]
 
@@ -756,7 +756,8 @@
 
         ctx = context.memctx(self.repo, (p1, p2), text, files, getfilectx,
                              author, date, extra)
-        node = self.repo.commitctx(ctx)
+        
+        node = self.repo.commitctx(ctx, pa)
 
         # save changeset to mapping file
         cs = hex(node)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hgrepo.py	Mon Jun 01 14:57:19 2009 -0700
@@ -0,0 +1,126 @@
+from mercurial import localrepo, lock, node
+from mercurial import changelog, dirstate, filelog, manifest, context, weakref
+from mercurial.node import bin, hex, nullid, nullrev, short
+
+class hgrepo(localrepo.localrepository):
+
+    def commitctx(self, wctx, ancestor):
+    
+        tr = None
+        valid = 0 # don't save the dirstate if this isn't set
+        try:
+            force=False
+            force_editor=False
+            empty_ok=False
+            use_dirstate=False
+            update_dirstate=False
+            
+            commit = sorted(wctx.modified() + wctx.added())
+            remove = wctx.removed()
+            extra = wctx.extra().copy()
+            branchname = extra['branch']
+            user = wctx.user()
+            text = wctx.description()
+
+            p1, p2 = [p.node() for p in wctx.parents()]
+            c1 = self.changelog.read(p1)
+            c2 = self.changelog.read(p2)
+            m1 = self.manifest.read(c1[0]).copy()
+            m2 = self.manifest.read(c2[0])
+            ma = None
+            if ancestor:
+                ma = ancestor.manifest()
+
+            xp1 = hex(p1)
+            if p2 == nullid: xp2 = ''
+            else: xp2 = hex(p2)
+
+            tr = self.transaction()
+            trp = weakref.proxy(tr)
+
+            # retarded.  this is retarded.
+            for f in m1:
+                if (f in m2) and (not f in commit) and (not m1[f] == m2[f]):
+                    commit.append(f)
+                    
+            # check in files
+            new = {}
+            changed = []
+            linkrev = len(self)
+            for f in commit:
+                self.ui.note(f + "\n")
+                try:
+                    fctx = wctx.filectx(f)
+                    newflags = fctx.flags()
+                    new[f] = self.filecommit(fctx, m1, m2, linkrev, trp, changed)
+                    if ((not changed or changed[-1] != f) and
+                        m2.get(f) != new[f]):
+                        # mention the file in the changelog if some
+                        # flag changed, even if there was no content
+                        # change.
+                        if m1.flags(f) != newflags:
+                            changed.append(f)
+                    m1.set(f, newflags)
+
+                except (OSError, IOError):
+                    remove.append(f)
+
+            print 'CHANGED'
+            print changed
+            
+            updated, added = [], []
+            for f in sorted(changed):
+                if f in m1 or f in m2:
+                    updated.append(f)
+                else:
+                    added.append(f)
+            
+            # update manifest
+            m1.update(new)
+            removed = [f for f in sorted(remove) if f in m1 or f in m2]
+            removed1 = []
+
+            for f in removed:
+                if f in m1:
+                    del m1[f]
+                    removed1.append(f)
+                else:
+                    if ma and (f in ma):
+                        del ma[f]
+                        removed.remove(f)
+            
+            mn = self.manifest.add(m1, trp, linkrev, c1[0], c2[0],
+                                   (new, removed1))
+
+            lines = [line.rstrip() for line in text.rstrip().splitlines()]
+            while lines and not lines[0]:
+                del lines[0]
+            if not lines and use_dirstate:
+                raise util.Abort(_("empty commit message"))
+            text = '\n'.join(lines)
+
+            self.changelog.delayupdate()
+            n = self.changelog.add(mn, changed + removed, text, trp, p1, p2,
+                                   user, wctx.date(), extra)
+            p = lambda: self.changelog.writepending() and self.root or ""
+            self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1,
+                      parent2=xp2, pending=p)
+            self.changelog.finalize(trp)
+            tr.close()
+            
+            if self.branchcache:
+                self.branchtags()
+
+            if update_dirstate:
+                self.dirstate.setparents(n)
+            valid = 1 # our dirstate updates are complete
+
+            self.hook("commit", node=hex(n), parent1=xp1, parent2=xp2)
+            return n
+        finally:
+            if not valid: # don't save our updated dirstate
+                self.dirstate.invalidate()
+            del tr
+
+
+instance = hgrepo