##// END OF EJS Templates
simplemerge: burn "minimal" feature to the ground...
Pierre-Yves David -
r22023:f1883065 default
parent child Browse files
Show More
@@ -11,8 +11,7 b" options = [('L', 'label', [], _('labels "
11 ('a', 'text', None, _('treat all files as text')),
11 ('a', 'text', None, _('treat all files as text')),
12 ('p', 'print', None,
12 ('p', 'print', None,
13 _('print results instead of overwriting LOCAL')),
13 _('print results instead of overwriting LOCAL')),
14 ('', 'no-minimal', None,
14 ('', 'no-minimal', None, _('no effect (DEPRECATED)')),
15 _('do not try to minimize conflict regions')),
16 ('h', 'help', None, _('display help and exit')),
15 ('h', 'help', None, _('display help and exit')),
17 ('q', 'quiet', None, _('suppress output'))]
16 ('q', 'quiet', None, _('suppress output'))]
18
17
@@ -191,8 +191,7 b' def _premerge(repo, toolconf, files, lab'
191 (tool, premerge, _valid))
191 (tool, premerge, _valid))
192
192
193 if premerge:
193 if premerge:
194 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels,
194 r = simplemerge.simplemerge(ui, a, b, c, quiet=True, label=labels)
195 no_minimal=True)
196 if not r:
195 if not r:
197 ui.debug(" premerge successful\n")
196 ui.debug(" premerge successful\n")
198 return 0
197 return 0
@@ -219,7 +218,7 b' def _imerge(repo, mynode, orig, fcd, fco'
219
218
220 ui = repo.ui
219 ui = repo.ui
221
220
222 r = simplemerge.simplemerge(ui, a, b, c, label=labels, no_minimal=True)
221 r = simplemerge.simplemerge(ui, a, b, c, label=labels)
223 return True, r
222 return True, r
224 return False, 0
223 return False, 0
225
224
@@ -82,8 +82,7 b' class Merge3Text(object):'
82 start_marker='<<<<<<<',
82 start_marker='<<<<<<<',
83 mid_marker='=======',
83 mid_marker='=======',
84 end_marker='>>>>>>>',
84 end_marker='>>>>>>>',
85 base_marker=None,
85 base_marker=None):
86 reprocess=False):
87 """Return merge in cvs-like form.
86 """Return merge in cvs-like form.
88 """
87 """
89 self.conflicts = False
88 self.conflicts = False
@@ -93,8 +92,6 b' class Merge3Text(object):'
93 newline = '\r\n'
92 newline = '\r\n'
94 elif self.a[0].endswith('\r'):
93 elif self.a[0].endswith('\r'):
95 newline = '\r'
94 newline = '\r'
96 if base_marker and reprocess:
97 raise CantReprocessAndShowBase
98 if name_a:
95 if name_a:
99 start_marker = start_marker + ' ' + name_a
96 start_marker = start_marker + ' ' + name_a
100 if name_b:
97 if name_b:
@@ -102,8 +99,6 b' class Merge3Text(object):'
102 if name_base and base_marker:
99 if name_base and base_marker:
103 base_marker = base_marker + ' ' + name_base
100 base_marker = base_marker + ' ' + name_base
104 merge_regions = self.merge_regions()
101 merge_regions = self.merge_regions()
105 if reprocess is True:
106 merge_regions = self.reprocess_merge_regions(merge_regions)
107 for t in merge_regions:
102 for t in merge_regions:
108 what = t[0]
103 what = t[0]
109 if what == 'unchanged':
104 if what == 'unchanged':
@@ -278,37 +273,6 b' class Merge3Text(object):'
278 ia = aend
273 ia = aend
279 ib = bend
274 ib = bend
280
275
281 def reprocess_merge_regions(self, merge_regions):
282 """Where there are conflict regions, remove the agreed lines.
283
284 Lines where both A and B have made the same changes are
285 eliminated.
286 """
287 for region in merge_regions:
288 if region[0] != "conflict":
289 yield region
290 continue
291 type, iz, zmatch, ia, amatch, ib, bmatch = region
292 a_region = self.a[ia:amatch]
293 b_region = self.b[ib:bmatch]
294 matches = mdiff.get_matching_blocks(''.join(a_region),
295 ''.join(b_region))
296 next_a = ia
297 next_b = ib
298 for region_ia, region_ib, region_len in matches[:-1]:
299 region_ia += ia
300 region_ib += ib
301 reg = self.mismatch_region(next_a, region_ia, next_b,
302 region_ib)
303 if reg is not None:
304 yield reg
305 yield 'same', region_ia, region_len + region_ia
306 next_a = region_ia + region_len
307 next_b = region_ib + region_len
308 reg = self.mismatch_region(next_a, amatch, next_b, bmatch)
309 if reg is not None:
310 yield reg
311
312 def mismatch_region(next_a, region_ia, next_b, region_ib):
276 def mismatch_region(next_a, region_ia, next_b, region_ib):
313 if next_a < region_ia or next_b < region_ib:
277 if next_a < region_ia or next_b < region_ib:
314 return 'conflict', None, None, next_a, region_ia, next_b, region_ib
278 return 'conflict', None, None, next_a, region_ia, next_b, region_ib
@@ -437,11 +401,8 b' def simplemerge(ui, local, base, other, '
437 else:
401 else:
438 out = sys.stdout
402 out = sys.stdout
439
403
440 reprocess = not opts.get('no_minimal')
441
442 m3 = Merge3Text(basetext, localtext, othertext)
404 m3 = Merge3Text(basetext, localtext, othertext)
443 for line in m3.merge_lines(name_a=name_a, name_b=name_b,
405 for line in m3.merge_lines(name_a=name_a, name_b=name_b):
444 reprocess=reprocess):
445 out.write(line)
406 out.write(line)
446
407
447 if not opts.get('print'):
408 if not opts.get('print'):
@@ -143,23 +143,11 b' conflicts'
143 $ echo not other >> conflict-local
143 $ echo not other >> conflict-local
144 $ echo end >> conflict-local
144 $ echo end >> conflict-local
145 $ echo end >> conflict-other
145 $ echo end >> conflict-other
146
146 $ python simplemerge -p conflict-local base conflict-other
147 $ python simplemerge -p conflict-local base conflict-other
147 base
148 base
148 <<<<<<< conflict-local
149 <<<<<<< conflict-local
149 not other
150 not other
150 =======
151 other
152 >>>>>>> conflict-other
153 end
154 warning: conflicts during merge.
155 [1]
156
157 --no-minimal
158
159 $ python simplemerge -p --no-minimal conflict-local base conflict-other
160 base
161 <<<<<<< conflict-local
162 not other
163 end
151 end
164 =======
152 =======
165 other
153 other
@@ -174,10 +162,11 b' 1 label'
174 base
162 base
175 <<<<<<< foo
163 <<<<<<< foo
176 not other
164 not other
165 end
177 =======
166 =======
178 other
167 other
168 end
179 >>>>>>> conflict-other
169 >>>>>>> conflict-other
180 end
181 warning: conflicts during merge.
170 warning: conflicts during merge.
182 [1]
171 [1]
183
172
@@ -187,10 +176,11 b' 2 labels'
187 base
176 base
188 <<<<<<< foo
177 <<<<<<< foo
189 not other
178 not other
179 end
190 =======
180 =======
191 other
181 other
182 end
192 >>>>>>> bar
183 >>>>>>> bar
193 end
194 warning: conflicts during merge.
184 warning: conflicts during merge.
195 [1]
185 [1]
196
186
@@ -231,7 +221,7 b' help'
231 -L --label labels to use on conflict markers
221 -L --label labels to use on conflict markers
232 -a --text treat all files as text
222 -a --text treat all files as text
233 -p --print print results instead of overwriting LOCAL
223 -p --print print results instead of overwriting LOCAL
234 --no-minimal do not try to minimize conflict regions
224 --no-minimal no effect (DEPRECATED)
235 -h --help display help and exit
225 -h --help display help and exit
236 -q --quiet suppress output
226 -q --quiet suppress output
237
227
@@ -251,7 +241,7 b' wrong number of arguments'
251 -L --label labels to use on conflict markers
241 -L --label labels to use on conflict markers
252 -a --text treat all files as text
242 -a --text treat all files as text
253 -p --print print results instead of overwriting LOCAL
243 -p --print print results instead of overwriting LOCAL
254 --no-minimal do not try to minimize conflict regions
244 --no-minimal no effect (DEPRECATED)
255 -h --help display help and exit
245 -h --help display help and exit
256 -q --quiet suppress output
246 -q --quiet suppress output
257 [1]
247 [1]
@@ -272,7 +262,7 b' bad option'
272 -L --label labels to use on conflict markers
262 -L --label labels to use on conflict markers
273 -a --text treat all files as text
263 -a --text treat all files as text
274 -p --print print results instead of overwriting LOCAL
264 -p --print print results instead of overwriting LOCAL
275 --no-minimal do not try to minimize conflict regions
265 --no-minimal no effect (DEPRECATED)
276 -h --help display help and exit
266 -h --help display help and exit
277 -q --quiet suppress output
267 -q --quiet suppress output
278 [1]
268 [1]
@@ -320,66 +320,6 b' bbb'
320 self.log(''.join(ml))
320 self.log(''.join(ml))
321 self.assertEquals(ml, MERGED_RESULT)
321 self.assertEquals(ml, MERGED_RESULT)
322
322
323 def test_minimal_conflicts_common(self):
324 """Reprocessing"""
325 base_text = ("a\n" * 20).splitlines(True)
326 this_text = ("a\n"*10+"b\n" * 10).splitlines(True)
327 other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True)
328 m3 = Merge3(base_text, other_text, this_text)
329 m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
330 merged_text = "".join(list(m_lines))
331 optimal_text = ("a\n" * 10 + "<<<<<<< OTHER\nc\n=======\n"
332 + ">>>>>>> THIS\n"
333 + 8* "b\n" + "<<<<<<< OTHER\nc\n=======\n"
334 + 2* "b\n" + ">>>>>>> THIS\n")
335 self.assertEquals(optimal_text, merged_text)
336
337 def test_minimal_conflicts_unique(self):
338 def add_newline(s):
339 """Add a newline to each entry in the string"""
340 return [(x+'\n') for x in s]
341
342 base_text = add_newline("abcdefghijklm")
343 this_text = add_newline("abcdefghijklmNOPQRSTUVWXYZ")
344 other_text = add_newline("abcdefghijklm1OPQRSTUVWXY2")
345 m3 = Merge3(base_text, other_text, this_text)
346 m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
347 merged_text = "".join(list(m_lines))
348 optimal_text = ''.join(add_newline("abcdefghijklm")
349 + ["<<<<<<< OTHER\n1\n=======\nN\n>>>>>>> THIS\n"]
350 + add_newline('OPQRSTUVWXY')
351 + ["<<<<<<< OTHER\n2\n=======\nZ\n>>>>>>> THIS\n"]
352 )
353 self.assertEquals(optimal_text, merged_text)
354
355 def test_minimal_conflicts_nonunique(self):
356 def add_newline(s):
357 """Add a newline to each entry in the string"""
358 return [(x+'\n') for x in s]
359
360 base_text = add_newline("abacddefgghij")
361 this_text = add_newline("abacddefgghijkalmontfprz")
362 other_text = add_newline("abacddefgghijknlmontfprd")
363 m3 = Merge3(base_text, other_text, this_text)
364 m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True)
365 merged_text = "".join(list(m_lines))
366 optimal_text = ''.join(add_newline("abacddefgghijk")
367 + ["<<<<<<< OTHER\nn\n=======\na\n>>>>>>> THIS\n"]
368 + add_newline('lmontfpr')
369 + ["<<<<<<< OTHER\nd\n=======\nz\n>>>>>>> THIS\n"]
370 )
371 self.assertEquals(optimal_text, merged_text)
372
373 def test_reprocess_and_base(self):
374 """Reprocessing and showing base breaks correctly"""
375 base_text = ("a\n" * 20).splitlines(True)
376 this_text = ("a\n"*10+"b\n" * 10).splitlines(True)
377 other_text = ("a\n"*10+"c\n"+"b\n" * 8 + "c\n").splitlines(True)
378 m3 = Merge3(base_text, other_text, this_text)
379 m_lines = m3.merge_lines('OTHER', 'THIS', reprocess=True,
380 base_marker='|||||||')
381 self.assertRaises(CantReprocessAndShowBase, list, m_lines)
382
383 def test_binary(self):
323 def test_binary(self):
384 self.assertRaises(util.Abort, Merge3, ['\x00'], ['a'], ['b'])
324 self.assertRaises(util.Abort, Merge3, ['\x00'], ['a'], ['b'])
385
325
@@ -1,5 +1,5 b''
1 ....................
1 ................
2 ----------------------------------------------------------------------
2 ----------------------------------------------------------------------
3 Ran 20 tests in 0.000s
3 Ran 16 tests in 0.000s
4
4
5 OK
5 OK
General Comments 0
You need to be logged in to leave comments. Login now