diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py --- a/mercurial/cmdutil.py +++ b/mercurial/cmdutil.py @@ -3430,85 +3430,101 @@ """logic to resume interrupted graft using 'hg continue'""" with repo.wlock(): graftstate = statemod.cmdstate(repo, 'graftstate') - statedata = readgraftstate(repo, graftstate) opts = {} + statedata = {} cont = True - 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'] - revs = [repo[node].rev() for node in nodes] - + basectx = None + revs = continuegraftstate(repo, graftstate, opts) skipped = set() - for rev in repo.revs('%ld and merge()', revs): - ui.warn(_('skipping ungraftable merge revision %d\n') % rev) - skipped.add(rev) - revs = [r for r in revs if r not in skipped] + if basectx is None: + # check for merges + for rev in repo.revs('%ld and merge()', revs): + ui.warn(_('skipping ungraftable merge revision %d\n') % rev) + skipped.add(rev) + revs = [r for r in revs if r not in skipped] if not revs: return -1 - - for pos, ctx in enumerate(repo.set("%ld", revs)): - desc = '%d:%s "%s"' % (ctx.rev(), ctx, + finishgraft(repo, ui, basectx, revs, statedata, cont, opts) + graftstate.delete() + return 0 + +def finishgraft(repo, ui, basectx, revs, statedata, cont, opts): + """logic to execute graft once revs are generated""" + 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) - - 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 - if not cont: - # perform the graft merge with p1(rev) as 'ancestor' - overrides = {('ui', 'forcemerge'): opts.get('tool', '')} - base = ctx.p1() - 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)) - 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( + 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 - if statedata.get('newnodes') is not None: - statedata['newnodes'].append(node) - graftstate.delete() - return 0 + elif statedata.get('newnodes') is not None: + statedata['newnodes'].append(node) + +def continuegraftstate(repo, graftstate, opts): + """updates opts based on the interrupted graftstate once + '--continue' flag is called.""" + 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 [repo[node].rev() for node in nodes] diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -2474,9 +2474,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'): @@ -2522,17 +2519,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'] - revs = [repo[node].rev() for node in nodes] + revs = cmdutil.continuegraftstate(repo, graftstate, opts) else: cmdutil.wrongtooltocontinue(repo, _('graft')) else: @@ -2623,69 +2610,8 @@ 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) # remove state when we complete successfully if not opts.get('dry_run'): graftstate.delete() diff --git a/tests/test-graft.t b/tests/test-graft.t --- a/tests/test-graft.t +++ b/tests/test-graft.t @@ -1,4 +1,4 @@ -#testcases abortcommand abortflag continueflag continuecommand +#testcases commandmode abortflag continueflag $ cat >> $HGRCPATH < [extdiff] @@ -1707,7 +1707,7 @@ (no more unresolved files) continue: hg graft --continue -#if continuecommand +#if commandmode $ hg continue --dry-run graft in progress, will be resumed #endif @@ -2041,7 +2041,7 @@ abort: cannot specify any other flag with '--abort' [255] -#if abortcommand +#if commandmode when in dry-run mode $ hg abort --dry-run graft in progress, will be aborted diff --git a/tests/test-issue1175.t b/tests/test-issue1175.t --- a/tests/test-issue1175.t +++ b/tests/test-issue1175.t @@ -1,3 +1,11 @@ +#testcases continueflag continuecommand +#if continueflag + $ cat >> $HGRCPATH < [alias] + > continue = graft --continue + > EOF +#endif + https://bz.mercurial-scm.org/1175 $ hg init @@ -80,7 +88,7 @@ $ hg resolve --mark b (no more unresolved files) continue: hg graft --continue - $ hg graft --continue + $ hg continue grafting 1:5974126fad84 "b1" warning: can't find ancestor for 'b' copied from 'a'! $ hg log -f b -T 'changeset: {rev}:{node|short}\nsummary: {desc}\n\n'