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.
--- 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.
--- a/tests/test-transplant.t Thu Apr 12 20:22:18 2012 -0500
+++ b/tests/test-transplant.t Tue Apr 10 23:24:12 2012 -0700
@@ -424,3 +424,57 @@
a\r (esc)
b\r (esc)
$ cd ..
+
+test transplant with merge changeset is skipped
+
+ $ hg init merge1a
+ $ cd merge1a
+ $ echo a > a
+ $ hg ci -Am a
+ adding a
+ $ hg branch b
+ marked working directory as branch b
+ (branches are permanent and global, did you want a bookmark?)
+ $ hg ci -m branchb
+ $ echo b > b
+ $ hg ci -Am b
+ adding b
+ $ hg update default
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg merge b
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ hg ci -m mergeb
+ $ cd ..
+
+ $ hg init merge1b
+ $ cd merge1b
+ $ hg transplant -s ../merge1a tip
+
+test transplant with merge changeset accepts --parent
+
+ $ hg init merge2a
+ $ cd merge2a
+ $ echo a > a
+ $ hg ci -Am a
+ adding a
+ $ hg branch b
+ marked working directory as branch b
+ (branches are permanent and global, did you want a bookmark?)
+ $ hg ci -m branchb
+ $ echo b > b
+ $ hg ci -Am b
+ adding b
+ $ hg update default
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ hg merge b
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ hg ci -m mergeb
+ $ cd ..
+
+ $ hg init merge2b
+ $ cd merge2b
+ $ hg transplant -s ../merge2a --parent 0 tip
+ applying be9f9b39483f
+ be9f9b39483f transplanted to 9959e51f94d1