##// END OF EJS Templates
merge: use constants for actions...
Gregory Szorc -
r37130:43ffd907 default
parent child Browse files
Show More
@@ -71,6 +71,23 b" MERGE_RECORD_UNRESOLVED_PATH = b'pu'"
71 MERGE_RECORD_RESOLVED_PATH = b'pr'
71 MERGE_RECORD_RESOLVED_PATH = b'pr'
72 MERGE_RECORD_DRIVER_RESOLVED = b'd'
72 MERGE_RECORD_DRIVER_RESOLVED = b'd'
73
73
74 ACTION_FORGET = b'f'
75 ACTION_REMOVE = b'r'
76 ACTION_ADD = b'a'
77 ACTION_GET = b'g'
78 ACTION_PATH_CONFLICT = b'p'
79 ACTION_PATH_CONFLICT_RESOLVE = b'pr'
80 ACTION_ADD_MODIFIED = b'am'
81 ACTION_CREATED = b'c'
82 ACTION_DELETED_CHANGED = b'dc'
83 ACTION_CHANGED_DELETED = b'cd'
84 ACTION_MERGE = b'm'
85 ACTION_LOCAL_DIR_RENAME_GET = b'dg'
86 ACTION_DIR_RENAME_MOVE_LOCAL = b'dm'
87 ACTION_KEEP = b'k'
88 ACTION_EXEC = b'e'
89 ACTION_CREATED_MERGE = b'cm'
90
74 class mergestate(object):
91 class mergestate(object):
75 '''track 3-way merge state of individual files
92 '''track 3-way merge state of individual files
76
93
@@ -588,18 +605,18 b' class mergestate(object):'
588 if fcd.isabsent():
605 if fcd.isabsent():
589 # dc: local picked. Need to drop if present, which may
606 # dc: local picked. Need to drop if present, which may
590 # happen on re-resolves.
607 # happen on re-resolves.
591 action = 'f'
608 action = ACTION_FORGET
592 else:
609 else:
593 # cd: remote picked (or otherwise deleted)
610 # cd: remote picked (or otherwise deleted)
594 action = 'r'
611 action = ACTION_REMOVE
595 else:
612 else:
596 if fcd.isabsent(): # dc: remote picked
613 if fcd.isabsent(): # dc: remote picked
597 action = 'g'
614 action = ACTION_GET
598 elif fco.isabsent(): # cd: local picked
615 elif fco.isabsent(): # cd: local picked
599 if dfile in self.localctx:
616 if dfile in self.localctx:
600 action = 'am'
617 action = ACTION_ADD_MODIFIED
601 else:
618 else:
602 action = 'a'
619 action = ACTION_ADD
603 # else: regular merges (no action necessary)
620 # else: regular merges (no action necessary)
604 self._results[dfile] = r, action
621 self._results[dfile] = r, action
605
622
@@ -631,7 +648,7 b' class mergestate(object):'
631 if r is None:
648 if r is None:
632 updated += 1
649 updated += 1
633 elif r == 0:
650 elif r == 0:
634 if action == 'r':
651 if action == ACTION_REMOVE:
635 removed += 1
652 removed += 1
636 else:
653 else:
637 merged += 1
654 merged += 1
@@ -643,7 +660,13 b' class mergestate(object):'
643
660
644 def actions(self):
661 def actions(self):
645 """return lists of actions to perform on the dirstate"""
662 """return lists of actions to perform on the dirstate"""
646 actions = {'r': [], 'f': [], 'a': [], 'am': [], 'g': []}
663 actions = {
664 ACTION_REMOVE: [],
665 ACTION_FORGET: [],
666 ACTION_ADD: [],
667 ACTION_ADD_MODIFIED: [],
668 ACTION_GET: [],
669 }
647 for f, (r, action) in self._results.iteritems():
670 for f, (r, action) in self._results.iteritems():
648 if action is not None:
671 if action is not None:
649 actions[action].append((f, None, "merge result"))
672 actions[action].append((f, None, "merge result"))
@@ -658,19 +681,19 b' class mergestate(object):'
658 """queues a file to be removed from the dirstate
681 """queues a file to be removed from the dirstate
659
682
660 Meant for use by custom merge drivers."""
683 Meant for use by custom merge drivers."""
661 self._results[f] = 0, 'r'
684 self._results[f] = 0, ACTION_REMOVE
662
685
663 def queueadd(self, f):
686 def queueadd(self, f):
664 """queues a file to be added to the dirstate
687 """queues a file to be added to the dirstate
665
688
666 Meant for use by custom merge drivers."""
689 Meant for use by custom merge drivers."""
667 self._results[f] = 0, 'a'
690 self._results[f] = 0, ACTION_ADD
668
691
669 def queueget(self, f):
692 def queueget(self, f):
670 """queues a file to be marked modified in the dirstate
693 """queues a file to be marked modified in the dirstate
671
694
672 Meant for use by custom merge drivers."""
695 Meant for use by custom merge drivers."""
673 self._results[f] = 0, 'g'
696 self._results[f] = 0, ACTION_GET
674
697
675 def _getcheckunknownconfig(repo, section, name):
698 def _getcheckunknownconfig(repo, section, name):
676 config = repo.ui.config(section, name)
699 config = repo.ui.config(section, name)
@@ -772,14 +795,14 b' def _checkunknownfiles(repo, wctx, mctx,'
772
795
773 checkunknowndirs = _unknowndirschecker()
796 checkunknowndirs = _unknowndirschecker()
774 for f, (m, args, msg) in actions.iteritems():
797 for f, (m, args, msg) in actions.iteritems():
775 if m in ('c', 'dc'):
798 if m in (ACTION_CREATED, ACTION_DELETED_CHANGED):
776 if _checkunknownfile(repo, wctx, mctx, f):
799 if _checkunknownfile(repo, wctx, mctx, f):
777 fileconflicts.add(f)
800 fileconflicts.add(f)
778 elif pathconfig and f not in wctx:
801 elif pathconfig and f not in wctx:
779 path = checkunknowndirs(repo, wctx, f)
802 path = checkunknowndirs(repo, wctx, f)
780 if path is not None:
803 if path is not None:
781 pathconflicts.add(path)
804 pathconflicts.add(path)
782 elif m == 'dg':
805 elif m == ACTION_LOCAL_DIR_RENAME_GET:
783 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
806 if _checkunknownfile(repo, wctx, mctx, f, args[0]):
784 fileconflicts.add(f)
807 fileconflicts.add(f)
785
808
@@ -791,7 +814,7 b' def _checkunknownfiles(repo, wctx, mctx,'
791 collectconflicts(unknownconflicts, unknownconfig)
814 collectconflicts(unknownconflicts, unknownconfig)
792 else:
815 else:
793 for f, (m, args, msg) in actions.iteritems():
816 for f, (m, args, msg) in actions.iteritems():
794 if m == 'cm':
817 if m == ACTION_CREATED_MERGE:
795 fl2, anc = args
818 fl2, anc = args
796 different = _checkunknownfile(repo, wctx, mctx, f)
819 different = _checkunknownfile(repo, wctx, mctx, f)
797 if repo.dirstate._ignore(f):
820 if repo.dirstate._ignore(f):
@@ -812,16 +835,16 b' def _checkunknownfiles(repo, wctx, mctx,'
812 # don't like an abort happening in the middle of
835 # don't like an abort happening in the middle of
813 # merge.update.
836 # merge.update.
814 if not different:
837 if not different:
815 actions[f] = ('g', (fl2, False), "remote created")
838 actions[f] = (ACTION_GET, (fl2, False), 'remote created')
816 elif mergeforce or config == 'abort':
839 elif mergeforce or config == 'abort':
817 actions[f] = ('m', (f, f, None, False, anc),
840 actions[f] = (ACTION_MERGE, (f, f, None, False, anc),
818 "remote differs from untracked local")
841 'remote differs from untracked local')
819 elif config == 'abort':
842 elif config == 'abort':
820 abortconflicts.add(f)
843 abortconflicts.add(f)
821 else:
844 else:
822 if config == 'warn':
845 if config == 'warn':
823 warnconflicts.add(f)
846 warnconflicts.add(f)
824 actions[f] = ('g', (fl2, True), "remote created")
847 actions[f] = (ACTION_GET, (fl2, True), 'remote created')
825
848
826 for f in sorted(abortconflicts):
849 for f in sorted(abortconflicts):
827 warn = repo.ui.warn
850 warn = repo.ui.warn
@@ -843,11 +866,11 b' def _checkunknownfiles(repo, wctx, mctx,'
843 repo.ui.warn(_("%s: replacing untracked files in directory\n") % f)
866 repo.ui.warn(_("%s: replacing untracked files in directory\n") % f)
844
867
845 for f, (m, args, msg) in actions.iteritems():
868 for f, (m, args, msg) in actions.iteritems():
846 if m == 'c':
869 if m == ACTION_CREATED:
847 backup = (f in fileconflicts or f in pathconflicts or
870 backup = (f in fileconflicts or f in pathconflicts or
848 any(p in pathconflicts for p in util.finddirs(f)))
871 any(p in pathconflicts for p in util.finddirs(f)))
849 flags, = args
872 flags, = args
850 actions[f] = ('g', (flags, backup), msg)
873 actions[f] = (ACTION_GET, (flags, backup), msg)
851
874
852 def _forgetremoved(wctx, mctx, branchmerge):
875 def _forgetremoved(wctx, mctx, branchmerge):
853 """
876 """
@@ -865,9 +888,9 b' def _forgetremoved(wctx, mctx, branchmer'
865 """
888 """
866
889
867 actions = {}
890 actions = {}
868 m = 'f'
891 m = ACTION_FORGET
869 if branchmerge:
892 if branchmerge:
870 m = 'r'
893 m = ACTION_REMOVE
871 for f in wctx.deleted():
894 for f in wctx.deleted():
872 if f not in mctx:
895 if f not in mctx:
873 actions[f] = m, None, "forget deleted"
896 actions[f] = m, None, "forget deleted"
@@ -875,7 +898,7 b' def _forgetremoved(wctx, mctx, branchmer'
875 if not branchmerge:
898 if not branchmerge:
876 for f in wctx.removed():
899 for f in wctx.removed():
877 if f not in mctx:
900 if f not in mctx:
878 actions[f] = 'f', None, "forget removed"
901 actions[f] = ACTION_FORGET, None, "forget removed"
879
902
880 return actions
903 return actions
881
904
@@ -884,19 +907,20 b' def _checkcollision(repo, wmf, actions):'
884 pmmf = set(wmf)
907 pmmf = set(wmf)
885
908
886 if actions:
909 if actions:
887 # k, dr, e and rd are no-op
910 # KEEP and EXEC are no-op
888 for m in 'a', 'am', 'f', 'g', 'cd', 'dc':
911 for m in (ACTION_ADD, ACTION_ADD_MODIFIED, ACTION_FORGET, ACTION_GET,
912 ACTION_CHANGED_DELETED, ACTION_DELETED_CHANGED):
889 for f, args, msg in actions[m]:
913 for f, args, msg in actions[m]:
890 pmmf.add(f)
914 pmmf.add(f)
891 for f, args, msg in actions['r']:
915 for f, args, msg in actions[ACTION_REMOVE]:
892 pmmf.discard(f)
916 pmmf.discard(f)
893 for f, args, msg in actions['dm']:
917 for f, args, msg in actions[ACTION_DIR_RENAME_MOVE_LOCAL]:
894 f2, flags = args
918 f2, flags = args
895 pmmf.discard(f2)
919 pmmf.discard(f2)
896 pmmf.add(f)
920 pmmf.add(f)
897 for f, args, msg in actions['dg']:
921 for f, args, msg in actions[ACTION_LOCAL_DIR_RENAME_GET]:
898 pmmf.add(f)
922 pmmf.add(f)
899 for f, args, msg in actions['m']:
923 for f, args, msg in actions[ACTION_MERGE]:
900 f1, f2, fa, move, anc = args
924 f1, f2, fa, move, anc = args
901 if move:
925 if move:
902 pmmf.discard(f1)
926 pmmf.discard(f1)
@@ -972,7 +996,8 b' def checkpathconflicts(repo, wctx, mctx,'
972 deletedfiles = set()
996 deletedfiles = set()
973
997
974 for f, (m, args, msg) in actions.items():
998 for f, (m, args, msg) in actions.items():
975 if m in ('c', 'dc', 'm', 'cm'):
999 if m in (ACTION_CREATED, ACTION_DELETED_CHANGED, ACTION_MERGE,
1000 ACTION_CREATED_MERGE):
976 # This action may create a new local file.
1001 # This action may create a new local file.
977 createdfiledirs.update(util.finddirs(f))
1002 createdfiledirs.update(util.finddirs(f))
978 if mf.hasdir(f):
1003 if mf.hasdir(f):
@@ -981,13 +1006,13 b' def checkpathconflicts(repo, wctx, mctx,'
981 # will be checked once we know what all the deleted files are.
1006 # will be checked once we know what all the deleted files are.
982 remoteconflicts.add(f)
1007 remoteconflicts.add(f)
983 # Track the names of all deleted files.
1008 # Track the names of all deleted files.
984 if m == 'r':
1009 if m == ACTION_REMOVE:
985 deletedfiles.add(f)
1010 deletedfiles.add(f)
986 if m == 'm':
1011 if m == ACTION_MERGE:
987 f1, f2, fa, move, anc = args
1012 f1, f2, fa, move, anc = args
988 if move:
1013 if move:
989 deletedfiles.add(f1)
1014 deletedfiles.add(f1)
990 if m == 'dm':
1015 if m == ACTION_DIR_RENAME_MOVE_LOCAL:
991 f2, flags = args
1016 f2, flags = args
992 deletedfiles.add(f2)
1017 deletedfiles.add(f2)
993
1018
@@ -1003,7 +1028,10 b' def checkpathconflicts(repo, wctx, mctx,'
1003 # A file is in a directory which aliases a local file.
1028 # A file is in a directory which aliases a local file.
1004 # We will need to rename the local file.
1029 # We will need to rename the local file.
1005 localconflicts.add(p)
1030 localconflicts.add(p)
1006 if p in actions and actions[p][0] in ('c', 'dc', 'm', 'cm'):
1031 if p in actions and actions[p][0] in (ACTION_CREATED,
1032 ACTION_DELETED_CHANGED,
1033 ACTION_MERGE,
1034 ACTION_CREATED_MERGE):
1007 # The file is in a directory which aliases a remote file.
1035 # The file is in a directory which aliases a remote file.
1008 # This is an internal inconsistency within the remote
1036 # This is an internal inconsistency within the remote
1009 # manifest.
1037 # manifest.
@@ -1014,8 +1042,10 b' def checkpathconflicts(repo, wctx, mctx,'
1014 if p not in deletedfiles:
1042 if p not in deletedfiles:
1015 ctxname = bytes(wctx).rstrip('+')
1043 ctxname = bytes(wctx).rstrip('+')
1016 pnew = util.safename(p, ctxname, wctx, set(actions.keys()))
1044 pnew = util.safename(p, ctxname, wctx, set(actions.keys()))
1017 actions[pnew] = ('pr', (p,), "local path conflict")
1045 actions[pnew] = (ACTION_PATH_CONFLICT_RESOLVE, (p,),
1018 actions[p] = ('p', (pnew, 'l'), "path conflict")
1046 'local path conflict')
1047 actions[p] = (ACTION_PATH_CONFLICT, (pnew, 'l'),
1048 'path conflict')
1019
1049
1020 if remoteconflicts:
1050 if remoteconflicts:
1021 # Check if all files in the conflicting directories have been removed.
1051 # Check if all files in the conflicting directories have been removed.
@@ -1024,14 +1054,16 b' def checkpathconflicts(repo, wctx, mctx,'
1024 if f not in deletedfiles:
1054 if f not in deletedfiles:
1025 m, args, msg = actions[p]
1055 m, args, msg = actions[p]
1026 pnew = util.safename(p, ctxname, wctx, set(actions.keys()))
1056 pnew = util.safename(p, ctxname, wctx, set(actions.keys()))
1027 if m in ('dc', 'm'):
1057 if m in (ACTION_DELETED_CHANGED, ACTION_MERGE):
1028 # Action was merge, just update target.
1058 # Action was merge, just update target.
1029 actions[pnew] = (m, args, msg)
1059 actions[pnew] = (m, args, msg)
1030 else:
1060 else:
1031 # Action was create, change to renamed get action.
1061 # Action was create, change to renamed get action.
1032 fl = args[0]
1062 fl = args[0]
1033 actions[pnew] = ('dg', (p, fl), "remote path conflict")
1063 actions[pnew] = (ACTION_LOCAL_DIR_RENAME_GET, (p, fl),
1034 actions[p] = ('p', (pnew, 'r'), "path conflict")
1064 'remote path conflict')
1065 actions[p] = (ACTION_PATH_CONFLICT, (pnew, ACTION_REMOVE),
1066 'path conflict')
1035 remoteconflicts.remove(p)
1067 remoteconflicts.remove(p)
1036 break
1068 break
1037
1069
@@ -1109,77 +1141,80 b' def manifestmerge(repo, wctx, p2, pa, br'
1109 if f not in ma:
1141 if f not in ma:
1110 fa = copy.get(f, None)
1142 fa = copy.get(f, None)
1111 if fa is not None:
1143 if fa is not None:
1112 actions[f] = ('m', (f, f, fa, False, pa.node()),
1144 actions[f] = (ACTION_MERGE, (f, f, fa, False, pa.node()),
1113 "both renamed from " + fa)
1145 'both renamed from %s' % fa)
1114 else:
1146 else:
1115 actions[f] = ('m', (f, f, None, False, pa.node()),
1147 actions[f] = (ACTION_MERGE, (f, f, None, False, pa.node()),
1116 "both created")
1148 'both created')
1117 else:
1149 else:
1118 a = ma[f]
1150 a = ma[f]
1119 fla = ma.flags(f)
1151 fla = ma.flags(f)
1120 nol = 'l' not in fl1 + fl2 + fla
1152 nol = 'l' not in fl1 + fl2 + fla
1121 if n2 == a and fl2 == fla:
1153 if n2 == a and fl2 == fla:
1122 actions[f] = ('k', (), "remote unchanged")
1154 actions[f] = (ACTION_KEEP, (), 'remote unchanged')
1123 elif n1 == a and fl1 == fla: # local unchanged - use remote
1155 elif n1 == a and fl1 == fla: # local unchanged - use remote
1124 if n1 == n2: # optimization: keep local content
1156 if n1 == n2: # optimization: keep local content
1125 actions[f] = ('e', (fl2,), "update permissions")
1157 actions[f] = (ACTION_EXEC, (fl2,), 'update permissions')
1126 else:
1158 else:
1127 actions[f] = ('g', (fl2, False), "remote is newer")
1159 actions[f] = (ACTION_GET, (fl2, False),
1160 'remote is newer')
1128 elif nol and n2 == a: # remote only changed 'x'
1161 elif nol and n2 == a: # remote only changed 'x'
1129 actions[f] = ('e', (fl2,), "update permissions")
1162 actions[f] = (ACTION_EXEC, (fl2,), 'update permissions')
1130 elif nol and n1 == a: # local only changed 'x'
1163 elif nol and n1 == a: # local only changed 'x'
1131 actions[f] = ('g', (fl1, False), "remote is newer")
1164 actions[f] = (ACTION_GET, (fl1, False), 'remote is newer')
1132 else: # both changed something
1165 else: # both changed something
1133 actions[f] = ('m', (f, f, f, False, pa.node()),
1166 actions[f] = (ACTION_MERGE, (f, f, f, False, pa.node()),
1134 "versions differ")
1167 'versions differ')
1135 elif n1: # file exists only on local side
1168 elif n1: # file exists only on local side
1136 if f in copied:
1169 if f in copied:
1137 pass # we'll deal with it on m2 side
1170 pass # we'll deal with it on m2 side
1138 elif f in movewithdir: # directory rename, move local
1171 elif f in movewithdir: # directory rename, move local
1139 f2 = movewithdir[f]
1172 f2 = movewithdir[f]
1140 if f2 in m2:
1173 if f2 in m2:
1141 actions[f2] = ('m', (f, f2, None, True, pa.node()),
1174 actions[f2] = (ACTION_MERGE, (f, f2, None, True, pa.node()),
1142 "remote directory rename, both created")
1175 'remote directory rename, both created')
1143 else:
1176 else:
1144 actions[f2] = ('dm', (f, fl1),
1177 actions[f2] = (ACTION_DIR_RENAME_MOVE_LOCAL, (f, fl1),
1145 "remote directory rename - move from " + f)
1178 'remote directory rename - move from %s' % f)
1146 elif f in copy:
1179 elif f in copy:
1147 f2 = copy[f]
1180 f2 = copy[f]
1148 actions[f] = ('m', (f, f2, f2, False, pa.node()),
1181 actions[f] = (ACTION_MERGE, (f, f2, f2, False, pa.node()),
1149 "local copied/moved from " + f2)
1182 'local copied/moved from %s' % f2)
1150 elif f in ma: # clean, a different, no remote
1183 elif f in ma: # clean, a different, no remote
1151 if n1 != ma[f]:
1184 if n1 != ma[f]:
1152 if acceptremote:
1185 if acceptremote:
1153 actions[f] = ('r', None, "remote delete")
1186 actions[f] = (ACTION_REMOVE, None, 'remote delete')
1154 else:
1187 else:
1155 actions[f] = ('cd', (f, None, f, False, pa.node()),
1188 actions[f] = (ACTION_CHANGED_DELETED,
1156 "prompt changed/deleted")
1189 (f, None, f, False, pa.node()),
1190 'prompt changed/deleted')
1157 elif n1 == addednodeid:
1191 elif n1 == addednodeid:
1158 # This extra 'a' is added by working copy manifest to mark
1192 # This extra 'a' is added by working copy manifest to mark
1159 # the file as locally added. We should forget it instead of
1193 # the file as locally added. We should forget it instead of
1160 # deleting it.
1194 # deleting it.
1161 actions[f] = ('f', None, "remote deleted")
1195 actions[f] = (ACTION_FORGET, None, 'remote deleted')
1162 else:
1196 else:
1163 actions[f] = ('r', None, "other deleted")
1197 actions[f] = (ACTION_REMOVE, None, 'other deleted')
1164 elif n2: # file exists only on remote side
1198 elif n2: # file exists only on remote side
1165 if f in copied:
1199 if f in copied:
1166 pass # we'll deal with it on m1 side
1200 pass # we'll deal with it on m1 side
1167 elif f in movewithdir:
1201 elif f in movewithdir:
1168 f2 = movewithdir[f]
1202 f2 = movewithdir[f]
1169 if f2 in m1:
1203 if f2 in m1:
1170 actions[f2] = ('m', (f2, f, None, False, pa.node()),
1204 actions[f2] = (ACTION_MERGE,
1171 "local directory rename, both created")
1205 (f2, f, None, False, pa.node()),
1206 'local directory rename, both created')
1172 else:
1207 else:
1173 actions[f2] = ('dg', (f, fl2),
1208 actions[f2] = (ACTION_LOCAL_DIR_RENAME_GET, (f, fl2),
1174 "local directory rename - get from " + f)
1209 'local directory rename - get from %s' % f)
1175 elif f in copy:
1210 elif f in copy:
1176 f2 = copy[f]
1211 f2 = copy[f]
1177 if f2 in m2:
1212 if f2 in m2:
1178 actions[f] = ('m', (f2, f, f2, False, pa.node()),
1213 actions[f] = (ACTION_MERGE, (f2, f, f2, False, pa.node()),
1179 "remote copied from " + f2)
1214 'remote copied from %s' % f2)
1180 else:
1215 else:
1181 actions[f] = ('m', (f2, f, f2, True, pa.node()),
1216 actions[f] = (ACTION_MERGE, (f2, f, f2, True, pa.node()),
1182 "remote moved from " + f2)
1217 'remote moved from %s' % f2)
1183 elif f not in ma:
1218 elif f not in ma:
1184 # local unknown, remote created: the logic is described by the
1219 # local unknown, remote created: the logic is described by the
1185 # following table:
1220 # following table:
@@ -1193,12 +1228,12 b' def manifestmerge(repo, wctx, p2, pa, br'
1193 # Checking whether the files are different is expensive, so we
1228 # Checking whether the files are different is expensive, so we
1194 # don't do that when we can avoid it.
1229 # don't do that when we can avoid it.
1195 if not force:
1230 if not force:
1196 actions[f] = ('c', (fl2,), "remote created")
1231 actions[f] = (ACTION_CREATED, (fl2,), 'remote created')
1197 elif not branchmerge:
1232 elif not branchmerge:
1198 actions[f] = ('c', (fl2,), "remote created")
1233 actions[f] = (ACTION_CREATED, (fl2,), 'remote created')
1199 else:
1234 else:
1200 actions[f] = ('cm', (fl2, pa.node()),
1235 actions[f] = (ACTION_CREATED_MERGE, (fl2, pa.node()),
1201 "remote created, get or merge")
1236 'remote created, get or merge')
1202 elif n2 != ma[f]:
1237 elif n2 != ma[f]:
1203 df = None
1238 df = None
1204 for d in dirmove:
1239 for d in dirmove:
@@ -1207,13 +1242,15 b' def manifestmerge(repo, wctx, p2, pa, br'
1207 df = dirmove[d] + f[len(d):]
1242 df = dirmove[d] + f[len(d):]
1208 break
1243 break
1209 if df is not None and df in m1:
1244 if df is not None and df in m1:
1210 actions[df] = ('m', (df, f, f, False, pa.node()),
1245 actions[df] = (ACTION_MERGE, (df, f, f, False, pa.node()),
1211 "local directory rename - respect move from " + f)
1246 'local directory rename - respect move '
1247 'from %s' % f)
1212 elif acceptremote:
1248 elif acceptremote:
1213 actions[f] = ('c', (fl2,), "remote recreating")
1249 actions[f] = (ACTION_CREATED, (fl2,), 'remote recreating')
1214 else:
1250 else:
1215 actions[f] = ('dc', (None, f, f, False, pa.node()),
1251 actions[f] = (ACTION_DELETED_CHANGED,
1216 "prompt deleted/changed")
1252 (None, f, f, False, pa.node()),
1253 'prompt deleted/changed')
1217
1254
1218 if repo.ui.configbool('experimental', 'merge.checkpathconflicts'):
1255 if repo.ui.configbool('experimental', 'merge.checkpathconflicts'):
1219 # If we are merging, look for path conflicts.
1256 # If we are merging, look for path conflicts.
@@ -1227,10 +1264,12 b' def _resolvetrivial(repo, wctx, mctx, an'
1227 # We force a copy of actions.items() because we're going to mutate
1264 # We force a copy of actions.items() because we're going to mutate
1228 # actions as we resolve trivial conflicts.
1265 # actions as we resolve trivial conflicts.
1229 for f, (m, args, msg) in list(actions.items()):
1266 for f, (m, args, msg) in list(actions.items()):
1230 if m == 'cd' and f in ancestor and not wctx[f].cmp(ancestor[f]):
1267 if (m == ACTION_CHANGED_DELETED and f in ancestor
1268 and not wctx[f].cmp(ancestor[f])):
1231 # local did change but ended up with same content
1269 # local did change but ended up with same content
1232 actions[f] = 'r', None, "prompt same"
1270 actions[f] = ACTION_REMOVE, None, 'prompt same'
1233 elif m == 'dc' and f in ancestor and not mctx[f].cmp(ancestor[f]):
1271 elif (m == ACTION_DELETED_CHANGED and f in ancestor
1272 and not mctx[f].cmp(ancestor[f])):
1234 # remote did change but ended up with same content
1273 # remote did change but ended up with same content
1235 del actions[f] # don't get = keep local deleted
1274 del actions[f] # don't get = keep local deleted
1236
1275
@@ -1294,18 +1333,18 b' def calculateupdates(repo, wctx, mctx, a'
1294 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1333 if all(a == l[0] for a in l[1:]): # len(bids) is > 1
1295 repo.ui.note(_(" %s: consensus for %s\n") % (f, m))
1334 repo.ui.note(_(" %s: consensus for %s\n") % (f, m))
1296 actions[f] = l[0]
1335 actions[f] = l[0]
1297 if m == 'dm':
1336 if m == ACTION_DIR_RENAME_MOVE_LOCAL:
1298 dms.append(f)
1337 dms.append(f)
1299 continue
1338 continue
1300 # If keep is an option, just do it.
1339 # If keep is an option, just do it.
1301 if 'k' in bids:
1340 if ACTION_KEEP in bids:
1302 repo.ui.note(_(" %s: picking 'keep' action\n") % f)
1341 repo.ui.note(_(" %s: picking 'keep' action\n") % f)
1303 actions[f] = bids['k'][0]
1342 actions[f] = bids[ACTION_KEEP][0]
1304 continue
1343 continue
1305 # If there are gets and they all agree [how could they not?], do it.
1344 # If there are gets and they all agree [how could they not?], do it.
1306 if 'g' in bids:
1345 if ACTION_GET in bids:
1307 ga0 = bids['g'][0]
1346 ga0 = bids[ACTION_GET][0]
1308 if all(a == ga0 for a in bids['g'][1:]):
1347 if all(a == ga0 for a in bids[ACTION_GET][1:]):
1309 repo.ui.note(_(" %s: picking 'get' action\n") % f)
1348 repo.ui.note(_(" %s: picking 'get' action\n") % f)
1310 actions[f] = ga0
1349 actions[f] = ga0
1311 continue
1350 continue
@@ -1320,14 +1359,14 b' def calculateupdates(repo, wctx, mctx, a'
1320 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
1359 repo.ui.warn(_(' %s: ambiguous merge - picked %s action\n') %
1321 (f, m))
1360 (f, m))
1322 actions[f] = l[0]
1361 actions[f] = l[0]
1323 if m == 'dm':
1362 if m == ACTION_DIR_RENAME_MOVE_LOCAL:
1324 dms.append(f)
1363 dms.append(f)
1325 continue
1364 continue
1326 # Work around 'dm' that can cause multiple actions for the same file
1365 # Work around 'dm' that can cause multiple actions for the same file
1327 for f in dms:
1366 for f in dms:
1328 dm, (f0, flags), msg = actions[f]
1367 dm, (f0, flags), msg = actions[f]
1329 assert dm == 'dm', dm
1368 assert dm == ACTION_DIR_RENAME_MOVE_LOCAL, dm
1330 if f0 in actions and actions[f0][0] == 'r':
1369 if f0 in actions and actions[f0][0] == ACTION_REMOVE:
1331 # We have one bid for removing a file and another for moving it.
1370 # We have one bid for removing a file and another for moving it.
1332 # These two could be merged as first move and then delete ...
1371 # These two could be merged as first move and then delete ...
1333 # but instead drop moving and just delete.
1372 # but instead drop moving and just delete.
@@ -1432,7 +1471,8 b' def _prefetchfiles(repo, ctx, actions):'
1432 # Skipping 'a', 'am', 'f', 'r', 'dm', 'e', 'k', 'p' and 'pr', because they
1471 # Skipping 'a', 'am', 'f', 'r', 'dm', 'e', 'k', 'p' and 'pr', because they
1433 # don't touch the context to be merged in. 'cd' is skipped, because
1472 # don't touch the context to be merged in. 'cd' is skipped, because
1434 # changed/deleted never resolves to something from the remote side.
1473 # changed/deleted never resolves to something from the remote side.
1435 oplist = [actions[a] for a in 'g dc dg m'.split()]
1474 oplist = [actions[a] for a in (ACTION_GET, ACTION_DELETED_CHANGED,
1475 ACTION_LOCAL_DIR_RENAME_GET, ACTION_MERGE)]
1436 prefetch = scmutil.fileprefetchhooks
1476 prefetch = scmutil.fileprefetchhooks
1437 prefetch(repo, ctx, [f for sublist in oplist for f, args, msg in sublist])
1477 prefetch(repo, ctx, [f for sublist in oplist for f, args, msg in sublist])
1438
1478
@@ -1479,9 +1519,9 b' def applyupdates(repo, actions, wctx, mc'
1479 l.sort()
1519 l.sort()
1480
1520
1481 # 'cd' and 'dc' actions are treated like other merge conflicts
1521 # 'cd' and 'dc' actions are treated like other merge conflicts
1482 mergeactions = sorted(actions['cd'])
1522 mergeactions = sorted(actions[ACTION_CHANGED_DELETED])
1483 mergeactions.extend(sorted(actions['dc']))
1523 mergeactions.extend(sorted(actions[ACTION_DELETED_CHANGED]))
1484 mergeactions.extend(actions['m'])
1524 mergeactions.extend(actions[ACTION_MERGE])
1485 for f, args, msg in mergeactions:
1525 for f, args, msg in mergeactions:
1486 f1, f2, fa, move, anc = args
1526 f1, f2, fa, move, anc = args
1487 if f == '.hgsubstate': # merged internally
1527 if f == '.hgsubstate': # merged internally
@@ -1516,14 +1556,15 b' def applyupdates(repo, actions, wctx, mc'
1516 wctx[f].audit()
1556 wctx[f].audit()
1517 wctx[f].remove()
1557 wctx[f].remove()
1518
1558
1519 numupdates = sum(len(l) for m, l in actions.items() if m != 'k')
1559 numupdates = sum(len(l) for m, l in actions.items()
1560 if m != ACTION_KEEP)
1520 z = 0
1561 z = 0
1521
1562
1522 if [a for a in actions['r'] if a[0] == '.hgsubstate']:
1563 if [a for a in actions[ACTION_REMOVE] if a[0] == '.hgsubstate']:
1523 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1564 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1524
1565
1525 # record path conflicts
1566 # record path conflicts
1526 for f, args, msg in actions['p']:
1567 for f, args, msg in actions[ACTION_PATH_CONFLICT]:
1527 f1, fo = args
1568 f1, fo = args
1528 s = repo.ui.status
1569 s = repo.ui.status
1529 s(_("%s: path conflict - a file or link has the same name as a "
1570 s(_("%s: path conflict - a file or link has the same name as a "
@@ -1543,14 +1584,14 b' def applyupdates(repo, actions, wctx, mc'
1543
1584
1544 # remove in parallel (must come before resolving path conflicts and getting)
1585 # remove in parallel (must come before resolving path conflicts and getting)
1545 prog = worker.worker(repo.ui, cost, batchremove, (repo, wctx),
1586 prog = worker.worker(repo.ui, cost, batchremove, (repo, wctx),
1546 actions['r'])
1587 actions[ACTION_REMOVE])
1547 for i, item in prog:
1588 for i, item in prog:
1548 z += i
1589 z += i
1549 progress(_updating, z, item=item, total=numupdates, unit=_files)
1590 progress(_updating, z, item=item, total=numupdates, unit=_files)
1550 removed = len(actions['r'])
1591 removed = len(actions[ACTION_REMOVE])
1551
1592
1552 # resolve path conflicts (must come before getting)
1593 # resolve path conflicts (must come before getting)
1553 for f, args, msg in actions['pr']:
1594 for f, args, msg in actions[ACTION_PATH_CONFLICT_RESOLVE]:
1554 repo.ui.debug(" %s: %s -> pr\n" % (f, msg))
1595 repo.ui.debug(" %s: %s -> pr\n" % (f, msg))
1555 f0, = args
1596 f0, = args
1556 if wctx[f0].lexists():
1597 if wctx[f0].lexists():
@@ -1563,40 +1604,40 b' def applyupdates(repo, actions, wctx, mc'
1563
1604
1564 # get in parallel
1605 # get in parallel
1565 prog = worker.worker(repo.ui, cost, batchget, (repo, mctx, wctx),
1606 prog = worker.worker(repo.ui, cost, batchget, (repo, mctx, wctx),
1566 actions['g'])
1607 actions[ACTION_GET])
1567 for i, item in prog:
1608 for i, item in prog:
1568 z += i
1609 z += i
1569 progress(_updating, z, item=item, total=numupdates, unit=_files)
1610 progress(_updating, z, item=item, total=numupdates, unit=_files)
1570 updated = len(actions['g'])
1611 updated = len(actions[ACTION_GET])
1571
1612
1572 if [a for a in actions['g'] if a[0] == '.hgsubstate']:
1613 if [a for a in actions[ACTION_GET] if a[0] == '.hgsubstate']:
1573 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1614 subrepoutil.submerge(repo, wctx, mctx, wctx, overwrite, labels)
1574
1615
1575 # forget (manifest only, just log it) (must come first)
1616 # forget (manifest only, just log it) (must come first)
1576 for f, args, msg in actions['f']:
1617 for f, args, msg in actions[ACTION_FORGET]:
1577 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
1618 repo.ui.debug(" %s: %s -> f\n" % (f, msg))
1578 z += 1
1619 z += 1
1579 progress(_updating, z, item=f, total=numupdates, unit=_files)
1620 progress(_updating, z, item=f, total=numupdates, unit=_files)
1580
1621
1581 # re-add (manifest only, just log it)
1622 # re-add (manifest only, just log it)
1582 for f, args, msg in actions['a']:
1623 for f, args, msg in actions[ACTION_ADD]:
1583 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
1624 repo.ui.debug(" %s: %s -> a\n" % (f, msg))
1584 z += 1
1625 z += 1
1585 progress(_updating, z, item=f, total=numupdates, unit=_files)
1626 progress(_updating, z, item=f, total=numupdates, unit=_files)
1586
1627
1587 # re-add/mark as modified (manifest only, just log it)
1628 # re-add/mark as modified (manifest only, just log it)
1588 for f, args, msg in actions['am']:
1629 for f, args, msg in actions[ACTION_ADD_MODIFIED]:
1589 repo.ui.debug(" %s: %s -> am\n" % (f, msg))
1630 repo.ui.debug(" %s: %s -> am\n" % (f, msg))
1590 z += 1
1631 z += 1
1591 progress(_updating, z, item=f, total=numupdates, unit=_files)
1632 progress(_updating, z, item=f, total=numupdates, unit=_files)
1592
1633
1593 # keep (noop, just log it)
1634 # keep (noop, just log it)
1594 for f, args, msg in actions['k']:
1635 for f, args, msg in actions[ACTION_KEEP]:
1595 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
1636 repo.ui.debug(" %s: %s -> k\n" % (f, msg))
1596 # no progress
1637 # no progress
1597
1638
1598 # directory rename, move local
1639 # directory rename, move local
1599 for f, args, msg in actions['dm']:
1640 for f, args, msg in actions[ACTION_DIR_RENAME_MOVE_LOCAL]:
1600 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
1641 repo.ui.debug(" %s: %s -> dm\n" % (f, msg))
1601 z += 1
1642 z += 1
1602 progress(_updating, z, item=f, total=numupdates, unit=_files)
1643 progress(_updating, z, item=f, total=numupdates, unit=_files)
@@ -1608,7 +1649,7 b' def applyupdates(repo, actions, wctx, mc'
1608 updated += 1
1649 updated += 1
1609
1650
1610 # local directory rename, get
1651 # local directory rename, get
1611 for f, args, msg in actions['dg']:
1652 for f, args, msg in actions[ACTION_LOCAL_DIR_RENAME_GET]:
1612 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
1653 repo.ui.debug(" %s: %s -> dg\n" % (f, msg))
1613 z += 1
1654 z += 1
1614 progress(_updating, z, item=f, total=numupdates, unit=_files)
1655 progress(_updating, z, item=f, total=numupdates, unit=_files)
@@ -1618,7 +1659,7 b' def applyupdates(repo, actions, wctx, mc'
1618 updated += 1
1659 updated += 1
1619
1660
1620 # exec
1661 # exec
1621 for f, args, msg in actions['e']:
1662 for f, args, msg in actions[ACTION_EXEC]:
1622 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
1663 repo.ui.debug(" %s: %s -> e\n" % (f, msg))
1623 z += 1
1664 z += 1
1624 progress(_updating, z, item=f, total=numupdates, unit=_files)
1665 progress(_updating, z, item=f, total=numupdates, unit=_files)
@@ -1696,17 +1737,17 b' def applyupdates(repo, actions, wctx, mc'
1696
1737
1697 extraactions = ms.actions()
1738 extraactions = ms.actions()
1698 if extraactions:
1739 if extraactions:
1699 mfiles = set(a[0] for a in actions['m'])
1740 mfiles = set(a[0] for a in actions[ACTION_MERGE])
1700 for k, acts in extraactions.iteritems():
1741 for k, acts in extraactions.iteritems():
1701 actions[k].extend(acts)
1742 actions[k].extend(acts)
1702 # Remove these files from actions['m'] as well. This is important
1743 # Remove these files from actions[ACTION_MERGE] as well. This is
1703 # because in recordupdates, files in actions['m'] are processed
1744 # important because in recordupdates, files in actions[ACTION_MERGE]
1704 # after files in other actions, and the merge driver might add
1745 # are processed after files in other actions, and the merge driver
1705 # files to those actions via extraactions above. This can lead to a
1746 # might add files to those actions via extraactions above. This can
1706 # file being recorded twice, with poor results. This is especially
1747 # lead to a file being recorded twice, with poor results. This is
1707 # problematic for actions['r'] (currently only possible with the
1748 # especially problematic for actions[ACTION_REMOVE] (currently only
1708 # merge driver in the initial merge process; interrupted merges
1749 # possible with the merge driver in the initial merge process;
1709 # don't go through this flow).
1750 # interrupted merges don't go through this flow).
1710 #
1751 #
1711 # The real fix here is to have indexes by both file and action so
1752 # The real fix here is to have indexes by both file and action so
1712 # that when the action for a file is changed it is automatically
1753 # that when the action for a file is changed it is automatically
@@ -1717,7 +1758,8 b' def applyupdates(repo, actions, wctx, mc'
1717 # those lists aren't consulted again.
1758 # those lists aren't consulted again.
1718 mfiles.difference_update(a[0] for a in acts)
1759 mfiles.difference_update(a[0] for a in acts)
1719
1760
1720 actions['m'] = [a for a in actions['m'] if a[0] in mfiles]
1761 actions[ACTION_MERGE] = [a for a in actions[ACTION_MERGE]
1762 if a[0] in mfiles]
1721
1763
1722 progress(_updating, None, total=numupdates, unit=_files)
1764 progress(_updating, None, total=numupdates, unit=_files)
1723 return updateresult(updated, merged, removed, unresolved)
1765 return updateresult(updated, merged, removed, unresolved)
@@ -1725,18 +1767,18 b' def applyupdates(repo, actions, wctx, mc'
1725 def recordupdates(repo, actions, branchmerge):
1767 def recordupdates(repo, actions, branchmerge):
1726 "record merge actions to the dirstate"
1768 "record merge actions to the dirstate"
1727 # remove (must come first)
1769 # remove (must come first)
1728 for f, args, msg in actions.get('r', []):
1770 for f, args, msg in actions.get(ACTION_REMOVE, []):
1729 if branchmerge:
1771 if branchmerge:
1730 repo.dirstate.remove(f)
1772 repo.dirstate.remove(f)
1731 else:
1773 else:
1732 repo.dirstate.drop(f)
1774 repo.dirstate.drop(f)
1733
1775
1734 # forget (must come first)
1776 # forget (must come first)
1735 for f, args, msg in actions.get('f', []):
1777 for f, args, msg in actions.get(ACTION_FORGET, []):
1736 repo.dirstate.drop(f)
1778 repo.dirstate.drop(f)
1737
1779
1738 # resolve path conflicts
1780 # resolve path conflicts
1739 for f, args, msg in actions.get('pr', []):
1781 for f, args, msg in actions.get(ACTION_PATH_CONFLICT_RESOLVE, []):
1740 f0, = args
1782 f0, = args
1741 origf0 = repo.dirstate.copied(f0) or f0
1783 origf0 = repo.dirstate.copied(f0) or f0
1742 repo.dirstate.add(f)
1784 repo.dirstate.add(f)
@@ -1747,33 +1789,33 b' def recordupdates(repo, actions, branchm'
1747 repo.dirstate.drop(f0)
1789 repo.dirstate.drop(f0)
1748
1790
1749 # re-add
1791 # re-add
1750 for f, args, msg in actions.get('a', []):
1792 for f, args, msg in actions.get(ACTION_ADD, []):
1751 repo.dirstate.add(f)
1793 repo.dirstate.add(f)
1752
1794
1753 # re-add/mark as modified
1795 # re-add/mark as modified
1754 for f, args, msg in actions.get('am', []):
1796 for f, args, msg in actions.get(ACTION_ADD_MODIFIED, []):
1755 if branchmerge:
1797 if branchmerge:
1756 repo.dirstate.normallookup(f)
1798 repo.dirstate.normallookup(f)
1757 else:
1799 else:
1758 repo.dirstate.add(f)
1800 repo.dirstate.add(f)
1759
1801
1760 # exec change
1802 # exec change
1761 for f, args, msg in actions.get('e', []):
1803 for f, args, msg in actions.get(ACTION_EXEC, []):
1762 repo.dirstate.normallookup(f)
1804 repo.dirstate.normallookup(f)
1763
1805
1764 # keep
1806 # keep
1765 for f, args, msg in actions.get('k', []):
1807 for f, args, msg in actions.get(ACTION_KEEP, []):
1766 pass
1808 pass
1767
1809
1768 # get
1810 # get
1769 for f, args, msg in actions.get('g', []):
1811 for f, args, msg in actions.get(ACTION_GET, []):
1770 if branchmerge:
1812 if branchmerge:
1771 repo.dirstate.otherparent(f)
1813 repo.dirstate.otherparent(f)
1772 else:
1814 else:
1773 repo.dirstate.normal(f)
1815 repo.dirstate.normal(f)
1774
1816
1775 # merge
1817 # merge
1776 for f, args, msg in actions.get('m', []):
1818 for f, args, msg in actions.get(ACTION_MERGE, []):
1777 f1, f2, fa, move, anc = args
1819 f1, f2, fa, move, anc = args
1778 if branchmerge:
1820 if branchmerge:
1779 # We've done a branch merge, mark this file as merged
1821 # We've done a branch merge, mark this file as merged
@@ -1798,7 +1840,7 b' def recordupdates(repo, actions, branchm'
1798 repo.dirstate.drop(f1)
1840 repo.dirstate.drop(f1)
1799
1841
1800 # directory rename, move local
1842 # directory rename, move local
1801 for f, args, msg in actions.get('dm', []):
1843 for f, args, msg in actions.get(ACTION_DIR_RENAME_MOVE_LOCAL, []):
1802 f0, flag = args
1844 f0, flag = args
1803 if branchmerge:
1845 if branchmerge:
1804 repo.dirstate.add(f)
1846 repo.dirstate.add(f)
@@ -1809,7 +1851,7 b' def recordupdates(repo, actions, branchm'
1809 repo.dirstate.drop(f0)
1851 repo.dirstate.drop(f0)
1810
1852
1811 # directory rename, get
1853 # directory rename, get
1812 for f, args, msg in actions.get('dg', []):
1854 for f, args, msg in actions.get(ACTION_LOCAL_DIR_RENAME_GET, []):
1813 f0, flag = args
1855 f0, flag = args
1814 if branchmerge:
1856 if branchmerge:
1815 repo.dirstate.add(f)
1857 repo.dirstate.add(f)
@@ -1982,7 +2024,8 b' def update(repo, node, branchmerge, forc'
1982
2024
1983 if updatecheck == 'noconflict':
2025 if updatecheck == 'noconflict':
1984 for f, (m, args, msg) in actionbyfile.iteritems():
2026 for f, (m, args, msg) in actionbyfile.iteritems():
1985 if m not in ('g', 'k', 'e', 'r', 'pr'):
2027 if m not in (ACTION_GET, ACTION_KEEP, ACTION_EXEC,
2028 ACTION_REMOVE, ACTION_PATH_CONFLICT_RESOLVE):
1986 msg = _("conflicting changes")
2029 msg = _("conflicting changes")
1987 hint = _("commit or update --clean to discard changes")
2030 hint = _("commit or update --clean to discard changes")
1988 raise error.Abort(msg, hint=hint)
2031 raise error.Abort(msg, hint=hint)
@@ -1995,30 +2038,45 b' def update(repo, node, branchmerge, forc'
1995 m, args, msg = actionbyfile[f]
2038 m, args, msg = actionbyfile[f]
1996 prompts = filemerge.partextras(labels)
2039 prompts = filemerge.partextras(labels)
1997 prompts['f'] = f
2040 prompts['f'] = f
1998 if m == 'cd':
2041 if m == ACTION_CHANGED_DELETED:
1999 if repo.ui.promptchoice(
2042 if repo.ui.promptchoice(
2000 _("local%(l)s changed %(f)s which other%(o)s deleted\n"
2043 _("local%(l)s changed %(f)s which other%(o)s deleted\n"
2001 "use (c)hanged version or (d)elete?"
2044 "use (c)hanged version or (d)elete?"
2002 "$$ &Changed $$ &Delete") % prompts, 0):
2045 "$$ &Changed $$ &Delete") % prompts, 0):
2003 actionbyfile[f] = ('r', None, "prompt delete")
2046 actionbyfile[f] = (ACTION_REMOVE, None, 'prompt delete')
2004 elif f in p1:
2047 elif f in p1:
2005 actionbyfile[f] = ('am', None, "prompt keep")
2048 actionbyfile[f] = (ACTION_ADD_MODIFIED, None, 'prompt keep')
2006 else:
2049 else:
2007 actionbyfile[f] = ('a', None, "prompt keep")
2050 actionbyfile[f] = (ACTION_ADD, None, 'prompt keep')
2008 elif m == 'dc':
2051 elif m == ACTION_DELETED_CHANGED:
2009 f1, f2, fa, move, anc = args
2052 f1, f2, fa, move, anc = args
2010 flags = p2[f2].flags()
2053 flags = p2[f2].flags()
2011 if repo.ui.promptchoice(
2054 if repo.ui.promptchoice(
2012 _("other%(o)s changed %(f)s which local%(l)s deleted\n"
2055 _("other%(o)s changed %(f)s which local%(l)s deleted\n"
2013 "use (c)hanged version or leave (d)eleted?"
2056 "use (c)hanged version or leave (d)eleted?"
2014 "$$ &Changed $$ &Deleted") % prompts, 0) == 0:
2057 "$$ &Changed $$ &Deleted") % prompts, 0) == 0:
2015 actionbyfile[f] = ('g', (flags, False), "prompt recreating")
2058 actionbyfile[f] = (ACTION_GET, (flags, False),
2059 'prompt recreating')
2016 else:
2060 else:
2017 del actionbyfile[f]
2061 del actionbyfile[f]
2018
2062
2019 # Convert to dictionary-of-lists format
2063 # Convert to dictionary-of-lists format
2020 actions = dict((m, [])
2064 actions = dict((m, [])
2021 for m in 'a am f g cd dc r dm dg m e k p pr'.split())
2065 for m in (
2066 ACTION_ADD,
2067 ACTION_ADD_MODIFIED,
2068 ACTION_FORGET,
2069 ACTION_GET,
2070 ACTION_CHANGED_DELETED,
2071 ACTION_DELETED_CHANGED,
2072 ACTION_REMOVE,
2073 ACTION_DIR_RENAME_MOVE_LOCAL,
2074 ACTION_LOCAL_DIR_RENAME_GET,
2075 ACTION_MERGE,
2076 ACTION_EXEC,
2077 ACTION_KEEP,
2078 ACTION_PATH_CONFLICT,
2079 ACTION_PATH_CONFLICT_RESOLVE))
2022 for f, (m, args, msg) in actionbyfile.iteritems():
2080 for f, (m, args, msg) in actionbyfile.iteritems():
2023 if m not in actions:
2081 if m not in actions:
2024 actions[m] = []
2082 actions[m] = []
@@ -2081,7 +2139,7 b' def update(repo, node, branchmerge, forc'
2081 if (fsmonitorwarning
2139 if (fsmonitorwarning
2082 and not fsmonitorenabled
2140 and not fsmonitorenabled
2083 and p1.node() == nullid
2141 and p1.node() == nullid
2084 and len(actions['g']) >= fsmonitorthreshold
2142 and len(actions[ACTION_GET]) >= fsmonitorthreshold
2085 and pycompat.sysplatform.startswith(('linux', 'darwin'))):
2143 and pycompat.sysplatform.startswith(('linux', 'darwin'))):
2086 repo.ui.warn(
2144 repo.ui.warn(
2087 _('(warning: large working directory being used without '
2145 _('(warning: large working directory being used without '
General Comments 0
You need to be logged in to leave comments. Login now