Show More
@@ -52,13 +52,67 b' def merge3(repo, fn, my, other, p1, p2):' | |||
|
52 | 52 | os.unlink(c) |
|
53 | 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 | 104 | Merge manifest m1 with m2 using ancestor ma and generate merge action list |
|
58 | 105 | """ |
|
59 | 106 | |
|
60 | 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 | 116 | # Compare manifests |
|
63 | 117 | for f, n in m1.iteritems(): |
|
64 | 118 | if f in m2: |
@@ -176,7 +230,8 b' def update(repo, node, branchmerge=False' | |||
|
176 | 230 | raise util.Abort(_("update spans branches, use 'hg merge' " |
|
177 | 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 | 235 | if branchmerge and not forcemerge: |
|
181 | 236 | if modified or added or removed: |
|
182 | 237 | raise util.Abort(_("outstanding uncommitted changes")) |
@@ -185,13 +240,6 b' def update(repo, node, branchmerge=False' | |||
|
185 | 240 | m2 = repo.changectx(p2).manifest().copy() |
|
186 | 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 | 243 | # resolve the manifest to determine which files |
|
196 | 244 | # we care about merging |
|
197 | 245 | repo.ui.note(_("resolving manifests\n")) |
@@ -201,31 +249,13 b' def update(repo, node, branchmerge=False' | |||
|
201 | 249 | (short(p1), short(p2), short(pa))) |
|
202 | 250 | |
|
203 | 251 | action = [] |
|
204 | ||
|
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] | |
|
252 | m1 = workingmanifest(repo, m1, status) | |
|
213 | 253 | |
|
214 | # If we're jumping between revisions (as opposed to merging), | |
|
215 | # and if neither the working directory nor the target rev has | |
|
216 | # the file, then we need to remove it from the dirstate, to | |
|
217 | # prevent the dirstate from listing the file when it is no | |
|
218 | # longer in the manifest. | |
|
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) | |
|
254 | if not force: | |
|
255 | checkunknown(repo, m2, status) | |
|
256 | if linear_path: | |
|
257 | action += forgetremoved(m2, status) | |
|
258 | action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) | |
|
229 | 259 | del m1, m2, ma |
|
230 | 260 | |
|
231 | 261 | ### apply phase |
General Comments 0
You need to be logged in to leave comments.
Login now