--- a/mercurial/cmdutil.py Mon Mar 16 15:37:00 2015 -0700
+++ b/mercurial/cmdutil.py Mon Mar 16 16:33:59 2015 -0700
@@ -3018,8 +3018,8 @@
if not opts.get('dry_run'):
needdata = ('revert', 'add', 'undelete')
_revertprefetch(repo, ctx, *[actions[name][0] for name in needdata])
-
- _performrevert(repo, parents, ctx, actions)
+ interactive = opts.get('interactive', False)
+ _performrevert(repo, parents, ctx, actions, interactive)
# get the list of subrepos that must be reverted
subrepomatch = scmutil.match(ctx, pats, opts)
@@ -3036,7 +3036,7 @@
"""Let extension changing the storage layer prefetch content"""
pass
-def _performrevert(repo, parents, ctx, actions):
+def _performrevert(repo, parents, ctx, actions, interactive=False):
"""function that actually perform all the actions computed for revert
This is an independent function to let extension to plug in and react to
@@ -3070,10 +3070,40 @@
normal = repo.dirstate.normallookup
else:
normal = repo.dirstate.normal
- for f in actions['revert'][0]:
- checkout(f)
- if normal:
- normal(f)
+
+ if interactive:
+ # Prompt the user for changes to revert
+ torevert = [repo.wjoin(f) for f in actions['revert'][0]]
+ m = scmutil.match(ctx, torevert, {})
+ diff = patch.diff(repo, None, ctx.node(), m)
+ originalchunks = patch.parsepatch(diff)
+ try:
+ chunks = recordfilter(repo.ui, originalchunks)
+ except patch.PatchError, err:
+ raise util.Abort(_('error parsing patch: %s') % err)
+
+ # Apply changes
+ fp = cStringIO.StringIO()
+ for c in chunks:
+ c.write(fp)
+ dopatch = fp.tell()
+ fp.seek(0)
+ if dopatch:
+ try:
+ patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
+ except patch.PatchError, err:
+ raise util.Abort(str(err))
+ del fp
+
+ for f in actions['revert'][0]:
+ if normal:
+ normal(f)
+
+ else:
+ for f in actions['revert'][0]:
+ checkout(f)
+ if normal:
+ normal(f)
for f in actions['add'][0]:
checkout(f)
--- a/mercurial/commands.py Mon Mar 16 15:37:00 2015 -0700
+++ b/mercurial/commands.py Mon Mar 16 16:33:59 2015 -0700
@@ -5375,6 +5375,7 @@
('d', 'date', '', _('tipmost revision matching date'), _('DATE')),
('r', 'rev', '', _('revert to the specified revision'), _('REV')),
('C', 'no-backup', None, _('do not save backup copies of files')),
+ ('i', 'interactive', None, _('interactively select the changes')),
] + walkopts + dryrunopts,
_('[OPTION]... [-r REV] [NAME]...'))
def revert(ui, repo, *pats, **opts):
--- a/tests/test-completion.t Mon Mar 16 15:37:00 2015 -0700
+++ b/tests/test-completion.t Mon Mar 16 16:33:59 2015 -0700
@@ -279,7 +279,7 @@
recover:
rename: after, force, include, exclude, dry-run
resolve: all, list, mark, unmark, no-status, tool, include, exclude, template
- revert: all, date, rev, no-backup, include, exclude, dry-run
+ revert: all, date, rev, no-backup, interactive, include, exclude, dry-run
rollback: dry-run, force
root:
tag: force, local, rev, remove, edit, message, date, user
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-revert-interactive.t Mon Mar 16 16:33:59 2015 -0700
@@ -0,0 +1,203 @@
+Revert interactive tests
+1 add and commit file f
+2 add commit file folder1/g
+3 add and commit file folder2/h
+4 add and commit file folder1/i
+5 commit change to file f
+6 commit changes to files folder1/g folder2/h
+7 commit changes to files folder1/g folder2/h
+8 revert interactive to commit id 2 (line 3 above), check that folder1/i is removed and
+9 make workdir match 7
+10 run the same test than 8 from within folder1 and check same expectations
+
+ $ cat <<EOF >> $HGRCPATH
+ > [ui]
+ > interactive = true
+ > [extensions]
+ > record =
+ > EOF
+
+
+ $ mkdir -p a/{folder1,folder2}
+ $ cd a
+ $ hg init
+ $ seq 1 5 > f ; hg add f ; hg commit -m "adding f"
+ $ seq 1 5 > folder1/g ; hg add folder1/g ; hg commit -m "adding folder1/g"
+ $ seq 1 5 > folder2/h ; hg add folder2/h ; hg commit -m "adding folder2/h"
+ $ seq 1 5 > folder1/i ; hg add folder1/i ; hg commit -m "adding folder1/i"
+ $ echo "a" > f ; seq 1 5 >> f ; echo "b" >> f ; hg commit -m "modifying f"
+ $ echo "c" > folder1/g ; seq 1 5 >> folder1/g ; echo "d" >> folder1/g ; hg commit -m "modifying folder1/g"
+ $ echo "e" > folder2/h ; seq 1 5 >> folder2/h ; echo "f" >> folder2/h ; hg commit -m "modifying folder2/h"
+ $ hg tip
+ changeset: 6:59dd6e4ab63a
+ tag: tip
+ user: test
+ date: Thu Jan 01 00:00:00 1970 +0000
+ summary: modifying folder2/h
+
+ $ hg revert -i -r 2 --all -- << EOF
+ > y
+ > y
+ > y
+ > y
+ > y
+ > n
+ > n
+ > EOF
+ reverting f
+ reverting folder1/g (glob)
+ removing folder1/i (glob)
+ reverting folder2/h (glob)
+ diff -r 89ac3d72e4a4 f
+ 2 hunks, 2 lines changed
+ examine changes to 'f'? [Ynesfdaq?] y
+
+ @@ -1,6 +1,5 @@
+ -a
+ 1
+ 2
+ 3
+ 4
+ 5
+ record change 1/6 to 'f'? [Ynesfdaq?] y
+
+ @@ -2,6 +1,5 @@
+ 1
+ 2
+ 3
+ 4
+ 5
+ -b
+ record change 2/6 to 'f'? [Ynesfdaq?] y
+
+ diff -r 89ac3d72e4a4 folder1/g
+ 2 hunks, 2 lines changed
+ examine changes to 'folder1/g'? [Ynesfdaq?] y
+
+ @@ -1,6 +1,5 @@
+ -c
+ 1
+ 2
+ 3
+ 4
+ 5
+ record change 3/6 to 'folder1/g'? [Ynesfdaq?] y
+
+ @@ -2,6 +1,5 @@
+ 1
+ 2
+ 3
+ 4
+ 5
+ -d
+ record change 4/6 to 'folder1/g'? [Ynesfdaq?] n
+
+ diff -r 89ac3d72e4a4 folder2/h
+ 2 hunks, 2 lines changed
+ examine changes to 'folder2/h'? [Ynesfdaq?] n
+
+ $ cat f
+ 1
+ 2
+ 3
+ 4
+ 5
+ $ cat folder1/g
+ 1
+ 2
+ 3
+ 4
+ 5
+ d
+ $ cat folder2/h
+ e
+ 1
+ 2
+ 3
+ 4
+ 5
+ f
+ $ hg update -C 6
+ 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg revert -i -r 2 --all -- << EOF
+ > y
+ > y
+ > y
+ > y
+ > y
+ > n
+ > n
+ > EOF
+ reverting f
+ reverting folder1/g (glob)
+ removing folder1/i (glob)
+ reverting folder2/h (glob)
+ diff -r 89ac3d72e4a4 f
+ 2 hunks, 2 lines changed
+ examine changes to 'f'? [Ynesfdaq?] y
+
+ @@ -1,6 +1,5 @@
+ -a
+ 1
+ 2
+ 3
+ 4
+ 5
+ record change 1/6 to 'f'? [Ynesfdaq?] y
+
+ @@ -2,6 +1,5 @@
+ 1
+ 2
+ 3
+ 4
+ 5
+ -b
+ record change 2/6 to 'f'? [Ynesfdaq?] y
+
+ diff -r 89ac3d72e4a4 folder1/g
+ 2 hunks, 2 lines changed
+ examine changes to 'folder1/g'? [Ynesfdaq?] y
+
+ @@ -1,6 +1,5 @@
+ -c
+ 1
+ 2
+ 3
+ 4
+ 5
+ record change 3/6 to 'folder1/g'? [Ynesfdaq?] y
+
+ @@ -2,6 +1,5 @@
+ 1
+ 2
+ 3
+ 4
+ 5
+ -d
+ record change 4/6 to 'folder1/g'? [Ynesfdaq?] n
+
+ diff -r 89ac3d72e4a4 folder2/h
+ 2 hunks, 2 lines changed
+ examine changes to 'folder2/h'? [Ynesfdaq?] n
+
+ $ cat f
+ 1
+ 2
+ 3
+ 4
+ 5
+ $ cat folder1/g
+ 1
+ 2
+ 3
+ 4
+ 5
+ d
+ $ cat folder2/h
+ e
+ 1
+ 2
+ 3
+ 4
+ 5
+ f