Commit 92799032 authored by Laurent Charignon's avatar Laurent Charignon

revert: add flag to make revert interactive

parent 8d9e9063b040
......@@ -3018,8 +3018,8 @@ def revert(ui, repo, ctx, parents, *pats, **opts):
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 @@ def _revertprefetch(repo, ctx, *files):
"""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 @@ def _performrevert(repo, parents, ctx, actions):
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)
......
......@@ -5375,6 +5375,7 @@ def resolve(ui, repo, *pats, **opts):
('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):
......
......@@ -279,7 +279,7 @@ Show all commands + options
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
......
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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment