D3754: graft: introduce --abort flag to abort interrupted graft
pulkit (Pulkit Goyal)
phabricator at mercurial-scm.org
Mon Jun 25 06:05:30 EDT 2018
pulkit updated this revision to Diff 9275.
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D3754?vs=9100&id=9275
REVISION DETAIL
https://phab.mercurial-scm.org/D3754
AFFECTED FILES
mercurial/commands.py
tests/test-completion.t
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
@@ -1670,3 +1670,218 @@
|
o 0:9092f1db7931 added a
+ $ cd ..
+
+Testing the --abort flag for `hg graft` which aborts and rollback to state
+before the graft
+
+ $ hg init abortgraft
+ $ cd abortgraft
+ $ for ch in a b c d; do echo $ch > $ch; hg add $ch; hg ci -Aqm "added "$ch; done;
+
+ $ hg up '.^^'
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+
+ $ echo x > x
+ $ hg ci -Aqm "added x"
+ $ hg up '.^'
+ 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+ $ echo foo > c
+ $ hg ci -Aqm "added foo to c"
+
+ $ hg log -GT "{rev}:{node|short} {desc}"
+ @ 5:36b793615f78 added foo to c
+ |
+ | o 4:863a25e1a9ea added x
+ |/
+ | o 3:9150fe93bec6 added d
+ | |
+ | o 2:155349b645be added c
+ |/
+ o 1:5f6d8a4bf34a added b
+ |
+ o 0:9092f1db7931 added a
+
+ $ hg up 9150fe93bec6
+ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+
+ $ hg graft --abort
+ abort: no interrupted graft to abort
+ [255]
+
+when stripping is required
+ $ hg graft -r 4 -r 5
+ grafting 4:863a25e1a9ea "added x"
+ grafting 5:36b793615f78 "added foo to c" (tip)
+ merging c
+ warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+ abort: unresolved conflicts, can't continue
+ (use 'hg resolve' and 'hg graft --continue')
+ [255]
+
+ $ hg graft --continue --abort
+ abort: cannot use '--continue' and '--abort' together
+ [255]
+
+ $ hg graft --abort --stop
+ abort: cannot use '--abort' and '--stop' together
+ [255]
+
+ $ hg graft --abort --currentuser
+ abort: cannot specify any other flag with '--abort'
+ [255]
+
+ $ hg graft --abort --edit
+ abort: cannot specify any other flag with '--abort'
+ [255]
+
+ $ hg graft --abort
+ graft aborted
+ working directory is now at 9150fe93bec6
+ $ hg log -GT "{rev}:{node|short} {desc}"
+ o 5:36b793615f78 added foo to c
+ |
+ | o 4:863a25e1a9ea added x
+ |/
+ | @ 3:9150fe93bec6 added d
+ | |
+ | o 2:155349b645be added c
+ |/
+ o 1:5f6d8a4bf34a added b
+ |
+ o 0:9092f1db7931 added a
+
+when stripping is not required
+ $ hg graft -r 5
+ grafting 5:36b793615f78 "added foo to c" (tip)
+ merging c
+ warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+ abort: unresolved conflicts, can't continue
+ (use 'hg resolve' and 'hg graft --continue')
+ [255]
+
+ $ hg graft --abort
+ graft aborted
+ working directory is now at 9150fe93bec6
+ $ hg log -GT "{rev}:{node|short} {desc}"
+ o 5:36b793615f78 added foo to c
+ |
+ | o 4:863a25e1a9ea added x
+ |/
+ | @ 3:9150fe93bec6 added d
+ | |
+ | o 2:155349b645be added c
+ |/
+ o 1:5f6d8a4bf34a added b
+ |
+ o 0:9092f1db7931 added a
+
+when some of the changesets became public
+
+ $ hg graft -r 4 -r 5
+ grafting 4:863a25e1a9ea "added x"
+ grafting 5:36b793615f78 "added foo to c" (tip)
+ merging c
+ warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+ abort: unresolved conflicts, can't continue
+ (use 'hg resolve' and 'hg graft --continue')
+ [255]
+
+ $ hg log -GT "{rev}:{node|short} {desc}"
+ @ 6:6ec71c037d94 added x
+ |
+ | o 5:36b793615f78 added foo to c
+ | |
+ | | o 4:863a25e1a9ea added x
+ | |/
+ o | 3:9150fe93bec6 added d
+ | |
+ o | 2:155349b645be added c
+ |/
+ o 1:5f6d8a4bf34a added b
+ |
+ o 0:9092f1db7931 added a
+
+ $ hg phase -r 6 --public
+
+ $ hg graft --abort
+ cannot clean up public changesets 6ec71c037d94
+ graft aborted
+ working directory is now at 6ec71c037d94
+
+when we created new changesets on top of existing one
+
+ $ hg up '.^^'
+ 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
+ $ echo y > y
+ $ hg ci -Aqm "added y"
+ $ echo z > z
+ $ hg ci -Aqm "added z"
+
+ $ hg up 3
+ 1 files updated, 0 files merged, 3 files removed, 0 files unresolved
+ $ hg log -GT "{rev}:{node|short} {desc}"
+ o 8:637f9e9bbfd4 added z
+ |
+ o 7:123221671fd4 added y
+ |
+ | o 6:6ec71c037d94 added x
+ | |
+ | | o 5:36b793615f78 added foo to c
+ | | |
+ | | | o 4:863a25e1a9ea added x
+ | | |/
+ | @ | 3:9150fe93bec6 added d
+ |/ /
+ o / 2:155349b645be added c
+ |/
+ o 1:5f6d8a4bf34a added b
+ |
+ o 0:9092f1db7931 added a
+
+ $ hg graft -r 8 -r 7 -r 5
+ grafting 8:637f9e9bbfd4 "added z" (tip)
+ grafting 7:123221671fd4 "added y"
+ grafting 5:36b793615f78 "added foo to c"
+ merging c
+ warning: conflicts while merging c! (edit, then use 'hg resolve --mark')
+ abort: unresolved conflicts, can't continue
+ (use 'hg resolve' and 'hg graft --continue')
+ [255]
+
+ $ cd ..
+ $ hg init pullrepo
+ $ cd pullrepo
+ $ cat >> .hg/hgrc <<EOF
+ > [phases]
+ > publish=False
+ > EOF
+ $ hg pull ../abortgraft --config phases.publish=False
+ pulling from ../abortgraft
+ requesting all changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 11 changesets with 9 changes to 8 files (+4 heads)
+ new changesets 9092f1db7931:6b98ff0062dd
+ (run 'hg heads' to see heads, 'hg merge' to merge)
+ $ hg up 9
+ 5 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ echo w > w
+ $ hg ci -Aqm "added w" --config phases.publish=False
+
+ $ cd ../abortgraft
+ $ hg pull ../pullrepo
+ pulling from ../pullrepo
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 1 changesets with 1 changes to 1 files (+1 heads)
+ new changesets 311dfc6cf3bf
+ (run 'hg heads .' to see heads, 'hg merge' to merge)
+
+ $ hg graft --abort
+ new changesets detected on destination branch, can't strip
+ graft aborted
+ working directory is now at 6b98ff0062dd
diff --git a/tests/test-completion.t b/tests/test-completion.t
--- a/tests/test-completion.t
+++ b/tests/test-completion.t
@@ -312,7 +312,7 @@
debugwireargs: three, four, five, ssh, remotecmd, insecure
debugwireproto: localssh, peer, noreadstderr, nologhandshake, ssh, remotecmd, insecure
files: rev, print0, include, exclude, template, subrepos
- graft: rev, continue, stop, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
+ graft: rev, continue, stop, abort, edit, log, force, currentdate, currentuser, date, user, tool, dry-run
grep: print0, all, diff, text, follow, ignore-case, files-with-matches, line-number, rev, allfiles, user, date, template, include, exclude
heads: rev, topo, active, closed, style, template
help: extension, command, keyword, system
diff --git a/mercurial/commands.py b/mercurial/commands.py
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -49,6 +49,7 @@
pycompat,
rcutil,
registrar,
+ repair,
revsetlang,
rewriteutil,
scmutil,
@@ -2107,6 +2108,7 @@
[('r', 'rev', [], _('revisions to graft'), _('REV')),
('c', 'continue', False, _('resume interrupted graft')),
('', 'stop', False, _('stop interrupted graft')),
+ ('', 'abort', False, _('abort interrupted graft')),
('e', 'edit', False, _('invoke editor on commit messages')),
('', 'log', None, _('append graft info to log message')),
('f', 'force', False, _('force graft')),
@@ -2204,11 +2206,24 @@
if opts.get('continue'):
raise error.Abort(_("cannot use '--continue' and "
"'--stop' together"))
+ if opts.get('abort'):
+ raise error.Abort(_("cannot use '--abort' and '--stop' together"))
+
if any((opts.get('edit'), opts.get('log'), opts.get('user'),
opts.get('date'), opts.get('currentdate'),
opts.get('currentuser'), opts.get('rev'))):
raise error.Abort(_("cannot specify any other flag with '--stop'"))
return _stopgraft(ui, repo, graftstate)
+ elif opts.get('abort'):
+ if opts.get('continue'):
+ raise error.Abort(_("cannot use '--continue' and "
+ "'--abort' together"))
+ if any((opts.get('edit'), opts.get('log'), opts.get('user'),
+ opts.get('date'), opts.get('currentdate'),
+ opts.get('currentuser'), opts.get('rev'))):
+ raise error.Abort(_("cannot specify any other flag with '--abort'"))
+
+ return _abortgraft(ui, repo, graftstate)
elif opts.get('continue'):
cont = True
if revs:
@@ -2375,6 +2390,62 @@
return 0
+def _abortgraft(ui, repo, graftstate):
+ """abort the interrupted graft and rollbacks to the state before interrupted
+ graft"""
+ if not graftstate.exists():
+ raise error.Abort(_("no interrupted graft to abort"))
+ statedata = _readgraftstate(repo, graftstate)
+ newnodes = statedata.get('newnodes')
+ if newnodes is None:
+ # and old graft state which does not have all the data required to abort
+ # the graft
+ raise error.Abort(_("cannot abort using an old graftstate"))
+
+ # changeset from which graft operation was started
+ startctx = None
+ if len(newnodes) > 0:
+ startctx = repo[newnodes[0]].p1()
+ else:
+ startctx = repo['.']
+ # whether to strip or not
+ cleanup = False
+ if newnodes:
+ newnodes = [repo[r].rev() for r in newnodes]
+ cleanup = True
+ # checking that none of the newnodes turned public or is public
+ immutable = [c for c in newnodes if not repo[c].mutable()]
+ if immutable:
+ repo.ui.warn(_("cannot clean up public changesets %s\n")
+ % ','.join(bytes(repo[r]) for r in immutable),
+ hint=_("see 'hg help phases' for details"))
+ cleanup = False
+
+ # checking that no new nodes are created on top of grafted revs
+ desc = set(repo.changelog.descendants(newnodes))
+ if desc - set(newnodes):
+ repo.ui.warn(_("new changesets detected on destination "
+ "branch, can't strip\n"))
+ cleanup = False
+
+ if cleanup:
+ with repo.wlock(), repo.lock():
+ hg.updaterepo(repo, startctx.node(), True)
+ # stripping the new nodes created
+ strippoints = [c.node() for c in repo.set("roots(%ld)",
+ newnodes)]
+ repair.strip(repo.ui, repo, strippoints, False)
+
+ if not cleanup:
+ # we don't update to the startnode if we can't strip
+ startctx = repo['.']
+ hg.updaterepo(repo, startctx.node(), True)
+
+ ui.write(_("graft aborted\nworking directory is now at %s\n")
+ % startctx.hex()[:12])
+ graftstate.delete()
+ return 0
+
def _readgraftstate(repo, graftstate):
"""read the graft state file and return a dict of the data stored in it"""
try:
To: pulkit, #hg-reviewers
Cc: yuja, mercurial-devel
More information about the Mercurial-devel
mailing list