Mercurial > hg
comparison mercurial/merge.py @ 3107:3bd05ad67f45
merge: pull manifest checks and updates into separate functions
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Sun, 17 Sep 2006 16:47:33 -0500 |
parents | 4ec28446fca8 |
children | 67874ebbb7dd |
comparison
equal
deleted
inserted
replaced
3106:4ec28446fca8 | 3107:3bd05ad67f45 |
---|---|
50 | 50 |
51 os.unlink(b) | 51 os.unlink(b) |
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 = [] |
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] | |
61 | 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: |
65 queued = 0 | 119 queued = 0 |
174 | 228 |
175 if not linear_path and not (overwrite or branchmerge): | 229 if not linear_path and not (overwrite or branchmerge): |
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")) |
183 | 238 |
184 m1 = repo.changectx(p1).manifest().copy() | 239 m1 = repo.changectx(p1).manifest().copy() |
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 | |
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 | 242 |
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")) |
198 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % | 246 repo.ui.debug(_(" overwrite %s branchmerge %s partial %s linear %s\n") % |
199 (overwrite, branchmerge, bool(partial), linear_path)) | 247 (overwrite, branchmerge, bool(partial), linear_path)) |
200 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % | 248 repo.ui.debug(_(" ancestor %s local %s remote %s\n") % |
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 | 253 |
206 for i,l in (("a", added), ("m", modified), ("u", unknown)): | 254 if not force: |
207 for f in l: | 255 checkunknown(repo, m2, status) |
208 m1[f] = m1.get(f, nullid) + i | 256 if linear_path: |
209 m1.set(f, util.is_exec(repo.wjoin(f), m1.execf(f))) | 257 action += forgetremoved(m2, status) |
210 | 258 action += manifestmerge(repo.ui, m1, m2, ma, overwrite, backwards, partial) |
211 for f in deleted + removed: | |
212 del m1[f] | |
213 | |
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) | |
229 del m1, m2, ma | 259 del m1, m2, ma |
230 | 260 |
231 ### apply phase | 261 ### apply phase |
232 | 262 |
233 if linear_path or overwrite: | 263 if linear_path or overwrite: |