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