comparison mercurial/merge.py @ 5708:f6bf89722e29

merge: add flag merging intelligence - properly handle all 27 combinations of flags - prompt on conflicts
author Matt Mackall <mpm@selenic.com>
date Thu, 27 Dec 2007 22:47:44 -0600
parents 5049bbf988e1
children c704b03884ef
comparison
equal deleted inserted replaced
5707:76dd039c2bad 5708:f6bf89722e29
354 def fmerge(f, f2=None, fa=None): 354 def fmerge(f, f2=None, fa=None):
355 """merge flags""" 355 """merge flags"""
356 if not f2: 356 if not f2:
357 f2 = f 357 f2 = f
358 fa = f 358 fa = f
359 a, b, c = ma.execf(fa), m1.execf(f), m2.execf(f2) 359 a, m, n = ma.flags(fa), m1.flags(f), m2.flags(f2)
360 if ((a^b) | (a^c)) ^ a: 360 if m == n: # flags agree
361 return 'x' 361 return m # unchanged
362 a, b, c = ma.linkf(fa), m1.linkf(f), m2.linkf(f2) 362 if m and n: # flags are set but don't agree
363 if ((a^b) | (a^c)) ^ a: 363 if not a: # both differ from parent
364 return 'l' 364 r = repo.ui.prompt(
365 return '' 365 _(" conflicting flags for %s\n"
366 "(n)one, e(x)ec or sym(l)ink?") % f, "[nxl]", "n")
367 return r != "n" and r or ''
368 if m == a:
369 return n # changed from m to n
370 return m # changed from n to m
371 if m and m != a: # changed from a to m
372 return m
373 if n and n != a: # changed from a to n
374 return n
375 return '' # flag was cleared
366 376
367 def act(msg, m, f, *args): 377 def act(msg, m, f, *args):
368 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) 378 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m))
369 action.append((f, m) + args) 379 action.append((f, m) + args)
370 380
384 # Compare manifests 394 # Compare manifests
385 for f, n in m1.iteritems(): 395 for f, n in m1.iteritems():
386 if partial and not partial(f): 396 if partial and not partial(f):
387 continue 397 continue
388 if f in m2: 398 if f in m2:
399 if overwrite or backwards:
400 rflags = m2.flags(f)
401 else:
402 rflags = fmerge(f)
389 # are files different? 403 # are files different?
390 if n != m2[f]: 404 if n != m2[f]:
391 a = ma.get(f, nullid) 405 a = ma.get(f, nullid)
392 # are we clobbering? 406 # are we clobbering?
393 if overwrite: 407 if overwrite:
394 act("clobbering", "g", f, m2.flags(f)) 408 act("clobbering", "g", f, rflags)
395 # or are we going back in time and clean? 409 # or are we going back in time and clean?
396 elif backwards and not n[20:]: 410 elif backwards and not n[20:]:
397 act("reverting", "g", f, m2.flags(f)) 411 act("reverting", "g", f, rflags)
398 # are both different from the ancestor? 412 # are both different from the ancestor?
399 elif n != a and m2[f] != a: 413 elif n != a and m2[f] != a:
400 act("versions differ", "m", f, f, f, fmerge(f), False) 414 act("versions differ", "m", f, f, f, rflags, False)
401 # is remote's version newer? 415 # is remote's version newer?
402 elif m2[f] != a: 416 elif m2[f] != a:
403 act("remote is newer", "g", f, fmerge(f)) 417 act("remote is newer", "g", f, rflags)
404 # local is newer, not overwrite, check mode bits 418 # local is newer, not overwrite, check mode bits
405 elif fmerge(f) != m1.flags(f): 419 elif m1.flags(f) != rflags:
406 act("update permissions", "e", f, m2.flags(f)) 420 act("update permissions", "e", f, rflags)
407 # contents same, check mode bits 421 # contents same, check mode bits
408 elif m1.flags(f) != m2.flags(f): 422 elif m1.flags(f) != rflags:
409 # are we clobbering? 423 act("update permissions", "e", f, rflags)
410 # is remote's version newer?
411 # or are we going back?
412 if overwrite or fmerge(f) != m1.flags(f) or backwards:
413 act("update permissions", "e", f, m2.flags(f))
414 elif f in copied: 424 elif f in copied:
415 continue 425 continue
416 elif f in copy: 426 elif f in copy:
417 f2 = copy[f] 427 f2 = copy[f]
418 if f2 not in m2: # directory rename 428 if f2 not in m2: # directory rename