D6655: continue: added support for graft

taapas1128 (Taapas Agrawal) phabricator at mercurial-scm.org
Thu Jul 18 17:46:45 UTC 2019


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

REVISION SUMMARY
  This adds support of graft to hg continue plan.
  
  The patch creates a seperate function `cmdutil.continuegraft`
  so that continue logic for graft can be called independently.
  This logic is registered to the statedetection API as `continuefunc`.
  
  Results are shown as tests.

REPOSITORY
  rHG Mercurial

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

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

CHANGE DETAILS

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
+#testcases abortcommand abortflag continueflag continuecommand
 
   $ cat >> $HGRCPATH <<EOF
   > [extdiff]
@@ -13,6 +13,13 @@
   > EOF
 #endif
 
+#if continueflag
+  $ cat >> $HGRCPATH <<EOF
+  > [alias]
+  > continue = graft --continue
+  > EOF
+#endif
+
 Create a repo with some stuff in it:
 
   $ hg init a
@@ -92,9 +99,11 @@
 
   $ hg -q up -cr tip
   $ hg rm -q e
-  $ hg graft --continue
-  abort: no graft in progress
-  [255]
+  $ hg continue
+  abort: no graft in progress (continueflag !)
+  abort: no operation in progress (no-continueflag !)
+  [255]
+
   $ hg revert -r . -q e
 
 Need to specify a rev:
@@ -1697,7 +1706,13 @@
   $ hg resolve -m
   (no more unresolved files)
   continue: hg graft --continue
-  $ hg graft --continue
+
+#if continuecommand
+  $ hg continue --dry-run
+  graft in progress, will be resumed
+#endif
+
+  $ hg continue
   grafting 1:80e6d2c47cfe "added b"
   grafting 2:8be98ac1a569 "added c"
 
@@ -1754,7 +1769,7 @@
   (no more unresolved files)
   continue: hg graft --continue
 
-  $ hg graft --continue
+  $ hg continue
   grafting 1:80e6d2c47cfe "added b"
   grafting 2:8be98ac1a569 "added c"
 
@@ -1803,7 +1818,7 @@
   $ hg resolve -m
   (no more unresolved files)
   continue: hg graft --continue
-  $ hg graft --continue
+  $ hg continue
   grafting 1:80e6d2c47cfe "added b"
   grafting 2:8be98ac1a569 "added c"
 
@@ -1843,7 +1858,7 @@
   (no more unresolved files)
   continue: hg graft --continue
 
-  $ hg graft --continue
+  $ hg continue
   grafting 1:80e6d2c47cfe "added b"
   grafting 2:8be98ac1a569 "added c"
 
@@ -1997,7 +2012,7 @@
 
   $ hg abort
   abort: no interrupted graft to abort (abortflag !)
-  abort: no operation in progress (abortcommand !)
+  abort: no operation in progress (no-abortflag !)
   [255]
 
 when stripping is required
@@ -2273,7 +2288,7 @@
   (no more unresolved files)
   continue: hg graft --continue
 
-  $ hg graft --continue
+  $ hg continue
   grafting 3:09e253b87e17 "A in file a"
   $ hg log -GT "{rev}:{node|short} {desc}\n"
   @  4:2aa9ad1006ff B in file a
@@ -2350,7 +2365,7 @@
   $ hg resolve --mark
   (no more unresolved files)
   continue: hg graft --continue
-  $ hg graft --continue
+  $ hg continue
   grafting 3:09e253b87e17 "A in file a"
   $ hg diff
   diff -r 2aa9ad1006ff a
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -2706,6 +2706,7 @@
 statemod.addunfinished(
     'graft', fname='graftstate', clearable=True, stopflag=True,
     continueflag=True, abortfunc=cmdutil.hgabortgraft,
+    continuefunc=cmdutil.continuegraft,
     cmdhint=_("use 'hg graft --continue' or 'hg graft --stop' to stop")
 )
 
diff --git a/mercurial/cmdutil.py b/mercurial/cmdutil.py
--- a/mercurial/cmdutil.py
+++ b/mercurial/cmdutil.py
@@ -3425,3 +3425,90 @@
     with repo.wlock():
         graftstate = statemod.cmdstate(repo, 'graftstate')
         return abortgraft(ui, repo, graftstate)
+
+def continuegraft(ui, repo):
+    """logic to resume interrupted graft using 'hg continue'"""
+    with repo.wlock():
+        graftstate = statemod.cmdstate(repo, 'graftstate')
+        statedata = readgraftstate(repo, graftstate)
+        opts = {}
+        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]
+
+        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 not revs:
+            return -1
+
+        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(
+                    _('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



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


More information about the Mercurial-devel mailing list