##// END OF EJS Templates
merge: pull manifest checks and updates into separate functions
Matt Mackall -
r3107:3bd05ad6 default
parent child Browse files
Show More
@@ -52,13 +52,67 b' def merge3(repo, fn, my, other, p1, p2):'
52 os.unlink(c)
52 os.unlink(c)
53 return r
53 return r
54
54
55 def manifestmerge(ui, m1, m2, ma, overwrite, backwards):
55 def checkunknown(repo, m2, status):
56 """
57 check for collisions between unknown files and files in m2
58 """
59 modified, added, removed, deleted, unknown = status[:5]
60 for f in unknown:
61 if f in m2:
62 if repo.file(f).cmp(m2[f], repo.wread(f)):
63 raise util.Abort(_("'%s' already exists in the working"
64 " dir and differs from remote") % f)
65
66 def workingmanifest(repo, man, status):
67 """
68 Update manifest to correspond to the working directory
69 """
70
71 modified, added, removed, deleted, unknown = status[:5]
72 for i,l in (("a", added), ("m", modified), ("u", unknown)):
73 for f in l:
74 man[f] = man.get(f, nullid) + i
75 man.set(f, util.is_exec(repo.wjoin(f), man.execf(f)))
76
77 for f in deleted + removed:
78 del man[f]
79
80 return man
81
82 def forgetremoved(m2, status):
83 """
84 Forget removed files
85
86 If we're jumping between revisions (as opposed to merging), and if
87 neither the working directory nor the target rev has the file,
88 then we need to remove it from the dirstate, to prevent the
89 dirstate from listing the file when it is no longer in the
90 manifest.
91 """
92
93 modified, added, removed, deleted, unknown = status[:5]
94 action = []
95
96 for f in deleted + removed:
97 if f not in m2:
98 action.append((f, "f"))
99
100 return action
101
102 def manifestmerge(ui, m1, m2, ma, overwrite, backwards, partial):
56 """
103 """
57 Merge manifest m1 with m2 using ancestor ma and generate merge action list
104 Merge manifest m1 with m2 using ancestor ma and generate merge action list
58 """
105 """
59
106
60 action = []
107 action = []
61
108
109 # Filter manifests
110 if partial:
111 for f in m1.keys():
112 if not partial(f): del m1[f]
113 for f in m2.keys():
114 if not partial(f): del m2[f]
115
62 # Compare manifests
116 # Compare manifests
63 for f, n in m1.iteritems():
117 for f, n in m1.iteritems():
64 if f in m2:
118 if f in m2:
@@ -176,7 +230,8 b' def update(repo, node, branchmerge=False'
176 raise util.Abort(_("update spans branches, use 'hg merge' "
230 raise util.Abort(_("update spans branches, use 'hg merge' "
177 "or 'hg update -C' to lose changes"))
231 "or 'hg update -C' to lose changes"))
178
232
179 modified, added, removed, deleted, unknown = repo.status()[:5]
233 status = repo.status()
234 modified, added, removed, deleted, unknown = status[:5]
180 if branchmerge and not forcemerge:
235 if branchmerge and not forcemerge:
181 if modified or added or removed:
236 if modified or added or removed:
182 raise util.Abort(_("outstanding uncommitted changes"))
237 raise util.Abort(_("outstanding uncommitted changes"))
@@ -185,13 +240,6 b' def update(repo, node, branchmerge=False'
185 m2 = repo.changectx(p2).manifest().copy()
240 m2 = repo.changectx(p2).manifest().copy()
186 ma = repo.changectx(pa).manifest()
241 ma = repo.changectx(pa).manifest()
187
242
188 if not force:
189 for f in unknown:
190 if f in m2:
191 if repo.file(f).cmp(m2[f], repo.wread(f)):
192 raise util.Abort(_("'%s' already exists in the working"
193 " dir and differs from remote") % f)
194
195 # resolve the manifest to determine which files
243 # resolve the manifest to determine which files
196 # we care about merging
244 # we care about merging
197 repo.ui.note(_("resolving manifests\n"))
245 repo.ui.note(_("resolving manifests\n"))
@@ -201,31 +249,13 b' def update(repo, node, branchmerge=False'
201 (short(p1), short(p2), short(pa)))
249 (short(p1), short(p2), short(pa)))
202
250
203 action = []
251 action = []
204
252 m1 = workingmanifest(repo, m1, status)
205 # update m1 from working dir
206 for i,l in (("a", added), ("m", modified), ("u", unknown)):
207 for f in l:
208 m1[f] = m1.get(f, nullid) + i
209 m1.set(f, util.is_exec(repo.wjoin(f), m1.execf(f)))
210
211 for f in deleted + removed:
212 del m1[f]
213
253
214 # If we're jumping between revisions (as opposed to merging),
254 if not force:
215 # and if neither the working directory nor the target rev has
255 checkunknown(repo, m2, status)
216 # the file, then we need to remove it from the dirstate, to
256 if linear_path:
217 # prevent the dirstate from listing the file when it is no
257 action += forgetremoved(m2, status)
218 # longer in the manifest.
258 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial)
219 if linear_path and f not in m2:
220 action.append((f, "f"))
221
222 if partial:
223 for f in m1.keys():
224 if not partial(f): del m1[f]
225 for f in m2.keys():
226 if not partial(f): del m2[f]
227
228 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards)
229 del m1, m2, ma
259 del m1, m2, ma
230
260
231 ### apply phase
261 ### apply phase
General Comments 0
You need to be logged in to leave comments. Login now