graft: add initial implementation

This commit is contained in:
Matt Mackall 2011-10-12 18:45:36 -05:00
parent 6d4a8aa3a9
commit 06ac7c8606
4 changed files with 76 additions and 0 deletions

View File

@ -2447,6 +2447,75 @@ def forget(ui, repo, *pats, **opts):
repo[None].forget(forget)
return errs
@command('graft',
[],
_('[OPTION]... REVISION...'))
def graft(ui, repo, rev, *revs, **opts):
'''copy changes from other branches onto the current branch
This command uses Mercurial's merge logic to copy individual
changes from other branches without merging branches in the
history graph. This is sometimes known as 'backporting' or
'cherry-picking'.
Changesets that are ancestors of the current revision, that have
already been grafted, or that are merges will be skipped.
Returns 0 on successful completion.
'''
cmdutil.bailifchanged(repo)
revs = [rev] + list(revs)
revs = scmutil.revrange(repo, revs)
# check for merges
for ctx in repo.set('%ld and merge()', revs):
ui.warn(_('skipping ungraftable merge revision %s\n') % ctx.rev())
revs.remove(ctx.rev())
if not revs:
return -1
# check for ancestors of dest branch
for ctx in repo.set('::. and %ld', revs):
ui.warn(_('skipping ancestor revision %s\n') % ctx.rev())
revs.remove(ctx.rev())
if not revs:
return -1
# check ancestors for earlier grafts
ui.debug('scanning for existing transplants')
for ctx in repo.set("::. - ::%ld", revs):
n = ctx.extra().get('source')
if n and n in repo:
r = repo[n].rev()
ui.warn(_('skipping already grafted revision %s\n') % r)
revs.remove(r)
if not revs:
return -1
for ctx in repo.set("%ld", revs):
current = repo['.']
ui.debug('grafting revision %s', ctx.rev())
# perform the graft merge with p1(rev) as 'ancestor'
stats = mergemod.update(repo, ctx.node(), True, True, False,
ctx.p1().node())
# drop the second merge parent
repo.dirstate.setparents(current.node(), nullid)
repo.dirstate.write()
# fix up dirstate for copies and renames
cmdutil.duplicatecopies(repo, ctx.rev(), current.node(), nullid)
# report any conflicts
if stats and stats[3] > 0:
raise util.Abort(_("unresolved conflicts, can't continue"),
hint=_('use hg resolve and hg graft --continue'))
# commit
extra = {'source': ctx.hex()}
repo.commit(text=ctx.description(), user=ctx.user(),
date=ctx.date(), extra=extra)
return 0
@command('grep',
[('0', 'print0', None, _('end fields with NUL')),
('', 'all', None, _('print all revisions that match')),

View File

@ -17,6 +17,7 @@ Show all commands except debug commands
diff
export
forget
graft
grep
heads
help
@ -242,6 +243,7 @@ Show all commands + options
debugsub: rev
debugwalk: include, exclude
debugwireargs: three, four, five, ssh, remotecmd, insecure
graft:
grep: print0, all, text, follow, ignore-case, files-with-matches, line-number, rev, user, date, include, exclude
heads: rev, topo, active, closed, style, template
help: extension, command

View File

@ -296,6 +296,7 @@ Testing -h/--help:
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
graft copy changes from other branches onto the current branch
grep search for a pattern in specified files and revisions
heads show current repository heads or show branch heads
help show help for a given topic or a help overview
@ -377,6 +378,7 @@ Testing -h/--help:
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
graft copy changes from other branches onto the current branch
grep search for a pattern in specified files and revisions
heads show current repository heads or show branch heads
help show help for a given topic or a help overview

View File

@ -66,6 +66,7 @@ Short help:
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
graft copy changes from other branches onto the current branch
grep search for a pattern in specified files and revisions
heads show current repository heads or show branch heads
help show help for a given topic or a help overview
@ -141,6 +142,7 @@ Short help:
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
graft copy changes from other branches onto the current branch
grep search for a pattern in specified files and revisions
heads show current repository heads or show branch heads
help show help for a given topic or a help overview
@ -626,6 +628,7 @@ Test that default list of commands omits extension commands
diff diff repository (or selected files)
export dump the header and diffs for one or more changesets
forget forget the specified files on the next commit
graft copy changes from other branches onto the current branch
grep search for a pattern in specified files and revisions
heads show current repository heads or show branch heads
help show help for a given topic or a help overview