D6659: graft: split graft code to avoid duplication

taapas1128 (Taapas Agrawal) phabricator at mercurial-scm.org
Thu Jul 18 16:21:20 EDT 2019


taapas1128 created this revision.
Herald added a subscriber: mercurial-devel.
Herald added a reviewer: hg-reviewers.

REVISION SUMMARY
  To avoid duplication of code due to `cmdutil.continuegraft()`; `graft()`
  is split into `cmdutil.finishgraft()` which deals with the execution of graft
  once `revs` are generated and `cmdutil.continuegraftstate()` which updates opts
  from `graftstate` file when graft is continued from an interrupted state.
  
  Further tests for issue1175 are updated to show the behaviour of `hg continue`.

REPOSITORY
  rHG Mercurial

REVISION DETAIL
  https://phab.mercurial-scm.org/D6659

AFFECTED FILES
  mercurial/cmdutil.py
  mercurial/commands.py
  tests/test-issue1175.t

CHANGE DETAILS

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 <<EOF
+  > [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'
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/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]



To: taapas1128, #hg-reviewers
Cc: mercurial-devel


More information about the Mercurial-devel mailing list