##// END OF EJS Templates
merge: introduce mergeresult.addfile() and use it...
Pulkit Goyal -
r45839:b442920a default
parent child Browse files
Show More
@@ -578,21 +578,17 b' def overridecalculateupdates('
578 % lfile
578 % lfile
579 )
579 )
580 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
580 if repo.ui.promptchoice(usermsg, 0) == 0: # pick remote largefile
581 mresult.actions[lfile] = (b'r', None, b'replaced by standin')
581 mresult.addfile(lfile, b'r', None, b'replaced by standin')
582 mresult.actions[standin] = (b'g', sargs, b'replaces standin')
582 mresult.addfile(standin, b'g', sargs, b'replaces standin')
583 else: # keep local normal file
583 else: # keep local normal file
584 mresult.actions[lfile] = (b'k', None, b'replaces standin')
584 mresult.addfile(lfile, b'k', None, b'replaces standin')
585 if branchmerge:
585 if branchmerge:
586 mresult.actions[standin] = (
586 mresult.addfile(
587 b'k',
587 standin, b'k', None, b'replaced by non-standin',
588 None,
589 b'replaced by non-standin',
590 )
588 )
591 else:
589 else:
592 mresult.actions[standin] = (
590 mresult.addfile(
593 b'r',
591 standin, b'r', None, b'replaced by non-standin',
594 None,
595 b'replaced by non-standin',
596 )
592 )
597 elif lm in (b'g', b'dc') and sm != b'r':
593 elif lm in (b'g', b'dc') and sm != b'r':
598 if lm == b'dc':
594 if lm == b'dc':
@@ -611,29 +607,23 b' def overridecalculateupdates('
611 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
607 if repo.ui.promptchoice(usermsg, 0) == 0: # keep local largefile
612 if branchmerge:
608 if branchmerge:
613 # largefile can be restored from standin safely
609 # largefile can be restored from standin safely
614 mresult.actions[lfile] = (
610 mresult.addfile(
615 b'k',
611 lfile, b'k', None, b'replaced by standin',
616 None,
617 b'replaced by standin',
618 )
612 )
619 mresult.actions[standin] = (b'k', None, b'replaces standin')
613 mresult.addfile(standin, b'k', None, b'replaces standin')
620 else:
614 else:
621 # "lfile" should be marked as "removed" without
615 # "lfile" should be marked as "removed" without
622 # removal of itself
616 # removal of itself
623 mresult.actions[lfile] = (
617 mresult.addfile(
624 b'lfmr',
618 lfile, b'lfmr', None, b'forget non-standin largefile',
625 None,
626 b'forget non-standin largefile',
627 )
619 )
628
620
629 # linear-merge should treat this largefile as 're-added'
621 # linear-merge should treat this largefile as 're-added'
630 mresult.actions[standin] = (b'a', None, b'keep standin')
622 mresult.addfile(standin, b'a', None, b'keep standin')
631 else: # pick remote normal file
623 else: # pick remote normal file
632 mresult.actions[lfile] = (b'g', largs, b'replaces standin')
624 mresult.addfile(lfile, b'g', largs, b'replaces standin')
633 mresult.actions[standin] = (
625 mresult.addfile(
634 b'r',
626 standin, b'r', None, b'replaced by non-standin',
635 None,
636 b'replaced by non-standin',
637 )
627 )
638
628
639 return mresult
629 return mresult
@@ -561,12 +561,21 b' class mergeresult(object):'
561 self._renamedelete = {}
561 self._renamedelete = {}
562 self._commitinfo = {}
562 self._commitinfo = {}
563
563
564 def updatevalues(self, actions, diverge, renamedelete, commitinfo):
564 def updatevalues(self, diverge, renamedelete, commitinfo):
565 self._actions = actions
566 self._diverge = diverge
565 self._diverge = diverge
567 self._renamedelete = renamedelete
566 self._renamedelete = renamedelete
568 self._commitinfo = commitinfo
567 self._commitinfo = commitinfo
569
568
569 def addfile(self, filename, action, data, message):
570 """ adds a new file to the mergeresult object
571
572 filename: file which we are adding
573 action: one of mergestatemod.ACTION_*
574 data: a tuple of information like fctx and ctx related to this merge
575 message: a message about the merge
576 """
577 self._actions[filename] = (action, data, message)
578
570 @property
579 @property
571 def actions(self):
580 def actions(self):
572 return self._actions
581 return self._actions
@@ -636,6 +645,7 b' def manifestmerge('
636
645
637 Returns an object of mergeresult class
646 Returns an object of mergeresult class
638 """
647 """
648 mresult = mergeresult()
639 if matcher is not None and matcher.always():
649 if matcher is not None and matcher.always():
640 matcher = None
650 matcher = None
641
651
@@ -700,7 +710,6 b' def manifestmerge('
700
710
701 diff = m1.diff(m2, match=matcher)
711 diff = m1.diff(m2, match=matcher)
702
712
703 actions = {}
704 for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff):
713 for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff):
705 if n1 and n2: # file exists on both local and remote side
714 if n1 and n2: # file exists on both local and remote side
706 if f not in ma:
715 if f not in ma:
@@ -709,13 +718,15 b' def manifestmerge('
709 f, None
718 f, None
710 ) or branch_copies2.copy.get(f, None)
719 ) or branch_copies2.copy.get(f, None)
711 if fa is not None:
720 if fa is not None:
712 actions[f] = (
721 mresult.addfile(
722 f,
713 mergestatemod.ACTION_MERGE,
723 mergestatemod.ACTION_MERGE,
714 (f, f, fa, False, pa.node()),
724 (f, f, fa, False, pa.node()),
715 b'both renamed from %s' % fa,
725 b'both renamed from %s' % fa,
716 )
726 )
717 else:
727 else:
718 actions[f] = (
728 mresult.addfile(
729 f,
719 mergestatemod.ACTION_MERGE,
730 mergestatemod.ACTION_MERGE,
720 (f, f, None, False, pa.node()),
731 (f, f, None, False, pa.node()),
721 b'both created',
732 b'both created',
@@ -725,20 +736,20 b' def manifestmerge('
725 fla = ma.flags(f)
736 fla = ma.flags(f)
726 nol = b'l' not in fl1 + fl2 + fla
737 nol = b'l' not in fl1 + fl2 + fla
727 if n2 == a and fl2 == fla:
738 if n2 == a and fl2 == fla:
728 actions[f] = (
739 mresult.addfile(
729 mergestatemod.ACTION_KEEP,
740 f, mergestatemod.ACTION_KEEP, (), b'remote unchanged',
730 (),
731 b'remote unchanged',
732 )
741 )
733 elif n1 == a and fl1 == fla: # local unchanged - use remote
742 elif n1 == a and fl1 == fla: # local unchanged - use remote
734 if n1 == n2: # optimization: keep local content
743 if n1 == n2: # optimization: keep local content
735 actions[f] = (
744 mresult.addfile(
745 f,
736 mergestatemod.ACTION_EXEC,
746 mergestatemod.ACTION_EXEC,
737 (fl2,),
747 (fl2,),
738 b'update permissions',
748 b'update permissions',
739 )
749 )
740 else:
750 else:
741 actions[f] = (
751 mresult.addfile(
752 f,
742 mergestatemod.ACTION_GET,
753 mergestatemod.ACTION_GET,
743 (fl2, False),
754 (fl2, False),
744 b'remote is newer',
755 b'remote is newer',
@@ -746,13 +757,15 b' def manifestmerge('
746 if branchmerge:
757 if branchmerge:
747 commitinfo[f] = b'other'
758 commitinfo[f] = b'other'
748 elif nol and n2 == a: # remote only changed 'x'
759 elif nol and n2 == a: # remote only changed 'x'
749 actions[f] = (
760 mresult.addfile(
761 f,
750 mergestatemod.ACTION_EXEC,
762 mergestatemod.ACTION_EXEC,
751 (fl2,),
763 (fl2,),
752 b'update permissions',
764 b'update permissions',
753 )
765 )
754 elif nol and n1 == a: # local only changed 'x'
766 elif nol and n1 == a: # local only changed 'x'
755 actions[f] = (
767 mresult.addfile(
768 f,
756 mergestatemod.ACTION_GET,
769 mergestatemod.ACTION_GET,
757 (fl1, False),
770 (fl1, False),
758 b'remote is newer',
771 b'remote is newer',
@@ -760,7 +773,8 b' def manifestmerge('
760 if branchmerge:
773 if branchmerge:
761 commitinfo[f] = b'other'
774 commitinfo[f] = b'other'
762 else: # both changed something
775 else: # both changed something
763 actions[f] = (
776 mresult.addfile(
777 f,
764 mergestatemod.ACTION_MERGE,
778 mergestatemod.ACTION_MERGE,
765 (f, f, f, False, pa.node()),
779 (f, f, f, False, pa.node()),
766 b'versions differ',
780 b'versions differ',
@@ -773,20 +787,23 b' def manifestmerge('
773 ): # directory rename, move local
787 ): # directory rename, move local
774 f2 = branch_copies1.movewithdir[f]
788 f2 = branch_copies1.movewithdir[f]
775 if f2 in m2:
789 if f2 in m2:
776 actions[f2] = (
790 mresult.addfile(
791 f2,
777 mergestatemod.ACTION_MERGE,
792 mergestatemod.ACTION_MERGE,
778 (f, f2, None, True, pa.node()),
793 (f, f2, None, True, pa.node()),
779 b'remote directory rename, both created',
794 b'remote directory rename, both created',
780 )
795 )
781 else:
796 else:
782 actions[f2] = (
797 mresult.addfile(
798 f2,
783 mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL,
799 mergestatemod.ACTION_DIR_RENAME_MOVE_LOCAL,
784 (f, fl1),
800 (f, fl1),
785 b'remote directory rename - move from %s' % f,
801 b'remote directory rename - move from %s' % f,
786 )
802 )
787 elif f in branch_copies1.copy:
803 elif f in branch_copies1.copy:
788 f2 = branch_copies1.copy[f]
804 f2 = branch_copies1.copy[f]
789 actions[f] = (
805 mresult.addfile(
806 f,
790 mergestatemod.ACTION_MERGE,
807 mergestatemod.ACTION_MERGE,
791 (f, f2, f2, False, pa.node()),
808 (f, f2, f2, False, pa.node()),
792 b'local copied/moved from %s' % f2,
809 b'local copied/moved from %s' % f2,
@@ -794,13 +811,15 b' def manifestmerge('
794 elif f in ma: # clean, a different, no remote
811 elif f in ma: # clean, a different, no remote
795 if n1 != ma[f]:
812 if n1 != ma[f]:
796 if acceptremote:
813 if acceptremote:
797 actions[f] = (
814 mresult.addfile(
815 f,
798 mergestatemod.ACTION_REMOVE,
816 mergestatemod.ACTION_REMOVE,
799 None,
817 None,
800 b'remote delete',
818 b'remote delete',
801 )
819 )
802 else:
820 else:
803 actions[f] = (
821 mresult.addfile(
822 f,
804 mergestatemod.ACTION_CHANGED_DELETED,
823 mergestatemod.ACTION_CHANGED_DELETED,
805 (f, None, f, False, pa.node()),
824 (f, None, f, False, pa.node()),
806 b'prompt changed/deleted',
825 b'prompt changed/deleted',
@@ -808,16 +827,12 b' def manifestmerge('
808 elif n1 == addednodeid:
827 elif n1 == addednodeid:
809 # This file was locally added. We should forget it instead of
828 # This file was locally added. We should forget it instead of
810 # deleting it.
829 # deleting it.
811 actions[f] = (
830 mresult.addfile(
812 mergestatemod.ACTION_FORGET,
831 f, mergestatemod.ACTION_FORGET, None, b'remote deleted',
813 None,
814 b'remote deleted',
815 )
832 )
816 else:
833 else:
817 actions[f] = (
834 mresult.addfile(
818 mergestatemod.ACTION_REMOVE,
835 f, mergestatemod.ACTION_REMOVE, None, b'other deleted',
819 None,
820 b'other deleted',
821 )
836 )
822 elif n2: # file exists only on remote side
837 elif n2: # file exists only on remote side
823 if f in copied1:
838 if f in copied1:
@@ -825,13 +840,15 b' def manifestmerge('
825 elif f in branch_copies2.movewithdir:
840 elif f in branch_copies2.movewithdir:
826 f2 = branch_copies2.movewithdir[f]
841 f2 = branch_copies2.movewithdir[f]
827 if f2 in m1:
842 if f2 in m1:
828 actions[f2] = (
843 mresult.addfile(
844 f2,
829 mergestatemod.ACTION_MERGE,
845 mergestatemod.ACTION_MERGE,
830 (f2, f, None, False, pa.node()),
846 (f2, f, None, False, pa.node()),
831 b'local directory rename, both created',
847 b'local directory rename, both created',
832 )
848 )
833 else:
849 else:
834 actions[f2] = (
850 mresult.addfile(
851 f2,
835 mergestatemod.ACTION_LOCAL_DIR_RENAME_GET,
852 mergestatemod.ACTION_LOCAL_DIR_RENAME_GET,
836 (f, fl2),
853 (f, fl2),
837 b'local directory rename - get from %s' % f,
854 b'local directory rename - get from %s' % f,
@@ -839,13 +856,15 b' def manifestmerge('
839 elif f in branch_copies2.copy:
856 elif f in branch_copies2.copy:
840 f2 = branch_copies2.copy[f]
857 f2 = branch_copies2.copy[f]
841 if f2 in m2:
858 if f2 in m2:
842 actions[f] = (
859 mresult.addfile(
860 f,
843 mergestatemod.ACTION_MERGE,
861 mergestatemod.ACTION_MERGE,
844 (f2, f, f2, False, pa.node()),
862 (f2, f, f2, False, pa.node()),
845 b'remote copied from %s' % f2,
863 b'remote copied from %s' % f2,
846 )
864 )
847 else:
865 else:
848 actions[f] = (
866 mresult.addfile(
867 f,
849 mergestatemod.ACTION_MERGE,
868 mergestatemod.ACTION_MERGE,
850 (f2, f, f2, True, pa.node()),
869 (f2, f, f2, True, pa.node()),
851 b'remote moved from %s' % f2,
870 b'remote moved from %s' % f2,
@@ -863,19 +882,22 b' def manifestmerge('
863 # Checking whether the files are different is expensive, so we
882 # Checking whether the files are different is expensive, so we
864 # don't do that when we can avoid it.
883 # don't do that when we can avoid it.
865 if not force:
884 if not force:
866 actions[f] = (
885 mresult.addfile(
886 f,
867 mergestatemod.ACTION_CREATED,
887 mergestatemod.ACTION_CREATED,
868 (fl2,),
888 (fl2,),
869 b'remote created',
889 b'remote created',
870 )
890 )
871 elif not branchmerge:
891 elif not branchmerge:
872 actions[f] = (
892 mresult.addfile(
893 f,
873 mergestatemod.ACTION_CREATED,
894 mergestatemod.ACTION_CREATED,
874 (fl2,),
895 (fl2,),
875 b'remote created',
896 b'remote created',
876 )
897 )
877 else:
898 else:
878 actions[f] = (
899 mresult.addfile(
900 f,
879 mergestatemod.ACTION_CREATED_MERGE,
901 mergestatemod.ACTION_CREATED_MERGE,
880 (fl2, pa.node()),
902 (fl2, pa.node()),
881 b'remote created, get or merge',
903 b'remote created, get or merge',
@@ -888,20 +910,23 b' def manifestmerge('
888 df = branch_copies1.dirmove[d] + f[len(d) :]
910 df = branch_copies1.dirmove[d] + f[len(d) :]
889 break
911 break
890 if df is not None and df in m1:
912 if df is not None and df in m1:
891 actions[df] = (
913 mresult.addfile(
914 df,
892 mergestatemod.ACTION_MERGE,
915 mergestatemod.ACTION_MERGE,
893 (df, f, f, False, pa.node()),
916 (df, f, f, False, pa.node()),
894 b'local directory rename - respect move '
917 b'local directory rename - respect move '
895 b'from %s' % f,
918 b'from %s' % f,
896 )
919 )
897 elif acceptremote:
920 elif acceptremote:
898 actions[f] = (
921 mresult.addfile(
922 f,
899 mergestatemod.ACTION_CREATED,
923 mergestatemod.ACTION_CREATED,
900 (fl2,),
924 (fl2,),
901 b'remote recreating',
925 b'remote recreating',
902 )
926 )
903 else:
927 else:
904 actions[f] = (
928 mresult.addfile(
929 f,
905 mergestatemod.ACTION_DELETED_CHANGED,
930 mergestatemod.ACTION_DELETED_CHANGED,
906 (None, f, f, False, pa.node()),
931 (None, f, f, False, pa.node()),
907 b'prompt deleted/changed',
932 b'prompt deleted/changed',
@@ -909,18 +934,17 b' def manifestmerge('
909
934
910 if repo.ui.configbool(b'experimental', b'merge.checkpathconflicts'):
935 if repo.ui.configbool(b'experimental', b'merge.checkpathconflicts'):
911 # If we are merging, look for path conflicts.
936 # If we are merging, look for path conflicts.
912 checkpathconflicts(repo, wctx, p2, actions)
937 checkpathconflicts(repo, wctx, p2, mresult.actions)
913
938
914 narrowmatch = repo.narrowmatch()
939 narrowmatch = repo.narrowmatch()
915 if not narrowmatch.always():
940 if not narrowmatch.always():
916 # Updates "actions" in place
941 # Updates "actions" in place
917 _filternarrowactions(narrowmatch, branchmerge, actions)
942 _filternarrowactions(narrowmatch, branchmerge, mresult.actions)
918
943
919 renamedelete = branch_copies1.renamedelete
944 renamedelete = branch_copies1.renamedelete
920 renamedelete.update(branch_copies2.renamedelete)
945 renamedelete.update(branch_copies2.renamedelete)
921
946
922 mresult = mergeresult()
947 mresult.updatevalues(diverge, renamedelete, commitinfo)
923 mresult.updatevalues(actions, diverge, renamedelete, commitinfo)
924 return mresult
948 return mresult
925
949
926
950
@@ -1046,7 +1070,7 b' def calculateupdates('
1046 # Call for bids
1070 # Call for bids
1047 # Pick the best bid for each file
1071 # Pick the best bid for each file
1048 repo.ui.note(_(b'\nauction for merging merge bids\n'))
1072 repo.ui.note(_(b'\nauction for merging merge bids\n'))
1049 actions = {}
1073 mresult = mergeresult()
1050 for f, bids in sorted(fbids.items()):
1074 for f, bids in sorted(fbids.items()):
1051 # bids is a mapping from action method to list af actions
1075 # bids is a mapping from action method to list af actions
1052 # Consensus?
1076 # Consensus?
@@ -1054,19 +1078,19 b' def calculateupdates('
1054 m, l = list(bids.items())[0]
1078 m, l = list(bids.items())[0]
1055 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1079 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1056 repo.ui.note(_(b" %s: consensus for %s\n") % (f, m))
1080 repo.ui.note(_(b" %s: consensus for %s\n") % (f, m))
1057 actions[f] = l[0]
1081 mresult.addfile(f, *l[0])
1058 continue
1082 continue
1059 # If keep is an option, just do it.
1083 # If keep is an option, just do it.
1060 if mergestatemod.ACTION_KEEP in bids:
1084 if mergestatemod.ACTION_KEEP in bids:
1061 repo.ui.note(_(b" %s: picking 'keep' action\n") % f)
1085 repo.ui.note(_(b" %s: picking 'keep' action\n") % f)
1062 actions[f] = bids[mergestatemod.ACTION_KEEP][0]
1086 mresult.addfile(f, *bids[mergestatemod.ACTION_KEEP][0])
1063 continue
1087 continue
1064 # If there are gets and they all agree [how could they not?], do it.
1088 # If there are gets and they all agree [how could they not?], do it.
1065 if mergestatemod.ACTION_GET in bids:
1089 if mergestatemod.ACTION_GET in bids:
1066 ga0 = bids[mergestatemod.ACTION_GET][0]
1090 ga0 = bids[mergestatemod.ACTION_GET][0]
1067 if all(a == ga0 for a in bids[mergestatemod.ACTION_GET][1:]):
1091 if all(a == ga0 for a in bids[mergestatemod.ACTION_GET][1:]):
1068 repo.ui.note(_(b" %s: picking 'get' action\n") % f)
1092 repo.ui.note(_(b" %s: picking 'get' action\n") % f)
1069 actions[f] = ga0
1093 mresult.addfile(f, *ga0)
1070 continue
1094 continue
1071 # TODO: Consider other simple actions such as mode changes
1095 # TODO: Consider other simple actions such as mode changes
1072 # Handle inefficient democrazy.
1096 # Handle inefficient democrazy.
@@ -1079,12 +1103,11 b' def calculateupdates('
1079 repo.ui.warn(
1103 repo.ui.warn(
1080 _(b' %s: ambiguous merge - picked %s action\n') % (f, m)
1104 _(b' %s: ambiguous merge - picked %s action\n') % (f, m)
1081 )
1105 )
1082 actions[f] = l[0]
1106 mresult.addfile(f, *l[0])
1083 continue
1107 continue
1084 repo.ui.note(_(b'end of auction\n\n'))
1108 repo.ui.note(_(b'end of auction\n\n'))
1085 # TODO: think about commitinfo when bid merge is used
1109 # TODO: think about commitinfo when bid merge is used
1086 mresult = mergeresult()
1110 mresult.updatevalues(diverge, renamedelete, {})
1087 mresult.updatevalues(actions, diverge, renamedelete, {})
1088
1111
1089 if wctx.rev() is None:
1112 if wctx.rev() is None:
1090 fractions = _forgetremoved(wctx, mctx, branchmerge)
1113 fractions = _forgetremoved(wctx, mctx, branchmerge)
@@ -1870,22 +1893,19 b' def update('
1870 % prompts,
1893 % prompts,
1871 0,
1894 0,
1872 ):
1895 ):
1873 mresult.actions[f] = (
1896 mresult.addfile(
1874 mergestatemod.ACTION_REMOVE,
1897 f, mergestatemod.ACTION_REMOVE, None, b'prompt delete',
1875 None,
1876 b'prompt delete',
1877 )
1898 )
1878 elif f in p1:
1899 elif f in p1:
1879 mresult.actions[f] = (
1900 mresult.addfile(
1901 f,
1880 mergestatemod.ACTION_ADD_MODIFIED,
1902 mergestatemod.ACTION_ADD_MODIFIED,
1881 None,
1903 None,
1882 b'prompt keep',
1904 b'prompt keep',
1883 )
1905 )
1884 else:
1906 else:
1885 mresult.actions[f] = (
1907 mresult.addfile(
1886 mergestatemod.ACTION_ADD,
1908 f, mergestatemod.ACTION_ADD, None, b'prompt keep',
1887 None,
1888 b'prompt keep',
1889 )
1909 )
1890 elif m == mergestatemod.ACTION_DELETED_CHANGED:
1910 elif m == mergestatemod.ACTION_DELETED_CHANGED:
1891 f1, f2, fa, move, anc = args
1911 f1, f2, fa, move, anc = args
@@ -1902,7 +1922,8 b' def update('
1902 )
1922 )
1903 == 0
1923 == 0
1904 ):
1924 ):
1905 mresult.actions[f] = (
1925 mresult.addfile(
1926 f,
1906 mergestatemod.ACTION_GET,
1927 mergestatemod.ACTION_GET,
1907 (flags, False),
1928 (flags, False),
1908 b'prompt recreating',
1929 b'prompt recreating',
General Comments 0
You need to be logged in to leave comments. Login now