@@ -428,4 +428,52 @@ class uihunk(patchnode):
return x.getvalue()
+ def reversehunk(self):
+ """return a recordhunk which is the reverse of the hunk
+
+ Assuming the displayed patch is diff(A, B) result. The returned hunk is
+ intended to be applied to B, instead of A.
+
+ For example, when A is "0\n1\n2\n6\n" and B is "0\n3\n4\n5\n6\n", and
+ the user made the following selection:
+
+ 0
+ [x] -1 [x]: selected
+ [ ] -2 [ ]: not selected
+ [x] +3
+ [ ] +4
+ [x] +5
+ 6
+
+ This function returns a hunk like:
+
+ 0
+ -3
+ -4
+ -5
+ +1
+ +4
+ 6
+
+ Note "4" was first deleted then added. That's because "4" exists in B
+ side and "-4" must exist between "-3" and "-5" to make the patch
+ applicable to B.
+ """
+ dels = []
+ adds = []
+ for line in self.changedlines:
+ text = line.linetext
+ if line.applied:
+ if text[0] == '+':
+ dels.append(text[1:])
+ elif text[0] == '-':
+ adds.append(text[1:])
+ elif text[0] == '+':
+ dels.append(text[1:])
+ adds.append(text[1:])
+ hunk = ['-%s' % l for l in dels] + ['+%s' % l for l in adds]
+ h = self._hunk
+ return patchmod.recordhunk(h.header, h.toline, h.fromline, h.proc,
+ h.before, hunk, h.after)
+
def __getattr__(self, name):
return getattr(self._hunk, name)
@@ -960,4 +960,16 @@ class recordhunk(object):
return add, rem
+ def reversehunk(self):
+ """return another recordhunk which is the reverse of the hunk
+
+ If this hunk is diff(A, B), the returned hunk is diff(B, A). To do
+ that, swap fromline/toline and +/- signs while keep other things
+ unchanged.
+ """
+ m = {'+': '-', '-': '+'}
+ hunk = ['%s%s' % (m[l[0]], l[1:]) for l in self.hunk]
+ return recordhunk(self.header, self.toline, self.fromline, self.proc,
+ self.before, hunk, self.after)
+
def write(self, fp):
delta = len(self.before) + len(self.after)
@@ -1494,5 +1506,5 @@ def reversehunks(hunks):
1
2
- @@ -1,6 +2,6 @@
+ @@ -2,6 +1,6 @@
c
1
@@ -1502,5 +1514,5 @@ def reversehunks(hunks):
5
d
- @@ -5,3 +6,2 @@
+ @@ -6,3 +5,2 @@
5
d
@@ -1509,17 +1521,8 @@ def reversehunks(hunks):
'''
- from . 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
+ if util.safehasattr(c, 'reversehunk'):
+ c = c.reversehunk()
newhunks.append(c)
return newhunks