mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
graft: add initial implementation
This commit is contained in:
parent
6d4a8aa3a9
commit
06ac7c8606
@ -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')),
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user