Mercurial > public > mercurial-scm > hg
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 |