681 """run the conclude step of the merge driver, if any |
681 """run the conclude step of the merge driver, if any |
682 |
682 |
683 This is currently not implemented -- it's an extension point.""" |
683 This is currently not implemented -- it's an extension point.""" |
684 return True |
684 return True |
685 |
685 |
686 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, partial, |
686 def manifestmerge(repo, wctx, p2, pa, branchmerge, force, matcher, |
687 acceptremote, followcopies): |
687 acceptremote, followcopies): |
688 """ |
688 """ |
689 Merge p1 and p2 with ancestor pa and generate merge action list |
689 Merge p1 and p2 with ancestor pa and generate merge action list |
690 |
690 |
691 branchmerge and force are as passed in to update |
691 branchmerge and force are as passed in to update |
692 partial = function to filter file lists |
692 matcher = matcher to filter file lists |
693 acceptremote = accept the incoming changes without prompting |
693 acceptremote = accept the incoming changes without prompting |
694 """ |
694 """ |
|
695 if matcher is not None and matcher.always(): |
|
696 matcher = None |
695 |
697 |
696 copy, movewithdir, diverge, renamedelete = {}, {}, {}, {} |
698 copy, movewithdir, diverge, renamedelete = {}, {}, {}, {} |
697 |
699 |
698 # manifests fetched in order are going to be faster, so prime the caches |
700 # manifests fetched in order are going to be faster, so prime the caches |
699 [x.manifest() for x in |
701 [x.manifest() for x in |
703 ret = copies.mergecopies(repo, wctx, p2, pa) |
705 ret = copies.mergecopies(repo, wctx, p2, pa) |
704 copy, movewithdir, diverge, renamedelete = ret |
706 copy, movewithdir, diverge, renamedelete = ret |
705 |
707 |
706 repo.ui.note(_("resolving manifests\n")) |
708 repo.ui.note(_("resolving manifests\n")) |
707 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n" |
709 repo.ui.debug(" branchmerge: %s, force: %s, partial: %s\n" |
708 % (bool(branchmerge), bool(force), bool(partial))) |
710 % (bool(branchmerge), bool(force), bool(matcher))) |
709 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2)) |
711 repo.ui.debug(" ancestor: %s, local: %s, remote: %s\n" % (pa, wctx, p2)) |
710 |
712 |
711 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest() |
713 m1, m2, ma = wctx.manifest(), p2.manifest(), pa.manifest() |
712 copied = set(copy.values()) |
714 copied = set(copy.values()) |
713 copied.update(movewithdir.values()) |
715 copied.update(movewithdir.values()) |
722 # Compare manifests |
724 # Compare manifests |
723 diff = m1.diff(m2) |
725 diff = m1.diff(m2) |
724 |
726 |
725 actions = {} |
727 actions = {} |
726 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems(): |
728 for f, ((n1, fl1), (n2, fl2)) in diff.iteritems(): |
727 if partial and not partial(f): |
729 if matcher and not matcher(f): |
728 continue |
730 continue |
729 if n1 and n2: # file exists on both local and remote side |
731 if n1 and n2: # file exists on both local and remote side |
730 if f not in ma: |
732 if f not in ma: |
731 fa = copy.get(f, None) |
733 fa = copy.get(f, None) |
732 if fa is not None: |
734 if fa is not None: |
842 del actions[f] # don't get = keep local deleted |
844 del actions[f] # don't get = keep local deleted |
843 |
845 |
844 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, |
846 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, |
845 acceptremote, followcopies, matcher=None): |
847 acceptremote, followcopies, matcher=None): |
846 "Calculate the actions needed to merge mctx into wctx using ancestors" |
848 "Calculate the actions needed to merge mctx into wctx using ancestors" |
847 if matcher is None or matcher.always(): |
|
848 partial = False |
|
849 else: |
|
850 partial = matcher.matchfn |
|
851 |
|
852 if len(ancestors) == 1: # default |
849 if len(ancestors) == 1: # default |
853 actions, diverge, renamedelete = manifestmerge( |
850 actions, diverge, renamedelete = manifestmerge( |
854 repo, wctx, mctx, ancestors[0], branchmerge, force, partial, |
851 repo, wctx, mctx, ancestors[0], branchmerge, force, matcher, |
855 acceptremote, followcopies) |
852 acceptremote, followcopies) |
856 _checkunknownfiles(repo, wctx, mctx, force, actions) |
853 _checkunknownfiles(repo, wctx, mctx, force, actions) |
857 |
854 |
858 else: # only when merge.preferancestor=* - the default |
855 else: # only when merge.preferancestor=* - the default |
859 repo.ui.note( |
856 repo.ui.note( |
864 fbids = {} # mapping filename to bids (action method to list af actions) |
861 fbids = {} # mapping filename to bids (action method to list af actions) |
865 diverge, renamedelete = None, None |
862 diverge, renamedelete = None, None |
866 for ancestor in ancestors: |
863 for ancestor in ancestors: |
867 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor) |
864 repo.ui.note(_('\ncalculating bids for ancestor %s\n') % ancestor) |
868 actions, diverge1, renamedelete1 = manifestmerge( |
865 actions, diverge1, renamedelete1 = manifestmerge( |
869 repo, wctx, mctx, ancestor, branchmerge, force, partial, |
866 repo, wctx, mctx, ancestor, branchmerge, force, matcher, |
870 acceptremote, followcopies) |
867 acceptremote, followcopies) |
871 _checkunknownfiles(repo, wctx, mctx, force, actions) |
868 _checkunknownfiles(repo, wctx, mctx, force, actions) |
872 |
869 |
873 # Track the shortest set of warning on the theory that bid |
870 # Track the shortest set of warning on the theory that bid |
874 # merge will correctly incorporate more information |
871 # merge will correctly incorporate more information |