mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 23:38:50 +03:00
graft: add --continue support
This commit is contained in:
parent
d5e94e6c90
commit
1841aff181
@ -2449,14 +2449,15 @@ def forget(ui, repo, *pats, **opts):
|
||||
|
||||
@command(
|
||||
'graft',
|
||||
[('e', 'edit', False, _('invoke editor on commit messages')),
|
||||
('D', 'currentdate', False,
|
||||
_('record the current date as commit date')),
|
||||
('U', 'currentuser', False,
|
||||
_('record the current user as committer'), _('DATE'))]
|
||||
[('c', 'continue', False, _('resume interrupted graft')),
|
||||
('e', 'edit', False, _('invoke editor on commit messages')),
|
||||
('D', 'currentdate', False,
|
||||
_('record the current date as commit date')),
|
||||
('U', 'currentuser', False,
|
||||
_('record the current user as committer'), _('DATE'))]
|
||||
+ commitopts2 + mergetoolopts,
|
||||
_('[OPTION]... REVISION...'))
|
||||
def graft(ui, repo, rev, *revs, **opts):
|
||||
def graft(ui, repo, *revs, **opts):
|
||||
'''copy changes from other branches onto the current branch
|
||||
|
||||
This command uses Mercurial's merge logic to copy individual
|
||||
@ -2467,11 +2468,17 @@ def graft(ui, repo, rev, *revs, **opts):
|
||||
Changesets that are ancestors of the current revision, that have
|
||||
already been grafted, or that are merges will be skipped.
|
||||
|
||||
If a graft merge results in conflicts, the graft process is
|
||||
aborted so that the current merge can be manually resolved. Once
|
||||
all conflicts are addressed, the graft process can be continued
|
||||
with the -c/--continue option.
|
||||
|
||||
.. note::
|
||||
The -c/--continue option does not reapply earlier options.
|
||||
|
||||
Returns 0 on successful completion.
|
||||
'''
|
||||
|
||||
cmdutil.bailifchanged(repo)
|
||||
|
||||
if not opts.get('user') and opts.get('currentuser'):
|
||||
opts['user'] = ui.username()
|
||||
if not opts.get('date') and opts.get('currentdate'):
|
||||
@ -2481,8 +2488,24 @@ def graft(ui, repo, rev, *revs, **opts):
|
||||
if opts.get('edit'):
|
||||
editor = cmdutil.commitforceeditor
|
||||
|
||||
revs = [rev] + list(revs)
|
||||
revs = scmutil.revrange(repo, revs)
|
||||
cont = False
|
||||
if opts['continue']:
|
||||
cont = True
|
||||
if revs:
|
||||
raise util.Abort(_("can't specify --continue and revisions"))
|
||||
# read in unfinished revisions
|
||||
try:
|
||||
nodes = repo.opener.read('graftstate').splitlines()
|
||||
revs = [repo[node].rev() for node in nodes]
|
||||
except IOError, inst:
|
||||
if inst.errno != errno.ENOENT:
|
||||
raise
|
||||
raise util.Abort(_("no graft state found, can't continue"))
|
||||
else:
|
||||
cmdutil.bailifchanged(repo)
|
||||
if not revs:
|
||||
raise util.Abort(_('no revisions specified'))
|
||||
revs = scmutil.revrange(repo, revs)
|
||||
|
||||
# check for merges
|
||||
for ctx in repo.set('%ld and merge()', revs):
|
||||
@ -2509,26 +2532,36 @@ def graft(ui, repo, rev, *revs, **opts):
|
||||
if not revs:
|
||||
return -1
|
||||
|
||||
for ctx in repo.set("%ld", revs):
|
||||
for pos, ctx in enumerate(repo.set("%ld", revs)):
|
||||
current = repo['.']
|
||||
ui.debug('grafting revision %s', ctx.rev())
|
||||
# perform the graft merge with p1(rev) as 'ancestor'
|
||||
try:
|
||||
# ui.forcemerge is an internal variable, do not document
|
||||
repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
|
||||
stats = mergemod.update(repo, ctx.node(), True, True, False,
|
||||
ctx.p1().node())
|
||||
finally:
|
||||
ui.setconfig('ui', 'forcemerge', '')
|
||||
# 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'))
|
||||
|
||||
# we don't merge the first commit when continuing
|
||||
if not cont:
|
||||
# perform the graft merge with p1(rev) as 'ancestor'
|
||||
try:
|
||||
# ui.forcemerge is an internal variable, do not document
|
||||
repo.ui.setconfig('ui', 'forcemerge', opts.get('tool', ''))
|
||||
stats = mergemod.update(repo, ctx.node(), True, True, False,
|
||||
ctx.p1().node())
|
||||
finally:
|
||||
ui.setconfig('ui', 'forcemerge', '')
|
||||
# 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:
|
||||
# write out state for --continue
|
||||
nodelines = [repo[rev].hex() + "\n" for rev in revs[pos:]]
|
||||
repo.opener.write('graftstate', ''.join(nodelines))
|
||||
raise util.Abort(
|
||||
_("unresolved conflicts, can't continue"),
|
||||
hint=_('use hg resolve and hg graft --continue'))
|
||||
else:
|
||||
cont = False
|
||||
|
||||
# commit
|
||||
extra = {'source': ctx.hex()}
|
||||
user = ctx.user()
|
||||
@ -2540,6 +2573,10 @@ def graft(ui, repo, rev, *revs, **opts):
|
||||
repo.commit(text=ctx.description(), user=user,
|
||||
date=date, extra=extra, editor=editor)
|
||||
|
||||
# remove state when we complete successfully
|
||||
if os.path.exists(repo.join('graftstate')):
|
||||
util.unlinkpath(repo.join('graftstate'))
|
||||
|
||||
return 0
|
||||
|
||||
@command('grep',
|
||||
|
@ -243,7 +243,7 @@ Show all commands + options
|
||||
debugsub: rev
|
||||
debugwalk: include, exclude
|
||||
debugwireargs: three, four, five, ssh, remotecmd, insecure
|
||||
graft: edit, currentdate, currentuser, date, user, tool
|
||||
graft: continue, edit, currentdate, currentuser, date, user, tool
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user