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