diff hgext/transplant.py @ 16400:f2ba409dbb0f

transplant: permit merge changesets via --parent This change permits the transplant extension to operate on merge changesets by way of --parent. This is particularly useful for workflows which cherrypick branch merges rather than each commit within a branch.
author Steven Stallion <sstallion@gmail.com>
date Tue, 10 Apr 2012 23:24:12 -0700
parents f7db54b832af
children 91196ebcaeed
line wrap: on
line diff
--- a/hgext/transplant.py	Thu Apr 12 20:22:18 2012 -0500
+++ b/hgext/transplant.py	Tue Apr 10 23:24:12 2012 -0700
@@ -144,14 +144,26 @@
                     if not hasnode(repo, node):
                         repo.pull(source, heads=[node])
 
+                skipmerge = False
                 if parents[1] != revlog.nullid:
-                    self.ui.note(_('skipping merge changeset %s:%s\n')
-                                 % (rev, short(node)))
+                    if not opts.get('parent'):
+                        self.ui.note(_('skipping merge changeset %s:%s\n')
+                                     % (rev, short(node)))
+                        skipmerge = True
+                    else:
+                        parent = source.lookup(opts['parent'])
+                        if parent not in parents:
+                            raise util.Abort(_('%s is not a parent of %s') %
+                                             (short(parent), short(node)))
+                else:
+                    parent = parents[0]
+
+                if skipmerge:
                     patchfile = None
                 else:
                     fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
                     fp = os.fdopen(fd, 'w')
-                    gen = patch.diff(source, parents[0], node, opts=diffopts)
+                    gen = patch.diff(source, parent, node, opts=diffopts)
                     for chunk in gen:
                         fp.write(chunk)
                     fp.close()
@@ -295,19 +307,29 @@
     def recover(self, repo):
         '''commit working directory using journal metadata'''
         node, user, date, message, parents = self.readlog()
-        merge = len(parents) == 2
+        merge = False
 
         if not user or not date or not message or not parents[0]:
             raise util.Abort(_('transplant log file is corrupt'))
 
+        parent = parents[0]
+        if len(parents) > 1:
+            if opts.get('parent'):
+                parent = source.lookup(opts['parent'])
+                if parent not in parents:
+                    raise util.Abort(_('%s is not a parent of %s') %
+                                     (short(parent), short(node)))
+            else:
+                merge = True
+
         extra = {'transplant_source': node}
         wlock = repo.wlock()
         try:
             p1, p2 = repo.dirstate.parents()
-            if p1 != parents[0]:
+            if p1 != parent:
                 raise util.Abort(
                     _('working dir not at transplant parent %s') %
-                                 revlog.hex(parents[0]))
+                                 revlog.hex(parent))
             if merge:
                 repo.dirstate.setparents(p1, parents[1])
             n = repo.commit(message, user, date, extra=extra,
@@ -468,6 +490,8 @@
     ('a', 'all', None, _('pull all changesets up to BRANCH')),
     ('p', 'prune', [], _('skip over REV'), _('REV')),
     ('m', 'merge', [], _('merge at REV'), _('REV')),
+    ('', 'parent', '',
+     _('parent to choose when transplanting merge'), _('REV')),
     ('e', 'edit', False, _('invoke editor on commit messages')),
     ('', 'log', None, _('append transplant info to log message')),
     ('c', 'continue', None, _('continue last transplant session '
@@ -510,6 +534,9 @@
     of a merged transplant, and you can merge descendants of them
     normally instead of transplanting them.
 
+    Merge changesets may be transplanted directly by specifying the
+    proper parent changeset by calling :hg: `transplant --parent`.
+
     If no merges or revisions are provided, :hg:`transplant` will
     start an interactive changeset browser.