diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -3425,3 +3425,86 @@ with repo.wlock(): graftstate = statemod.cmdstate(repo, 'graftstate') return abortgraft(ui, repo, graftstate) + +def finishgraft(repo, ui, basectx, revs, statedata, cont, opts, + graftstate=None): + """logic to execute graft once revs are generated""" + if not graftstate: + graftstate = statemod.cmdstate(repo, 'graftstate') + for pos, ctx in enumerate(repo.set("%ld", revs)): + desc = '%d:%s "%s"' % (ctx.rev(), ctx, + ctx.description().split('\n', 1)[0]) + names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) + if names: + desc += ' (%s)' % ' '.join(names) + ui.status(_('grafting %s\n') % desc) + if opts.get('dry_run'): + continue + + source = ctx.extra().get('source') + extra = {} + if source: + extra['source'] = source + extra['intermediate-source'] = ctx.hex() + else: + extra['source'] = ctx.hex() + user = ctx.user() + if opts.get('user'): + user = opts['user'] + statedata['user'] = user + date = ctx.date() + if opts.get('date'): + date = opts['date'] + statedata['date'] = date + message = ctx.description() + if opts.get('log'): + message += '\n(grafted from %s)' % ctx.hex() + statedata['log'] = True + + # we don't merge the first commit when continuing + if not cont: + # perform the graft merge with p1(rev) as 'ancestor' + overrides = {('ui', 'forcemerge'): opts.get('tool', '')} + base = ctx.p1() if basectx is None else basectx + with ui.configoverride(overrides, 'graft'): + stats = mergemod.graft(repo, ctx, base, ['local', 'graft']) + # report any conflicts + if stats.unresolvedcount > 0: + # write out state for --continue + nodes = [repo[rev].hex() for rev in revs[pos:]] + statedata['nodes'] = nodes + stateversion = 1 + graftstate.save(stateversion, statedata) + hint = _("use 'hg resolve' and 'hg graft --continue'") + raise error.Abort( + _("unresolved conflicts, can't continue"), + hint=hint) + else: + cont = False + editor = getcommiteditor(editform='graft', **pycompat.strkwargs(opts)) + # commit if --no-commit is false + if not opts.get('no_commit'): + node = repo.commit(text=message, user=user, date=date, extra=extra, + editor=editor) + if node is None: + ui.warn( + _('note: graft of %d:%s created no changes to commit\n') % + (ctx.rev(), ctx)) + # checking that newnodes exist because old state files won't have it + elif statedata.get('newnodes') is not None: + statedata['newnodes'].append(node) + +def updateopts(repo, graftstate, opts): + """updates opts and nodes from graftstate in case graft + is resumed from an interrupted step""" + statedata = readgraftstate(repo, graftstate) + if statedata.get('date'): + opts['date'] = statedata['date'] + if statedata.get('user'): + opts['user'] = statedata['user'] + if statedata.get('log'): + opts['log'] = True + if statedata.get('no_commit'): + opts['no_commit'] = statedata.get('no_commit') + nodes = statedata['nodes'] + return (nodes, opts) diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2470,9 +2470,6 @@ if not opts.get('date') and opts.get('currentdate'): opts['date'] = "%d %d" % dateutil.makedate() - editor = cmdutil.getcommiteditor(editform='graft', - **pycompat.strkwargs(opts)) - cont = False if opts.get('no_commit'): if opts.get('edit'): @@ -2518,16 +2515,7 @@ raise error.Abort(_("can't specify --continue and revisions")) # read in unfinished revisions if graftstate.exists(): - statedata = cmdutil.readgraftstate(repo, graftstate) - if statedata.get('date'): - opts['date'] = statedata['date'] - if statedata.get('user'): - opts['user'] = statedata['user'] - if statedata.get('log'): - opts['log'] = True - if statedata.get('no_commit'): - opts['no_commit'] = statedata.get('no_commit') - nodes = statedata['nodes'] + nodes, opts = cmdutil.updateopts(repo, graftstate, opts) revs = [repo[node].rev() for node in nodes] else: cmdutil.wrongtooltocontinue(repo, _('graft')) @@ -2619,69 +2607,9 @@ if opts.get('no_commit'): statedata['no_commit'] = True - for pos, ctx in enumerate(repo.set("%ld", revs)): - desc = '%d:%s "%s"' % (ctx.rev(), ctx, - ctx.description().split('\n', 1)[0]) - names = repo.nodetags(ctx.node()) + repo.nodebookmarks(ctx.node()) - if names: - desc += ' (%s)' % ' '.join(names) - ui.status(_('grafting %s\n') % desc) - if opts.get('dry_run'): - continue - - source = ctx.extra().get('source') - extra = {} - if source: - extra['source'] = source - extra['intermediate-source'] = ctx.hex() - else: - extra['source'] = ctx.hex() - user = ctx.user() - if opts.get('user'): - user = opts['user'] - statedata['user'] = user - date = ctx.date() - if opts.get('date'): - date = opts['date'] - statedata['date'] = date - message = ctx.description() - if opts.get('log'): - message += '\n(grafted from %s)' % ctx.hex() - statedata['log'] = True - - # we don't merge the first commit when continuing - if not cont: - # perform the graft merge with p1(rev) as 'ancestor' - overrides = {('ui', 'forcemerge'): opts.get('tool', '')} - base = ctx.p1() if basectx is None else basectx - with ui.configoverride(overrides, 'graft'): - stats = mergemod.graft(repo, ctx, base, ['local', 'graft']) - # report any conflicts - if stats.unresolvedcount > 0: - # write out state for --continue - nodes = [repo[rev].hex() for rev in revs[pos:]] - statedata['nodes'] = nodes - stateversion = 1 - graftstate.save(stateversion, statedata) - hint = _("use 'hg resolve' and 'hg graft --continue'") - raise error.Abort( - _("unresolved conflicts, can't continue"), - hint=hint) - else: - cont = False - - # commit if --no-commit is false - if not opts.get('no_commit'): - node = repo.commit(text=message, user=user, date=date, extra=extra, - editor=editor) - if node is None: - ui.warn( - _('note: graft of %d:%s created no changes to commit\n') % - (ctx.rev(), ctx)) - # checking that newnodes exist because old state files won't have it - elif statedata.get('newnodes') is not None: - statedata['newnodes'].append(node) - + + cmdutil.finishgraft(repo, ui, basectx, revs, statedata, cont, opts, + graftstate) # remove state when we complete successfully if not opts.get('dry_run'): graftstate.delete()