##// END OF EJS Templates
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)...
Patrick Mezard -
r9827:4fe9ca51 default
parent child Browse files
Show More
@@ -1,269 +1,273
1 # mdiff.py - diff and patch routines for mercurial
1 # mdiff.py - diff and patch routines for mercurial
2 #
2 #
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2, incorporated herein by reference.
6 # GNU General Public License version 2, incorporated herein by reference.
7
7
8 from i18n import _
8 from i18n import _
9 import bdiff, mpatch, util
9 import bdiff, mpatch, util
10 import re, struct
10 import re, struct
11
11
12 def splitnewlines(text):
12 def splitnewlines(text):
13 '''like str.splitlines, but only split on newlines.'''
13 '''like str.splitlines, but only split on newlines.'''
14 lines = [l + '\n' for l in text.split('\n')]
14 lines = [l + '\n' for l in text.split('\n')]
15 if lines:
15 if lines:
16 if lines[-1] == '\n':
16 if lines[-1] == '\n':
17 lines.pop()
17 lines.pop()
18 else:
18 else:
19 lines[-1] = lines[-1][:-1]
19 lines[-1] = lines[-1][:-1]
20 return lines
20 return lines
21
21
22 class diffopts(object):
22 class diffopts(object):
23 '''context is the number of context lines
23 '''context is the number of context lines
24 text treats all files as text
24 text treats all files as text
25 showfunc enables diff -p output
25 showfunc enables diff -p output
26 git enables the git extended patch format
26 git enables the git extended patch format
27 nodates removes dates from diff headers
27 nodates removes dates from diff headers
28 ignorews ignores all whitespace changes in the diff
28 ignorews ignores all whitespace changes in the diff
29 ignorewsamount ignores changes in the amount of whitespace
29 ignorewsamount ignores changes in the amount of whitespace
30 ignoreblanklines ignores changes whose lines are all blank'''
30 ignoreblanklines ignores changes whose lines are all blank'''
31
31
32 defaults = {
32 defaults = {
33 'context': 3,
33 'context': 3,
34 'text': False,
34 'text': False,
35 'showfunc': False,
35 'showfunc': False,
36 'git': False,
36 'git': False,
37 'nodates': False,
37 'nodates': False,
38 'ignorews': False,
38 'ignorews': False,
39 'ignorewsamount': False,
39 'ignorewsamount': False,
40 'ignoreblanklines': False,
40 'ignoreblanklines': False,
41 }
41 }
42
42
43 __slots__ = defaults.keys()
43 __slots__ = defaults.keys()
44
44
45 def __init__(self, **opts):
45 def __init__(self, **opts):
46 for k in self.__slots__:
46 for k in self.__slots__:
47 v = opts.get(k)
47 v = opts.get(k)
48 if v is None:
48 if v is None:
49 v = self.defaults[k]
49 v = self.defaults[k]
50 setattr(self, k, v)
50 setattr(self, k, v)
51
51
52 try:
52 try:
53 self.context = int(self.context)
53 self.context = int(self.context)
54 except ValueError:
54 except ValueError:
55 raise util.Abort(_('diff context lines count must be '
55 raise util.Abort(_('diff context lines count must be '
56 'an integer, not %r') % self.context)
56 'an integer, not %r') % self.context)
57
57
58 defaultopts = diffopts()
58 defaultopts = diffopts()
59
59
60 def wsclean(opts, text):
60 def wsclean(opts, text, blank=True):
61 if opts.ignorews:
61 if opts.ignorews:
62 text = re.sub('[ \t]+', '', text)
62 text = re.sub('[ \t]+', '', text)
63 elif opts.ignorewsamount:
63 elif opts.ignorewsamount:
64 text = re.sub('[ \t]+', ' ', text)
64 text = re.sub('[ \t]+', ' ', text)
65 text = re.sub('[ \t]+\n', '\n', text)
65 text = re.sub('[ \t]+\n', '\n', text)
66 if opts.ignoreblanklines:
66 if blank and opts.ignoreblanklines:
67 text = re.sub('\n+', '', text)
67 text = re.sub('\n+', '', text)
68 return text
68 return text
69
69
70 def diffline(revs, a, b, opts):
70 def diffline(revs, a, b, opts):
71 parts = ['diff']
71 parts = ['diff']
72 if opts.git:
72 if opts.git:
73 parts.append('--git')
73 parts.append('--git')
74 if revs and not opts.git:
74 if revs and not opts.git:
75 parts.append(' '.join(["-r %s" % rev for rev in revs]))
75 parts.append(' '.join(["-r %s" % rev for rev in revs]))
76 if opts.git:
76 if opts.git:
77 parts.append('a/%s' % a)
77 parts.append('a/%s' % a)
78 parts.append('b/%s' % b)
78 parts.append('b/%s' % b)
79 else:
79 else:
80 parts.append(a)
80 parts.append(a)
81 return ' '.join(parts) + '\n'
81 return ' '.join(parts) + '\n'
82
82
83 def unidiff(a, ad, b, bd, fn1, fn2, r=None, opts=defaultopts):
83 def unidiff(a, ad, b, bd, fn1, fn2, r=None, opts=defaultopts):
84 def datetag(date, addtab=True):
84 def datetag(date, addtab=True):
85 if not opts.git and not opts.nodates:
85 if not opts.git and not opts.nodates:
86 return '\t%s\n' % date
86 return '\t%s\n' % date
87 if addtab and ' ' in fn1:
87 if addtab and ' ' in fn1:
88 return '\t\n'
88 return '\t\n'
89 return '\n'
89 return '\n'
90
90
91 if not a and not b: return ""
91 if not a and not b: return ""
92 epoch = util.datestr((0, 0))
92 epoch = util.datestr((0, 0))
93
93
94 if not opts.text and (util.binary(a) or util.binary(b)):
94 if not opts.text and (util.binary(a) or util.binary(b)):
95 if a and b and len(a) == len(b) and a == b:
95 if a and b and len(a) == len(b) and a == b:
96 return ""
96 return ""
97 l = ['Binary file %s has changed\n' % fn1]
97 l = ['Binary file %s has changed\n' % fn1]
98 elif not a:
98 elif not a:
99 b = splitnewlines(b)
99 b = splitnewlines(b)
100 if a is None:
100 if a is None:
101 l1 = '--- /dev/null%s' % datetag(epoch, False)
101 l1 = '--- /dev/null%s' % datetag(epoch, False)
102 else:
102 else:
103 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad))
103 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad))
104 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd))
104 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd))
105 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
105 l3 = "@@ -0,0 +1,%d @@\n" % len(b)
106 l = [l1, l2, l3] + ["+" + e for e in b]
106 l = [l1, l2, l3] + ["+" + e for e in b]
107 elif not b:
107 elif not b:
108 a = splitnewlines(a)
108 a = splitnewlines(a)
109 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad))
109 l1 = "--- %s%s" % ("a/" + fn1, datetag(ad))
110 if b is None:
110 if b is None:
111 l2 = '+++ /dev/null%s' % datetag(epoch, False)
111 l2 = '+++ /dev/null%s' % datetag(epoch, False)
112 else:
112 else:
113 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd))
113 l2 = "+++ %s%s" % ("b/" + fn2, datetag(bd))
114 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
114 l3 = "@@ -1,%d +0,0 @@\n" % len(a)
115 l = [l1, l2, l3] + ["-" + e for e in a]
115 l = [l1, l2, l3] + ["-" + e for e in a]
116 else:
116 else:
117 al = splitnewlines(a)
117 al = splitnewlines(a)
118 bl = splitnewlines(b)
118 bl = splitnewlines(b)
119 l = list(bunidiff(a, b, al, bl, "a/" + fn1, "b/" + fn2, opts=opts))
119 l = list(bunidiff(a, b, al, bl, "a/" + fn1, "b/" + fn2, opts=opts))
120 if not l: return ""
120 if not l: return ""
121 # difflib uses a space, rather than a tab
121 # difflib uses a space, rather than a tab
122 l[0] = "%s%s" % (l[0][:-2], datetag(ad))
122 l[0] = "%s%s" % (l[0][:-2], datetag(ad))
123 l[1] = "%s%s" % (l[1][:-2], datetag(bd))
123 l[1] = "%s%s" % (l[1][:-2], datetag(bd))
124
124
125 for ln in xrange(len(l)):
125 for ln in xrange(len(l)):
126 if l[ln][-1] != '\n':
126 if l[ln][-1] != '\n':
127 l[ln] += "\n\ No newline at end of file\n"
127 l[ln] += "\n\ No newline at end of file\n"
128
128
129 if r:
129 if r:
130 l.insert(0, diffline(r, fn1, fn2, opts))
130 l.insert(0, diffline(r, fn1, fn2, opts))
131
131
132 return "".join(l)
132 return "".join(l)
133
133
134 # somewhat self contained replacement for difflib.unified_diff
134 # somewhat self contained replacement for difflib.unified_diff
135 # t1 and t2 are the text to be diffed
135 # t1 and t2 are the text to be diffed
136 # l1 and l2 are the text broken up into lines
136 # l1 and l2 are the text broken up into lines
137 # header1 and header2 are the filenames for the diff output
137 # header1 and header2 are the filenames for the diff output
138 def bunidiff(t1, t2, l1, l2, header1, header2, opts=defaultopts):
138 def bunidiff(t1, t2, l1, l2, header1, header2, opts=defaultopts):
139 def contextend(l, len):
139 def contextend(l, len):
140 ret = l + opts.context
140 ret = l + opts.context
141 if ret > len:
141 if ret > len:
142 ret = len
142 ret = len
143 return ret
143 return ret
144
144
145 def contextstart(l):
145 def contextstart(l):
146 ret = l - opts.context
146 ret = l - opts.context
147 if ret < 0:
147 if ret < 0:
148 return 0
148 return 0
149 return ret
149 return ret
150
150
151 def yieldhunk(hunk, header):
151 def yieldhunk(hunk, header):
152 if header:
152 if header:
153 for x in header:
153 for x in header:
154 yield x
154 yield x
155 (astart, a2, bstart, b2, delta) = hunk
155 (astart, a2, bstart, b2, delta) = hunk
156 aend = contextend(a2, len(l1))
156 aend = contextend(a2, len(l1))
157 alen = aend - astart
157 alen = aend - astart
158 blen = b2 - bstart + aend - a2
158 blen = b2 - bstart + aend - a2
159
159
160 func = ""
160 func = ""
161 if opts.showfunc:
161 if opts.showfunc:
162 # walk backwards from the start of the context
162 # walk backwards from the start of the context
163 # to find a line starting with an alphanumeric char.
163 # to find a line starting with an alphanumeric char.
164 for x in xrange(astart - 1, -1, -1):
164 for x in xrange(astart - 1, -1, -1):
165 t = l1[x].rstrip()
165 t = l1[x].rstrip()
166 if funcre.match(t):
166 if funcre.match(t):
167 func = ' ' + t[:40]
167 func = ' ' + t[:40]
168 break
168 break
169
169
170 yield "@@ -%d,%d +%d,%d @@%s\n" % (astart + 1, alen,
170 yield "@@ -%d,%d +%d,%d @@%s\n" % (astart + 1, alen,
171 bstart + 1, blen, func)
171 bstart + 1, blen, func)
172 for x in delta:
172 for x in delta:
173 yield x
173 yield x
174 for x in xrange(a2, aend):
174 for x in xrange(a2, aend):
175 yield ' ' + l1[x]
175 yield ' ' + l1[x]
176
176
177 header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ]
177 header = [ "--- %s\t\n" % header1, "+++ %s\t\n" % header2 ]
178
178
179 if opts.showfunc:
179 if opts.showfunc:
180 funcre = re.compile('\w')
180 funcre = re.compile('\w')
181
181
182 # bdiff.blocks gives us the matching sequences in the files. The loop
182 # bdiff.blocks gives us the matching sequences in the files. The loop
183 # below finds the spaces between those matching sequences and translates
183 # below finds the spaces between those matching sequences and translates
184 # them into diff output.
184 # them into diff output.
185 #
185 #
186 if opts.ignorews or opts.ignorewsamount:
187 t1 = wsclean(opts, t1, False)
188 t2 = wsclean(opts, t2, False)
189
186 diff = bdiff.blocks(t1, t2)
190 diff = bdiff.blocks(t1, t2)
187 hunk = None
191 hunk = None
188 for i, s1 in enumerate(diff):
192 for i, s1 in enumerate(diff):
189 # The first match is special.
193 # The first match is special.
190 # we've either found a match starting at line 0 or a match later
194 # we've either found a match starting at line 0 or a match later
191 # in the file. If it starts later, old and new below will both be
195 # in the file. If it starts later, old and new below will both be
192 # empty and we'll continue to the next match.
196 # empty and we'll continue to the next match.
193 if i > 0:
197 if i > 0:
194 s = diff[i-1]
198 s = diff[i-1]
195 else:
199 else:
196 s = [0, 0, 0, 0]
200 s = [0, 0, 0, 0]
197 delta = []
201 delta = []
198 a1 = s[1]
202 a1 = s[1]
199 a2 = s1[0]
203 a2 = s1[0]
200 b1 = s[3]
204 b1 = s[3]
201 b2 = s1[2]
205 b2 = s1[2]
202
206
203 old = l1[a1:a2]
207 old = l1[a1:a2]
204 new = l2[b1:b2]
208 new = l2[b1:b2]
205
209
206 # bdiff sometimes gives huge matches past eof, this check eats them,
210 # bdiff sometimes gives huge matches past eof, this check eats them,
207 # and deals with the special first match case described above
211 # and deals with the special first match case described above
208 if not old and not new:
212 if not old and not new:
209 continue
213 continue
210
214
211 if opts.ignorews or opts.ignorewsamount or opts.ignoreblanklines:
215 if opts.ignoreblanklines:
212 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)):
216 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)):
213 continue
217 continue
214
218
215 astart = contextstart(a1)
219 astart = contextstart(a1)
216 bstart = contextstart(b1)
220 bstart = contextstart(b1)
217 prev = None
221 prev = None
218 if hunk:
222 if hunk:
219 # join with the previous hunk if it falls inside the context
223 # join with the previous hunk if it falls inside the context
220 if astart < hunk[1] + opts.context + 1:
224 if astart < hunk[1] + opts.context + 1:
221 prev = hunk
225 prev = hunk
222 astart = hunk[1]
226 astart = hunk[1]
223 bstart = hunk[3]
227 bstart = hunk[3]
224 else:
228 else:
225 for x in yieldhunk(hunk, header):
229 for x in yieldhunk(hunk, header):
226 yield x
230 yield x
227 # we only want to yield the header if the files differ, and
231 # we only want to yield the header if the files differ, and
228 # we only want to yield it once.
232 # we only want to yield it once.
229 header = None
233 header = None
230 if prev:
234 if prev:
231 # we've joined the previous hunk, record the new ending points.
235 # we've joined the previous hunk, record the new ending points.
232 hunk[1] = a2
236 hunk[1] = a2
233 hunk[3] = b2
237 hunk[3] = b2
234 delta = hunk[4]
238 delta = hunk[4]
235 else:
239 else:
236 # create a new hunk
240 # create a new hunk
237 hunk = [ astart, a2, bstart, b2, delta ]
241 hunk = [ astart, a2, bstart, b2, delta ]
238
242
239 delta[len(delta):] = [ ' ' + x for x in l1[astart:a1] ]
243 delta[len(delta):] = [ ' ' + x for x in l1[astart:a1] ]
240 delta[len(delta):] = [ '-' + x for x in old ]
244 delta[len(delta):] = [ '-' + x for x in old ]
241 delta[len(delta):] = [ '+' + x for x in new ]
245 delta[len(delta):] = [ '+' + x for x in new ]
242
246
243 if hunk:
247 if hunk:
244 for x in yieldhunk(hunk, header):
248 for x in yieldhunk(hunk, header):
245 yield x
249 yield x
246
250
247 def patchtext(bin):
251 def patchtext(bin):
248 pos = 0
252 pos = 0
249 t = []
253 t = []
250 while pos < len(bin):
254 while pos < len(bin):
251 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
255 p1, p2, l = struct.unpack(">lll", bin[pos:pos + 12])
252 pos += 12
256 pos += 12
253 t.append(bin[pos:pos + l])
257 t.append(bin[pos:pos + l])
254 pos += l
258 pos += l
255 return "".join(t)
259 return "".join(t)
256
260
257 def patch(a, bin):
261 def patch(a, bin):
258 return mpatch.patches(a, [bin])
262 return mpatch.patches(a, [bin])
259
263
260 # similar to difflib.SequenceMatcher.get_matching_blocks
264 # similar to difflib.SequenceMatcher.get_matching_blocks
261 def get_matching_blocks(a, b):
265 def get_matching_blocks(a, b):
262 return [(d[0], d[2], d[1] - d[0]) for d in bdiff.blocks(a, b)]
266 return [(d[0], d[2], d[1] - d[0]) for d in bdiff.blocks(a, b)]
263
267
264 def trivialdiffheader(length):
268 def trivialdiffheader(length):
265 return struct.pack(">lll", 0, 0, length)
269 return struct.pack(">lll", 0, 0, length)
266
270
267 patches = mpatch.patches
271 patches = mpatch.patches
268 patchedsize = mpatch.patchedsize
272 patchedsize = mpatch.patchedsize
269 textdiff = bdiff.bdiff
273 textdiff = bdiff.bdiff
@@ -1,289 +1,281
1 adding foo
1 adding foo
2 >>> two diffs showing three added lines <<<
2 >>> two diffs showing three added lines <<<
3 hg diff
3 hg diff
4 diff -r 540c40a65b78 foo
4 diff -r 540c40a65b78 foo
5 --- a/foo
5 --- a/foo
6 +++ b/foo
6 +++ b/foo
7 @@ -1,2 +1,5 @@
7 @@ -1,2 +1,5 @@
8 +
8 +
9 hello world
9 hello world
10 +
10 +
11 goodbye world
11 goodbye world
12 +
12 +
13 hg diff -b
13 hg diff -b
14 diff -r 540c40a65b78 foo
14 diff -r 540c40a65b78 foo
15 --- a/foo
15 --- a/foo
16 +++ b/foo
16 +++ b/foo
17 @@ -1,2 +1,5 @@
17 @@ -1,2 +1,5 @@
18 +
18 +
19 hello world
19 hello world
20 +
20 +
21 goodbye world
21 goodbye world
22 +
22 +
23 >>> no diffs <<<
23 >>> no diffs <<<
24 hg diff -B
24 hg diff -B
25 hg diff -Bb
25 hg diff -Bb
26 >>> four diffs showing added space first on the first line <<<
26 >>> four diffs showing added space first on the first line <<<
27 hg diff
27 hg diff
28 diff -r 540c40a65b78 foo
28 diff -r 540c40a65b78 foo
29 --- a/foo
29 --- a/foo
30 +++ b/foo
30 +++ b/foo
31 @@ -1,2 +1,2 @@
31 @@ -1,2 +1,2 @@
32 -hello world
32 -hello world
33 + hello world
33 + hello world
34 goodbye world
34 goodbye world
35 hg diff -b
35 hg diff -b
36 diff -r 540c40a65b78 foo
36 diff -r 540c40a65b78 foo
37 --- a/foo
37 --- a/foo
38 +++ b/foo
38 +++ b/foo
39 @@ -1,2 +1,2 @@
39 @@ -1,2 +1,2 @@
40 -hello world
40 -hello world
41 + hello world
41 + hello world
42 goodbye world
42 goodbye world
43 hg diff -B
43 hg diff -B
44 diff -r 540c40a65b78 foo
44 diff -r 540c40a65b78 foo
45 --- a/foo
45 --- a/foo
46 +++ b/foo
46 +++ b/foo
47 @@ -1,2 +1,2 @@
47 @@ -1,2 +1,2 @@
48 -hello world
48 -hello world
49 + hello world
49 + hello world
50 goodbye world
50 goodbye world
51 hg diff -Bb
51 hg diff -Bb
52 diff -r 540c40a65b78 foo
52 diff -r 540c40a65b78 foo
53 --- a/foo
53 --- a/foo
54 +++ b/foo
54 +++ b/foo
55 @@ -1,2 +1,2 @@
55 @@ -1,2 +1,2 @@
56 -hello world
56 -hello world
57 + hello world
57 + hello world
58 goodbye world
58 goodbye world
59 >>> two diffs showing space appended to the first line <<<
59 >>> two diffs showing space appended to the first line <<<
60 hg diff
60 hg diff
61 diff -r 540c40a65b78 foo
61 diff -r 540c40a65b78 foo
62 --- a/foo
62 --- a/foo
63 +++ b/foo
63 +++ b/foo
64 @@ -1,2 +1,2 @@
64 @@ -1,2 +1,2 @@
65 -hello world
65 -hello world
66 +hello world
66 +hello world
67 goodbye world
67 goodbye world
68 hg diff -B
68 hg diff -B
69 diff -r 540c40a65b78 foo
69 diff -r 540c40a65b78 foo
70 --- a/foo
70 --- a/foo
71 +++ b/foo
71 +++ b/foo
72 @@ -1,2 +1,2 @@
72 @@ -1,2 +1,2 @@
73 -hello world
73 -hello world
74 +hello world
74 +hello world
75 goodbye world
75 goodbye world
76 >>> no diffs <<<
76 >>> no diffs <<<
77 hg diff -b
77 hg diff -b
78 hg diff -Bb
78 hg diff -Bb
79 >>> four diffs showing space inserted into "goodbye" <<<
79 >>> four diffs showing space inserted into "goodbye" <<<
80 hg diff
80 hg diff
81 diff -r 540c40a65b78 foo
81 diff -r 540c40a65b78 foo
82 --- a/foo
82 --- a/foo
83 +++ b/foo
83 +++ b/foo
84 @@ -1,2 +1,2 @@
84 @@ -1,2 +1,2 @@
85 hello world
85 hello world
86 -goodbye world
86 -goodbye world
87 +good bye world
87 +good bye world
88 hg diff -B
88 hg diff -B
89 diff -r 540c40a65b78 foo
89 diff -r 540c40a65b78 foo
90 --- a/foo
90 --- a/foo
91 +++ b/foo
91 +++ b/foo
92 @@ -1,2 +1,2 @@
92 @@ -1,2 +1,2 @@
93 hello world
93 hello world
94 -goodbye world
94 -goodbye world
95 +good bye world
95 +good bye world
96 hg diff -b
96 hg diff -b
97 diff -r 540c40a65b78 foo
97 diff -r 540c40a65b78 foo
98 --- a/foo
98 --- a/foo
99 +++ b/foo
99 +++ b/foo
100 @@ -1,2 +1,2 @@
100 @@ -1,2 +1,2 @@
101 hello world
101 hello world
102 -goodbye world
102 -goodbye world
103 +good bye world
103 +good bye world
104 hg diff -Bb
104 hg diff -Bb
105 diff -r 540c40a65b78 foo
105 diff -r 540c40a65b78 foo
106 --- a/foo
106 --- a/foo
107 +++ b/foo
107 +++ b/foo
108 @@ -1,2 +1,2 @@
108 @@ -1,2 +1,2 @@
109 hello world
109 hello world
110 -goodbye world
110 -goodbye world
111 +good bye world
111 +good bye world
112 >>> two diffs showing changed whitespace amount in the last line <<<
112 >>> two diffs showing changed whitespace amount in the last line <<<
113 hg diff
113 hg diff
114 diff -r 540c40a65b78 foo
114 diff -r 540c40a65b78 foo
115 --- a/foo
115 --- a/foo
116 +++ b/foo
116 +++ b/foo
117 @@ -1,2 +1,2 @@
117 @@ -1,2 +1,2 @@
118 hello world
118 hello world
119 -goodbye world
119 -goodbye world
120 +goodbye world
120 +goodbye world
121 hg diff -B
121 hg diff -B
122 diff -r 540c40a65b78 foo
122 diff -r 540c40a65b78 foo
123 --- a/foo
123 --- a/foo
124 +++ b/foo
124 +++ b/foo
125 @@ -1,2 +1,2 @@
125 @@ -1,2 +1,2 @@
126 hello world
126 hello world
127 -goodbye world
127 -goodbye world
128 +goodbye world
128 +goodbye world
129 >>> no diffs <<<
129 >>> no diffs <<<
130 hg diff -b
130 hg diff -b
131 hg diff -Bb
131 hg diff -Bb
132 >>> four diffs showing added blank line w/horizontal space <<<
132 >>> four diffs showing added blank line w/horizontal space <<<
133 hg diff
133 hg diff
134 diff -r 540c40a65b78 foo
134 diff -r 540c40a65b78 foo
135 --- a/foo
135 --- a/foo
136 +++ b/foo
136 +++ b/foo
137 @@ -1,2 +1,3 @@
137 @@ -1,2 +1,3 @@
138 hello world
138 hello world
139 +
139 +
140 goodbye world
140 goodbye world
141 hg diff -B
141 hg diff -B
142 diff -r 540c40a65b78 foo
142 diff -r 540c40a65b78 foo
143 --- a/foo
143 --- a/foo
144 +++ b/foo
144 +++ b/foo
145 @@ -1,2 +1,3 @@
145 @@ -1,2 +1,3 @@
146 hello world
146 hello world
147 +
147 +
148 goodbye world
148 goodbye world
149 hg diff -b
149 hg diff -b
150 diff -r 540c40a65b78 foo
150 diff -r 540c40a65b78 foo
151 --- a/foo
151 --- a/foo
152 +++ b/foo
152 +++ b/foo
153 @@ -1,2 +1,3 @@
153 @@ -1,2 +1,3 @@
154 hello world
154 hello world
155 +
155 +
156 goodbye world
156 goodbye world
157 hg diff -Bb
157 hg diff -Bb
158 >>> three diffs showing added blank line w/other space <<<
158 >>> three diffs showing added blank line w/other space <<<
159 hg diff
159 hg diff
160 diff -r 540c40a65b78 foo
160 diff -r 540c40a65b78 foo
161 --- a/foo
161 --- a/foo
162 +++ b/foo
162 +++ b/foo
163 @@ -1,2 +1,3 @@
163 @@ -1,2 +1,3 @@
164 -hello world
164 -hello world
165 -goodbye world
165 -goodbye world
166 +hello world
166 +hello world
167 +
167 +
168 +goodbye world
168 +goodbye world
169 hg diff -B
169 hg diff -B
170 diff -r 540c40a65b78 foo
170 diff -r 540c40a65b78 foo
171 --- a/foo
171 --- a/foo
172 +++ b/foo
172 +++ b/foo
173 @@ -1,2 +1,3 @@
173 @@ -1,2 +1,3 @@
174 -hello world
174 -hello world
175 -goodbye world
175 -goodbye world
176 +hello world
176 +hello world
177 +
177 +
178 +goodbye world
178 +goodbye world
179 hg diff -b
179 hg diff -b
180 diff -r 540c40a65b78 foo
180 diff -r 540c40a65b78 foo
181 --- a/foo
181 --- a/foo
182 +++ b/foo
182 +++ b/foo
183 @@ -1,2 +1,3 @@
183 @@ -1,2 +1,3 @@
184 -hello world
184 hello world
185 -goodbye world
186 +hello world
187 +
185 +
188 +goodbye world
186 goodbye world
189 hg diff -Bb
187 hg diff -Bb
190 >>> four diffs showing changed whitespace <<<
188 >>> four diffs showing changed whitespace <<<
191 hg diff
189 hg diff
192 diff -r 540c40a65b78 foo
190 diff -r 540c40a65b78 foo
193 --- a/foo
191 --- a/foo
194 +++ b/foo
192 +++ b/foo
195 @@ -1,2 +1,2 @@
193 @@ -1,2 +1,2 @@
196 -hello world
194 -hello world
197 -goodbye world
195 -goodbye world
198 +helloworld
196 +helloworld
199 +goodbye world
197 +goodbye world
200 hg diff -B
198 hg diff -B
201 diff -r 540c40a65b78 foo
199 diff -r 540c40a65b78 foo
202 --- a/foo
200 --- a/foo
203 +++ b/foo
201 +++ b/foo
204 @@ -1,2 +1,2 @@
202 @@ -1,2 +1,2 @@
205 -hello world
203 -hello world
206 -goodbye world
204 -goodbye world
207 +helloworld
205 +helloworld
208 +goodbye world
206 +goodbye world
209 hg diff -b
207 hg diff -b
210 diff -r 540c40a65b78 foo
208 diff -r 540c40a65b78 foo
211 --- a/foo
209 --- a/foo
212 +++ b/foo
210 +++ b/foo
213 @@ -1,2 +1,2 @@
211 @@ -1,2 +1,2 @@
214 -hello world
212 -hello world
215 -goodbye world
216 +helloworld
213 +helloworld
217 +goodbye world
214 goodbye world
218 hg diff -Bb
215 hg diff -Bb
219 diff -r 540c40a65b78 foo
216 diff -r 540c40a65b78 foo
220 --- a/foo
217 --- a/foo
221 +++ b/foo
218 +++ b/foo
222 @@ -1,2 +1,2 @@
219 @@ -1,2 +1,2 @@
223 -hello world
220 -hello world
224 -goodbye world
225 +helloworld
221 +helloworld
226 +goodbye world
222 goodbye world
227 hg diff -w
223 hg diff -w
228 >>> five diffs showing changed whitespace <<<
224 >>> five diffs showing changed whitespace <<<
229 hg diff
225 hg diff
230 diff -r 540c40a65b78 foo
226 diff -r 540c40a65b78 foo
231 --- a/foo
227 --- a/foo
232 +++ b/foo
228 +++ b/foo
233 @@ -1,2 +1,5 @@
229 @@ -1,2 +1,5 @@
234 -hello world
230 -hello world
235 -goodbye world
231 -goodbye world
236 +helloworld
232 +helloworld
237 +
233 +
238 +
234 +
239 +
235 +
240 +goodbye world
236 +goodbye world
241 hg diff -B
237 hg diff -B
242 diff -r 540c40a65b78 foo
238 diff -r 540c40a65b78 foo
243 --- a/foo
239 --- a/foo
244 +++ b/foo
240 +++ b/foo
245 @@ -1,2 +1,5 @@
241 @@ -1,2 +1,5 @@
246 -hello world
242 -hello world
247 -goodbye world
243 -goodbye world
248 +helloworld
244 +helloworld
249 +
245 +
250 +
246 +
251 +
247 +
252 +goodbye world
248 +goodbye world
253 hg diff -b
249 hg diff -b
254 diff -r 540c40a65b78 foo
250 diff -r 540c40a65b78 foo
255 --- a/foo
251 --- a/foo
256 +++ b/foo
252 +++ b/foo
257 @@ -1,2 +1,5 @@
253 @@ -1,2 +1,5 @@
258 -hello world
254 -hello world
259 -goodbye world
260 +helloworld
255 +helloworld
261 +
256 +
262 +
257 +
263 +
258 +
264 +goodbye world
259 goodbye world
265 hg diff -Bb
260 hg diff -Bb
266 diff -r 540c40a65b78 foo
261 diff -r 540c40a65b78 foo
267 --- a/foo
262 --- a/foo
268 +++ b/foo
263 +++ b/foo
269 @@ -1,2 +1,5 @@
264 @@ -1,2 +1,5 @@
270 -hello world
265 -hello world
271 -goodbye world
272 +helloworld
266 +helloworld
273 +
267 +
274 +
268 +
275 +
269 +
276 +goodbye world
270 goodbye world
277 hg diff -w
271 hg diff -w
278 diff -r 540c40a65b78 foo
272 diff -r 540c40a65b78 foo
279 --- a/foo
273 --- a/foo
280 +++ b/foo
274 +++ b/foo
281 @@ -1,2 +1,5 @@
275 @@ -1,2 +1,5 @@
282 -hello world
276 hello world
283 -goodbye world
284 +helloworld
285 +
277 +
286 +
278 +
287 +
279 +
288 +goodbye world
280 goodbye world
289 hg diff -wB
281 hg diff -wB
@@ -1,106 +1,105
1 % init
1 % init
2 % commit
2 % commit
3 adding base
3 adding base
4 % qnew mqbase
4 % qnew mqbase
5 % qrefresh
5 % qrefresh
6 % qdiff
6 % qdiff
7 diff -r 67e992f2c4f3 base
7 diff -r 67e992f2c4f3 base
8 --- a/base
8 --- a/base
9 +++ b/base
9 +++ b/base
10 @@ -1,1 +1,1 @@
10 @@ -1,1 +1,1 @@
11 -base
11 -base
12 +patched
12 +patched
13 % qdiff dirname
13 % qdiff dirname
14 diff -r 67e992f2c4f3 base
14 diff -r 67e992f2c4f3 base
15 --- a/base
15 --- a/base
16 +++ b/base
16 +++ b/base
17 @@ -1,1 +1,1 @@
17 @@ -1,1 +1,1 @@
18 -base
18 -base
19 +patched
19 +patched
20 % qdiff filename
20 % qdiff filename
21 diff -r 67e992f2c4f3 base
21 diff -r 67e992f2c4f3 base
22 --- a/base
22 --- a/base
23 +++ b/base
23 +++ b/base
24 @@ -1,1 +1,1 @@
24 @@ -1,1 +1,1 @@
25 -base
25 -base
26 +patched
26 +patched
27 % revert
27 % revert
28 % qpop
28 % qpop
29 popping mqbase
29 popping mqbase
30 patch queue now empty
30 patch queue now empty
31 % qdelete mqbase
31 % qdelete mqbase
32 % commit 2
32 % commit 2
33 adding lines
33 adding lines
34 % qnew 2
34 % qnew 2
35 % qdiff -U 1
35 % qdiff -U 1
36 diff -r 35fb829491c1 lines
36 diff -r 35fb829491c1 lines
37 --- a/lines
37 --- a/lines
38 +++ b/lines
38 +++ b/lines
39 @@ -1,1 +1,3 @@
39 @@ -1,1 +1,3 @@
40 +
40 +
41 +
41 +
42 1
42 1
43 @@ -4,4 +6,4 @@
43 @@ -4,4 +6,4 @@
44 4
44 4
45 -hello world
45 -hello world
46 -goodbye world
46 -goodbye world
47 +hello world
47 +hello world
48 + goodbye world
48 + goodbye world
49 7
49 7
50 % qdiff -b
50 % qdiff -b
51 diff -r 35fb829491c1 lines
51 diff -r 35fb829491c1 lines
52 --- a/lines
52 --- a/lines
53 +++ b/lines
53 +++ b/lines
54 @@ -1,9 +1,11 @@
54 @@ -1,9 +1,11 @@
55 +
55 +
56 +
56 +
57 1
57 1
58 2
58 2
59 3
59 3
60 4
60 4
61 -hello world
61 hello world
62 -goodbye world
62 -goodbye world
63 +hello world
64 + goodbye world
63 + goodbye world
65 7
64 7
66 8
65 8
67 9
66 9
68 % qdiff -U 1 -B
67 % qdiff -U 1 -B
69 diff -r 35fb829491c1 lines
68 diff -r 35fb829491c1 lines
70 --- a/lines
69 --- a/lines
71 +++ b/lines
70 +++ b/lines
72 @@ -4,4 +6,4 @@
71 @@ -4,4 +6,4 @@
73 4
72 4
74 -hello world
73 -hello world
75 -goodbye world
74 -goodbye world
76 +hello world
75 +hello world
77 + goodbye world
76 + goodbye world
78 7
77 7
79 % qdiff -w
78 % qdiff -w
80 diff -r 35fb829491c1 lines
79 diff -r 35fb829491c1 lines
81 --- a/lines
80 --- a/lines
82 +++ b/lines
81 +++ b/lines
83 @@ -1,3 +1,5 @@
82 @@ -1,3 +1,5 @@
84 +
83 +
85 +
84 +
86 1
85 1
87 2
86 2
88 3
87 3
89 % qdiff --inverse
88 % qdiff --inverse
90 diff -r 35fb829491c1 lines
89 diff -r 35fb829491c1 lines
91 --- a/lines
90 --- a/lines
92 +++ b/lines
91 +++ b/lines
93 @@ -1,11 +1,9 @@
92 @@ -1,11 +1,9 @@
94 -
93 -
95 -
94 -
96 1
95 1
97 2
96 2
98 3
97 3
99 4
98 4
100 -hello world
99 -hello world
101 - goodbye world
100 - goodbye world
102 +hello world
101 +hello world
103 +goodbye world
102 +goodbye world
104 7
103 7
105 8
104 8
106 9
105 9
General Comments 0
You need to be logged in to leave comments. Login now