Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/merge.py @ 20943:003cb972178d
merge: include ancestor node in merge actions
author | Mads Kiilerich <madski@unity3d.com> |
---|---|
date | Fri, 28 Feb 2014 02:38:33 +0100 |
parents | 0b50788c160c |
children | 5b8d5803d7b7 |
comparison
equal
deleted
inserted
replaced
20942:3737e653dcbe | 20943:003cb972178d |
---|---|
338 f2, fd, flags = args | 338 f2, fd, flags = args |
339 if f: | 339 if f: |
340 pmmf.discard(f) | 340 pmmf.discard(f) |
341 pmmf.add(fd) | 341 pmmf.add(fd) |
342 def mergeop(f, args): | 342 def mergeop(f, args): |
343 f2, fa, fd, move = args | 343 f2, fa, fd, move, anc = args |
344 if move: | 344 if move: |
345 pmmf.discard(f) | 345 pmmf.discard(f) |
346 pmmf.add(fd) | 346 pmmf.add(fd) |
347 | 347 |
348 opmap = { | 348 opmap = { |
466 elif nol and n2 == a: # remote only changed 'x' | 466 elif nol and n2 == a: # remote only changed 'x' |
467 actions.append((f, "e", (fl2,), "update permissions")) | 467 actions.append((f, "e", (fl2,), "update permissions")) |
468 elif nol and n1 == a: # local only changed 'x' | 468 elif nol and n1 == a: # local only changed 'x' |
469 actions.append((f, "g", (fl1,), "remote is newer")) | 469 actions.append((f, "g", (fl1,), "remote is newer")) |
470 else: # both changed something | 470 else: # both changed something |
471 actions.append((f, "m", (f, fa, f, False), "versions differ")) | 471 actions.append((f, "m", (f, fa, f, False, pa.node()), |
472 "versions differ")) | |
472 elif f in copied: # files we'll deal with on m2 side | 473 elif f in copied: # files we'll deal with on m2 side |
473 pass | 474 pass |
474 elif n1 and f in movewithdir: # directory rename | 475 elif n1 and f in movewithdir: # directory rename |
475 f2 = movewithdir[f] | 476 f2 = movewithdir[f] |
476 actions.append((f, "d", (None, f2, fl1), | 477 actions.append((f, "d", (None, f2, fl1), |
477 "remote renamed directory to " + f2)) | 478 "remote renamed directory to " + f2)) |
478 elif n1 and f in copy: | 479 elif n1 and f in copy: |
479 f2 = copy[f] | 480 f2 = copy[f] |
480 actions.append((f, "m", (f2, f2, f, False), | 481 actions.append((f, "m", (f2, f2, f, False, pa.node()), |
481 "local copied/moved to " + f2)) | 482 "local copied/moved to " + f2)) |
482 elif n1 and f in ma: # clean, a different, no remote | 483 elif n1 and f in ma: # clean, a different, no remote |
483 if n1 != ma[f]: | 484 if n1 != ma[f]: |
484 if acceptremote: | 485 if acceptremote: |
485 actions.append((f, "r", None, "remote delete")) | 486 actions.append((f, "r", None, "remote delete")) |
494 actions.append((None, "d", (f, f2, fl2), | 495 actions.append((None, "d", (f, f2, fl2), |
495 "local renamed directory to " + f2)) | 496 "local renamed directory to " + f2)) |
496 elif n2 and f in copy: | 497 elif n2 and f in copy: |
497 f2 = copy[f] | 498 f2 = copy[f] |
498 if f2 in m2: | 499 if f2 in m2: |
499 actions.append((f2, "m", (f, f2, f, False), | 500 actions.append((f2, "m", (f, f2, f, False, pa.node()), |
500 "remote copied to " + f)) | 501 "remote copied to " + f)) |
501 else: | 502 else: |
502 actions.append((f2, "m", (f, f2, f, True), | 503 actions.append((f2, "m", (f, f2, f, True, pa.node()), |
503 "remote moved to " + f)) | 504 "remote moved to " + f)) |
504 elif n2 and f not in ma: | 505 elif n2 and f not in ma: |
505 # local unknown, remote created: the logic is described by the | 506 # local unknown, remote created: the logic is described by the |
506 # following table: | 507 # following table: |
507 # | 508 # |
518 actions.append((f, "g", (fl2,), "remote created")) | 519 actions.append((f, "g", (fl2,), "remote created")) |
519 else: | 520 else: |
520 different = _checkunknownfile(repo, wctx, p2, f) | 521 different = _checkunknownfile(repo, wctx, p2, f) |
521 if force and branchmerge and different: | 522 if force and branchmerge and different: |
522 # FIXME: This is wrong - f is not in ma ... | 523 # FIXME: This is wrong - f is not in ma ... |
523 actions.append((f, "m", (f, f, f, False), | 524 actions.append((f, "m", (f, f, f, False, pa.node()), |
524 "remote differs from untracked local")) | 525 "remote differs from untracked local")) |
525 elif not force and different: | 526 elif not force and different: |
526 aborts.append((f, "ud")) | 527 aborts.append((f, "ud")) |
527 else: | 528 else: |
528 actions.append((f, "g", (fl2,), "remote created")) | 529 actions.append((f, "g", (fl2,), "remote created")) |
594 i = 0 | 595 i = 0 |
595 i += 1 | 596 i += 1 |
596 if i > 0: | 597 if i > 0: |
597 yield i, f | 598 yield i, f |
598 | 599 |
599 def applyupdates(repo, actions, wctx, mctx, actx, overwrite): | 600 def applyupdates(repo, actions, wctx, mctx, overwrite): |
600 """apply the merge action list to the working directory | 601 """apply the merge action list to the working directory |
601 | 602 |
602 wctx is the working copy context | 603 wctx is the working copy context |
603 mctx is the context to be merged into the working copy | 604 mctx is the context to be merged into the working copy |
604 actx is the context of the common ancestor | |
605 | 605 |
606 Return a tuple of counts (updated, merged, removed, unresolved) that | 606 Return a tuple of counts (updated, merged, removed, unresolved) that |
607 describes how many files were affected by the update. | 607 describes how many files were affected by the update. |
608 """ | 608 """ |
609 | 609 |
616 # prescan for merges | 616 # prescan for merges |
617 for a in actions: | 617 for a in actions: |
618 f, m, args, msg = a | 618 f, m, args, msg = a |
619 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) | 619 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) |
620 if m == "m": # merge | 620 if m == "m": # merge |
621 f2, fa, fd, move = args | 621 f2, fa, fd, move, anc = args |
622 if fd == '.hgsubstate': # merged internally | 622 if fd == '.hgsubstate': # merged internally |
623 continue | 623 continue |
624 repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd)) | 624 repo.ui.debug(" preserving %s for resolve of %s\n" % (f, fd)) |
625 fcl = wctx[f] | 625 fcl = wctx[f] |
626 fco = mctx[f2] | 626 fco = mctx[f2] |
627 if mctx == actx: # backwards, use working dir parent as ancestor | 627 actx = repo[anc] |
628 if fcl.parents(): | 628 if fa in actx: |
629 fca = fcl.p1() | |
630 else: | |
631 fca = repo.filectx(f, fileid=nullrev) | |
632 elif fa in actx: | |
633 fca = actx[fa] | 629 fca = actx[fa] |
634 else: | 630 else: |
635 fca = repo.filectx(f, fileid=nullrev) | 631 fca = repo.filectx(f, fileid=nullrev) |
636 ms.add(fcl, fco, fca, fd) | 632 ms.add(fcl, fco, fca, fd) |
637 if f != fd and move: | 633 if f != fd and move: |
681 | 677 |
682 for i, a in enumerate(actions): | 678 for i, a in enumerate(actions): |
683 f, m, args, msg = a | 679 f, m, args, msg = a |
684 progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files) | 680 progress(_updating, z + i + 1, item=f, total=numupdates, unit=_files) |
685 if m == "m": # merge | 681 if m == "m": # merge |
686 f2, fa, fd, move = args | 682 f2, fa, fd, move, anc = args |
687 if fd == '.hgsubstate': # subrepo states need updating | 683 if fd == '.hgsubstate': # subrepo states need updating |
688 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), | 684 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), |
689 overwrite) | 685 overwrite) |
690 continue | 686 continue |
691 audit(fd) | 687 audit(fd) |
791 if branchmerge: | 787 if branchmerge: |
792 repo.dirstate.otherparent(f) | 788 repo.dirstate.otherparent(f) |
793 else: | 789 else: |
794 repo.dirstate.normal(f) | 790 repo.dirstate.normal(f) |
795 elif m == "m": # merge | 791 elif m == "m": # merge |
796 f2, fa, fd, move = args | 792 f2, fa, fd, move, anc = args |
797 if branchmerge: | 793 if branchmerge: |
798 # We've done a branch merge, mark this file as merged | 794 # We've done a branch merge, mark this file as merged |
799 # so that we properly record the merger later | 795 # so that we properly record the merger later |
800 repo.dirstate.merge(fd) | 796 repo.dirstate.merge(fd) |
801 if f != f2: # copy/rename | 797 if f != f2: # copy/rename |
997 if not partial: | 993 if not partial: |
998 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) | 994 repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2) |
999 # note that we're in the middle of an update | 995 # note that we're in the middle of an update |
1000 repo.vfs.write('updatestate', p2.hex()) | 996 repo.vfs.write('updatestate', p2.hex()) |
1001 | 997 |
1002 stats = applyupdates(repo, actions, wc, p2, pa, overwrite) | 998 stats = applyupdates(repo, actions, wc, p2, overwrite) |
1003 | 999 |
1004 if not partial: | 1000 if not partial: |
1005 repo.setparents(fp1, fp2) | 1001 repo.setparents(fp1, fp2) |
1006 recordupdates(repo, actions, branchmerge) | 1002 recordupdates(repo, actions, branchmerge) |
1007 # update completed, clear state | 1003 # update completed, clear state |