Mercurial > public > mercurial-scm > hg
comparison mercurial/merge.py @ 23473:922b10c870c5
merge: branch code into {n1 and n2, n1, n2} top-level cases
There are three high-level cases that are of interest in
manifestmerge(): 1) The file exists on both sides, 2) The file exists
only on the local side, and 3) The file exists only on the remote
side. Let's make this clearer in the code.
The 'if f in copied' case will be broken up into the two applicable
branches in the next patch.
author | Martin von Zweigbergk <martinvonz@google.com> |
---|---|
date | Sun, 23 Nov 2014 14:09:10 -0800 |
parents | 6a92b5fcfba8 |
children | 9f4ac44a7273 |
comparison
equal
deleted
inserted
replaced
23472:48cdf90f17c5 | 23473:922b10c870c5 |
---|---|
412 diff = m1.diff(m2) | 412 diff = m1.diff(m2) |
413 | 413 |
414 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems(): | 414 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems(): |
415 if partial and not partial(f): | 415 if partial and not partial(f): |
416 continue | 416 continue |
417 if n1 and n2: | 417 if n1 and n2: # file exists on both local and remote side |
418 if f not in ma: | 418 if f not in ma: |
419 fa = copy.get(f, None) | 419 fa = copy.get(f, None) |
420 if fa is not None: | 420 if fa is not None: |
421 actions['m'].append((f, (f, f, fa, False, pa.node()), | 421 actions['m'].append((f, (f, f, fa, False, pa.node()), |
422 "both renamed from " + fa)) | 422 "both renamed from " + fa)) |
441 else: # both changed something | 441 else: # both changed something |
442 actions['m'].append((f, (f, f, f, False, pa.node()), | 442 actions['m'].append((f, (f, f, f, False, pa.node()), |
443 "versions differ")) | 443 "versions differ")) |
444 elif f in copied: # files we'll deal with on m2 side | 444 elif f in copied: # files we'll deal with on m2 side |
445 pass | 445 pass |
446 elif n1 and f in movewithdir: # directory rename, move local | 446 elif n1: # file exists only on local side |
447 f2 = movewithdir[f] | 447 if f in movewithdir: # directory rename, move local |
448 actions['dm'].append((f2, (f, fl1), | 448 f2 = movewithdir[f] |
449 "remote directory rename - move from " + f)) | 449 actions['dm'].append((f2, (f, fl1), |
450 elif n1 and f in copy: | 450 "remote directory rename - move from " + f)) |
451 f2 = copy[f] | 451 elif f in copy: |
452 actions['m'].append((f, (f, f2, f2, False, pa.node()), | 452 f2 = copy[f] |
453 "local copied/moved from " + f2)) | 453 actions['m'].append((f, (f, f2, f2, False, pa.node()), |
454 elif n1 and f in ma: # clean, a different, no remote | 454 "local copied/moved from " + f2)) |
455 if n1 != ma[f]: | 455 elif f in ma: # clean, a different, no remote |
456 if acceptremote: | 456 if n1 != ma[f]: |
457 actions['r'].append((f, None, "remote delete")) | 457 if acceptremote: |
458 actions['r'].append((f, None, "remote delete")) | |
459 else: | |
460 actions['cd'].append((f, None, | |
461 "prompt changed/deleted")) | |
462 elif n1[20:] == 'a': | |
463 # This extra 'a' is added by working copy manifest to mark | |
464 # the file as locally added. We should forget it instead of | |
465 # deleting it. | |
466 actions['f'].append((f, None, "remote deleted")) | |
458 else: | 467 else: |
459 actions['cd'].append((f, None, "prompt changed/deleted")) | 468 actions['r'].append((f, None, "other deleted")) |
460 elif n1[20:] == 'a': | 469 elif n2: # file exists only on remote side |
461 # This extra 'a' is added by working copy manifest to mark the | 470 if f in movewithdir: |
462 # file as locally added. We should forget it instead of | 471 f2 = movewithdir[f] |
463 # deleting it. | 472 actions['dg'].append((f2, (f, fl2), |
464 actions['f'].append((f, None, "remote deleted")) | 473 "local directory rename - get from " + f)) |
465 else: | 474 elif f in copy: |
466 actions['r'].append((f, None, "other deleted")) | 475 f2 = copy[f] |
467 elif n2 and f in movewithdir: | 476 if f2 in m2: |
468 f2 = movewithdir[f] | 477 actions['m'].append((f, (f2, f, f2, False, pa.node()), |
469 actions['dg'].append((f2, (f, fl2), | 478 "remote copied from " + f2)) |
470 "local directory rename - get from " + f)) | 479 else: |
471 elif n2 and f in copy: | 480 actions['m'].append((f, (f2, f, f2, True, pa.node()), |
472 f2 = copy[f] | 481 "remote moved from " + f2)) |
473 if f2 in m2: | 482 elif f not in ma: |
474 actions['m'].append((f, (f2, f, f2, False, pa.node()), | 483 # local unknown, remote created: the logic is described by the |
475 "remote copied from " + f2)) | 484 # following table: |
476 else: | 485 # |
477 actions['m'].append((f, (f2, f, f2, True, pa.node()), | 486 # force branchmerge different | action |
478 "remote moved from " + f2)) | 487 # n * n | get |
479 elif n2 and f not in ma: | 488 # n * y | abort |
480 # local unknown, remote created: the logic is described by the | 489 # y n * | get |
481 # following table: | 490 # y y n | get |
482 # | 491 # y y y | merge |
483 # force branchmerge different | action | 492 # |
484 # n * n | get | 493 # Checking whether the files are different is expensive, so we |
485 # n * y | abort | 494 # don't do that when we can avoid it. |
486 # y n * | get | 495 if force and not branchmerge: |
487 # y y n | get | 496 actions['g'].append((f, (fl2,), "remote created")) |
488 # y y y | merge | 497 else: |
489 # | 498 different = _checkunknownfile(repo, wctx, p2, f) |
490 # Checking whether the files are different is expensive, so we | 499 if force and branchmerge and different: |
491 # don't do that when we can avoid it. | 500 actions['m'].append((f, (f, f, None, False, pa.node()), |
492 if force and not branchmerge: | 501 "remote differs from untracked local")) |
493 actions['g'].append((f, (fl2,), "remote created")) | 502 elif not force and different: |
494 else: | 503 aborts.append((f, 'ud')) |
504 else: | |
505 actions['g'].append((f, (fl2,), "remote created")) | |
506 elif n2 != ma[f]: | |
495 different = _checkunknownfile(repo, wctx, p2, f) | 507 different = _checkunknownfile(repo, wctx, p2, f) |
496 if force and branchmerge and different: | 508 if not force and different: |
497 actions['m'].append((f, (f, f, None, False, pa.node()), | |
498 "remote differs from untracked local")) | |
499 elif not force and different: | |
500 aborts.append((f, 'ud')) | 509 aborts.append((f, 'ud')) |
501 else: | 510 else: |
502 actions['g'].append((f, (fl2,), "remote created")) | 511 if acceptremote: |
503 elif n2 and n2 != ma[f]: | 512 actions['g'].append((f, (fl2,), "remote recreating")) |
504 different = _checkunknownfile(repo, wctx, p2, f) | 513 else: |
505 if not force and different: | 514 actions['dc'].append((f, (fl2,), |
506 aborts.append((f, 'ud')) | 515 "prompt deleted/changed")) |
507 else: | |
508 if acceptremote: | |
509 actions['g'].append((f, (fl2,), "remote recreating")) | |
510 else: | |
511 actions['dc'].append((f, (fl2,), "prompt deleted/changed")) | |
512 | 516 |
513 for f, m in sorted(aborts): | 517 for f, m in sorted(aborts): |
514 if m == 'ud': | 518 if m == 'ud': |
515 repo.ui.warn(_("%s: untracked file differs\n") % f) | 519 repo.ui.warn(_("%s: untracked file differs\n") % f) |
516 else: assert False, m | 520 else: assert False, m |