--- a/hgext3rd/evolve/cmdrewrite.py Wed Jan 24 15:20:29 2018 +0100
+++ b/hgext3rd/evolve/cmdrewrite.py Thu Jan 11 20:03:20 2018 +0530
@@ -22,6 +22,7 @@
error,
hg,
lock as lockmod,
+ merge,
node,
obsolete,
patch,
@@ -34,6 +35,7 @@
from . import (
compat,
+ evolvestate,
exthelper,
rewriteutil,
utility,
@@ -1143,3 +1145,93 @@
tr.close()
finally:
lockmod.release(tr, lock, wlock)
+
+@eh.command(
+ 'grab',
+ [('r', 'rev', '', 'revision to grab'),
+ ('', 'continue', False, 'continue interrupted grab'),
+ ('', 'abort', False, 'abort interrupted grab'),
+ ],
+ _('[-r] rev'))
+def grab(ui, repo, *revs, **opts):
+ """grabs a commit, move it on the top of working directory parent and
+ updates to it."""
+
+ cont = opts.get('continue')
+ abort = opts.get('abort')
+
+ if cont and abort:
+ raise error.Abort(_("cannot specify both --continue and --abort"))
+
+ revs = list(revs)
+ if opts.get('rev'):
+ revs.append(opts['rev'])
+
+ with repo.wlock(), repo.lock(), repo.transaction('grab'):
+ state = evolvestate.evolvestate(repo, path='grabstate')
+
+ if not cont and not abort:
+ cmdutil.bailifchanged(repo)
+ revs = scmutil.revrange(repo, revs)
+ if len(revs) > 1:
+ raise error.Abort(_("specify just one revision"))
+ elif not revs:
+ raise error.Abort(_("empty revision set"))
+
+ origctx = repo[revs.first()]
+ pctx = repo['.']
+
+ if origctx in pctx.ancestors():
+ raise error.Abort(_("cannot grab an ancestor revision"))
+
+ rewriteutil.precheck(repo, [origctx.rev()], 'grab')
+
+ ui.status(_('grabbing %d:%s "%s"\n') %
+ (origctx.rev(), origctx,
+ origctx.description().split("\n", 1)[0]))
+ stats = merge.graft(repo, origctx, origctx.p1(), ['local',
+ 'destination'])
+ if stats[3]:
+ state.addopts({'orignode': origctx.node(),
+ 'oldpctx': pctx.node()})
+ state.save()
+ raise error.InterventionRequired(_("unresolved merge conflicts"
+ " (see hg help resolve)"))
+
+ elif abort:
+ if not state:
+ raise error.Abort(_("no interrupted grab state exists"))
+ state.load()
+ pctxnode = state['oldpctx']
+ ui.status(_("aborting grab, updating to %s\n") %
+ node.hex(pctxnode)[:12])
+ hg.updaterepo(repo, pctxnode, True)
+ return 0
+
+ else:
+ if revs:
+ raise error.Abort(_("cannot specify both --continue and "
+ "revision"))
+ if not state:
+ raise error.Abort(_("no interrupted grab state exists"))
+
+ state.load()
+ orignode = state['orignode']
+ origctx = repo[orignode]
+
+ newnode = repo.commit(text=origctx.description(), user=origctx.user(),
+ date=origctx.date(), extra=origctx.extra())
+
+ if state:
+ state.delete()
+ if newnode:
+ obsolete.createmarkers(repo, [(origctx, (repo[newnode],))])
+ else:
+ obsolete.createmarkers(repo, [(origctx, (pctx,))])
+
+ if newnode is None:
+ ui.warn(_("note: grab of %d:%s created no changes to commit\n") %
+ (origctx.rev(), origctx))
+ return 0
+
+ return 0