[PATCH] transplant: permit merge changesets via --parent
Steven Stallion
sstallion at gmail.com
Sun Apr 8 19:43:53 CDT 2012
# HG changeset patch
# User Steven Stallion <sstallion at gmail.com>
# Date 1333932216 25200
# Node ID 3979508e3822d65024de83a7add1d2adbfa2f3bf
# Parent 329887a7074c8e49e73fa76712d8d45aee0d0fd7
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.
diff -r 329887a7074c -r 3979508e3822 hgext/transplant.py
--- a/hgext/transplant.py Fri Apr 06 15:18:14 2012 -0500
+++ b/hgext/transplant.py Sun Apr 08 17:43:36 2012 -0700
@@ -121,10 +121,21 @@
continue
parents = source.changelog.parents(node)
+ if len(parents) > 1:
+ if not opts.get('parent'):
+ raise util.Abort(
+ _('cannot transplant a merge changeset'))
+ 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 not opts.get('filter'):
# If the changeset parent is the same as the
# wdir's parent, just pull it.
- if parents[0] == p1:
+ if parent == p1:
pulls.append(node)
p1 = node
continue
@@ -144,36 +155,30 @@
if not hasnode(repo, node):
repo.pull(source, heads=[node])
- if parents[1] != revlog.nullid:
- self.ui.note(_('skipping merge changeset %s:%s\n')
- % (rev, short(node)))
- patchfile = None
- else:
- fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
- fp = os.fdopen(fd, 'w')
- gen = patch.diff(source, parents[0], node, opts=diffopts)
- for chunk in gen:
- fp.write(chunk)
- fp.close()
+ fd, patchfile = tempfile.mkstemp(prefix='hg-transplant-')
+ fp = os.fdopen(fd, 'w')
+ gen = patch.diff(source, parent, node, opts=diffopts)
+ for chunk in gen:
+ fp.write(chunk)
+ fp.close()
del revmap[rev]
- if patchfile or domerge:
- try:
- n = self.applyone(repo, node,
- source.changelog.read(node),
- patchfile, merge=domerge,
- log=opts.get('log'),
- filter=opts.get('filter'))
- if n and domerge:
- self.ui.status(_('%s merged at %s\n') % (revstr,
- short(n)))
- elif n:
- self.ui.status(_('%s transplanted to %s\n')
- % (short(node),
- short(n)))
- finally:
- if patchfile:
- os.unlink(patchfile)
+ try:
+ n = self.applyone(repo, node,
+ source.changelog.read(node),
+ patchfile, merge=domerge,
+ log=opts.get('log'),
+ filter=opts.get('filter'))
+ if n and domerge:
+ self.ui.status(_('%s merged at %s\n') % (revstr,
+ short(n)))
+ elif n:
+ self.ui.status(_('%s transplanted to %s\n')
+ % (short(node),
+ short(n)))
+ finally:
+ if patchfile:
+ os.unlink(patchfile)
tr.close()
if pulls:
repo.pull(source, heads=pulls)
@@ -295,19 +300,30 @@
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'))
+
+ 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
+ if not parent:
+ parent = parents[0]
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 +484,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 +528,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.
More information about the Mercurial-devel
mailing list