Mercurial > hg
changeset 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 | 7416ce2c7887 |
children | c292bbbcf10c |
files | hgext/transplant.py tests/test-transplant.t |
diffstat | 2 files changed, 87 insertions(+), 6 deletions(-) [+] |
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.
--- 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