revert: add an experimental config to use inverted selection

We had a discussion on the list about the interactive ui for revert. This patch
adds a flag to allow people to test the second alternative (referred to as
proposition 2 on the mailing list). It effectively inverts the signs in the
This commit is contained in:
Laurent Charignon 2015-05-29 13:11:52 -07:00
parent 289c8c97de
commit f9d447f8e4
3 changed files with 154 additions and 1 deletions

View File

@ -3139,10 +3139,21 @@ def _performrevert(repo, parents, ctx, actions, interactive=False):
diffopts = patch.difffeatureopts(repo.ui, whitespace=True)
diffopts.nodates = True
diffopts.git = True
diff = patch.diff(repo, None, ctx.node(), m, opts=diffopts)
reversehunks = repo.ui.configbool('experimental',
'revertalternateinteractivemode',
False)
if reversehunks:
diff = patch.diff(repo, ctx.node(), None, m, opts=diffopts)
else:
diff = patch.diff(repo, None, ctx.node(), m, opts=diffopts)
originalchunks = patch.parsepatch(diff)
try:
chunks = recordfilter(repo.ui, originalchunks)
if reversehunks:
chunks = patch.reversehunks(chunks)
except patch.PatchError, err:
raise util.Abort(_('error parsing patch: %s') % err)

View File

@ -1385,6 +1385,77 @@ def parsefilename(str):
return s
return s[:i]
def reversehunks(hunks):
'''reverse the signs in the hunks given as argument
This function operates on hunks coming out of patch.filterpatch, that is
a list of the form: [header1, hunk1, hunk2, header2...]. Example usage:
>>> rawpatch = """diff --git a/folder1/g b/folder1/g
... --- a/folder1/g
... +++ b/folder1/g
... @@ -1,7 +1,7 @@
... +firstline
... c
... 1
... 2
... + 3
... -4
... 5
... d
... +lastline"""
>>> hunks = parsepatch(rawpatch)
>>> hunkscomingfromfilterpatch = []
>>> for h in hunks:
... hunkscomingfromfilterpatch.append(h)
... hunkscomingfromfilterpatch.extend(h.hunks)
>>> reversedhunks = reversehunks(hunkscomingfromfilterpatch)
>>> fp = cStringIO.StringIO()
>>> for c in reversedhunks:
... c.write(fp)
>>> fp.seek(0)
>>> reversedpatch = fp.read()
>>> print reversedpatch
diff --git a/folder1/g b/folder1/g
--- a/folder1/g
+++ b/folder1/g
@@ -1,4 +1,3 @@
-firstline
c
1
2
@@ -1,6 +2,6 @@
c
1
2
- 3
+4
5
d
@@ -5,3 +6,2 @@
5
d
-lastline
'''
import crecord as crecordmod
newhunks = []
for c in hunks:
if isinstance(c, crecordmod.uihunk):
# curses hunks encapsulate the record hunk in _hunk
c = c._hunk
if isinstance(c, recordhunk):
for j, line in enumerate(c.hunk):
if line.startswith("-"):
c.hunk[j] = "+" + c.hunk[j][1:]
elif line.startswith("+"):
c.hunk[j] = "-" + c.hunk[j][1:]
c.added, c.removed = c.removed, c.added
newhunks.append(c)
return newhunks
def parsepatch(originalchunks):
"""patch -> [] of headers -> [] of hunks """
class parser(object):

View File

@ -320,3 +320,74 @@ Check editing files newly added by a revert
4
5
b
Check the experimental config to invert the selection:
$ cat <<EOF >> $HGRCPATH
> [experimental]
> revertalternateinteractivemode=True
> EOF
$ hg up -C .
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ printf 'firstline\nc\n1\n2\n3\n 3\n5\nd\nlastline\n' > folder1/g
$ hg diff --nodates
diff -r 5a858e056dc0 folder1/g
--- a/folder1/g
+++ b/folder1/g
@@ -1,7 +1,9 @@
+firstline
c
1
2
3
-4
+ 3
5
d
+lastline
$ hg revert -i <<EOF
> y
> y
> y
> n
> EOF
reverting folder1/g (glob)
diff --git a/folder1/g b/folder1/g
3 hunks, 3 lines changed
examine changes to 'folder1/g'? [Ynesfdaq?] y
@@ -1,4 +1,5 @@
+firstline
c
1
2
3
record change 1/3 to 'folder1/g'? [Ynesfdaq?] y
@@ -1,7 +2,7 @@
c
1
2
3
-4
+ 3
5
d
record change 2/3 to 'folder1/g'? [Ynesfdaq?] y
@@ -6,2 +7,3 @@
5
d
+lastline
record change 3/3 to 'folder1/g'? [Ynesfdaq?] n
$ hg diff --nodates
diff -r 5a858e056dc0 folder1/g
--- a/folder1/g
+++ b/folder1/g
@@ -5,3 +5,4 @@
4
5
d
+lastline