comparison mercurial/simplemerge.py @ 48591:ad0c6bf6f02e

simplemerge: make minimize() a free function IMO, `Merge3Text` should be about merging text without knowing about conflict markers. "Conflict minimization" is about making conflict markers smaller, so it should be moved out. This patch does that. I'll refactor it next. Differential Revision: https://phab.mercurial-scm.org/D11980
author Martin von Zweigbergk <martinvonz@google.com>
date Tue, 11 Jan 2022 22:03:55 -0800
parents 12ac4401ff7d
children c2537aec3bb6
comparison
equal deleted inserted replaced
48590:12ac4401ff7d 48591:ad0c6bf6f02e
212 yield b'unchanged', zmatch, zend 212 yield b'unchanged', zmatch, zend
213 iz = zend 213 iz = zend
214 ia = aend 214 ia = aend
215 ib = bend 215 ib = bend
216 216
217 def minimize(self, merge_groups):
218 """Trim conflict regions of lines where A and B sides match.
219
220 Lines where both A and B have made the same changes at the beginning
221 or the end of each merge region are eliminated from the conflict
222 region and are instead considered the same.
223 """
224 for what, lines in merge_groups:
225 if what != b"conflict":
226 yield what, lines
227 continue
228 base_lines, a_lines, b_lines = lines
229 alen = len(a_lines)
230 blen = len(b_lines)
231
232 # find matches at the front
233 ii = 0
234 while ii < alen and ii < blen and a_lines[ii] == b_lines[ii]:
235 ii += 1
236 startmatches = ii
237
238 # find matches at the end
239 ii = 0
240 while (
241 ii < alen and ii < blen and a_lines[-ii - 1] == b_lines[-ii - 1]
242 ):
243 ii += 1
244 endmatches = ii
245
246 if startmatches > 0:
247 yield b'same', a_lines[:startmatches]
248
249 yield (
250 b'conflict',
251 (
252 base_lines,
253 a_lines[startmatches : alen - endmatches],
254 b_lines[startmatches : blen - endmatches],
255 ),
256 )
257
258 if endmatches > 0:
259 yield b'same', a_lines[alen - endmatches :]
260
261 def find_sync_regions(self): 217 def find_sync_regions(self):
262 """Return a list of sync regions, where both descendants match the base. 218 """Return a list of sync regions, where both descendants match the base.
263 219
264 Generates a list of (base1, base2, a1, a2, b1, b2). There is 220 Generates a list of (base1, base2, a1, a2, b1, b2). There is
265 always a zero-length sync region at the end of all the files. 221 always a zero-length sync region at the end of all the files.
346 if m3.a[0].endswith(b'\r\n'): 302 if m3.a[0].endswith(b'\r\n'):
347 return b'\r\n' 303 return b'\r\n'
348 elif m3.a[0].endswith(b'\r'): 304 elif m3.a[0].endswith(b'\r'):
349 return b'\r' 305 return b'\r'
350 return b'\n' 306 return b'\n'
307
308
309 def _minimize(merge_groups):
310 """Trim conflict regions of lines where A and B sides match.
311
312 Lines where both A and B have made the same changes at the beginning
313 or the end of each merge region are eliminated from the conflict
314 region and are instead considered the same.
315 """
316 for what, lines in merge_groups:
317 if what != b"conflict":
318 yield what, lines
319 continue
320 base_lines, a_lines, b_lines = lines
321 alen = len(a_lines)
322 blen = len(b_lines)
323
324 # find matches at the front
325 ii = 0
326 while ii < alen and ii < blen and a_lines[ii] == b_lines[ii]:
327 ii += 1
328 startmatches = ii
329
330 # find matches at the end
331 ii = 0
332 while ii < alen and ii < blen and a_lines[-ii - 1] == b_lines[-ii - 1]:
333 ii += 1
334 endmatches = ii
335
336 if startmatches > 0:
337 yield b'same', a_lines[:startmatches]
338
339 yield (
340 b'conflict',
341 (
342 base_lines,
343 a_lines[startmatches : alen - endmatches],
344 b_lines[startmatches : blen - endmatches],
345 ),
346 )
347
348 if endmatches > 0:
349 yield b'same', a_lines[alen - endmatches :]
351 350
352 351
353 def render_minimized( 352 def render_minimized(
354 m3, 353 m3,
355 name_a=None, 354 name_a=None,
364 if name_a: 363 if name_a:
365 start_marker = start_marker + b' ' + name_a 364 start_marker = start_marker + b' ' + name_a
366 if name_b: 365 if name_b:
367 end_marker = end_marker + b' ' + name_b 366 end_marker = end_marker + b' ' + name_b
368 merge_groups = m3.merge_groups() 367 merge_groups = m3.merge_groups()
369 merge_groups = m3.minimize(merge_groups) 368 merge_groups = _minimize(merge_groups)
370 lines = [] 369 lines = []
371 for what, group_lines in merge_groups: 370 for what, group_lines in merge_groups:
372 if what == b'conflict': 371 if what == b'conflict':
373 base_lines, a_lines, b_lines = group_lines 372 base_lines, a_lines, b_lines = group_lines
374 conflicts = True 373 conflicts = True