Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/merge.py @ 4674:723e0ddb6ada
merge: warn user about divergent renames
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 21 Jun 2007 18:02:03 -0500 |
parents | 63b9d2deed48 |
children | dc5920ea12f8 |
comparison
equal
deleted
inserted
replaced
4673:d8442fc0da8d | 4674:723e0ddb6ada |
---|---|
153 old.sort() | 153 old.sort() |
154 return old | 154 return old |
155 | 155 |
156 copy = {} | 156 copy = {} |
157 fullcopy = {} | 157 fullcopy = {} |
158 diverge = {} | |
158 | 159 |
159 def checkcopies(c, man): | 160 def checkcopies(c, man): |
160 '''check possible copies for filectx c''' | 161 '''check possible copies for filectx c''' |
161 for of in findold(c): | 162 for of in findold(c): |
163 fullcopy[c.path()] = of # remember for dir rename detection | |
162 if of not in man: # original file not in other manifest? | 164 if of not in man: # original file not in other manifest? |
165 if of in ma: | |
166 diverge.setdefault(of, []).append(c.path()) | |
163 continue | 167 continue |
164 c2 = ctx(of, man[of]) | 168 c2 = ctx(of, man[of]) |
165 ca = c.ancestor(c2) | 169 ca = c.ancestor(c2) |
166 if not ca: # unrelated? | 170 if not ca: # unrelated? |
167 continue | 171 continue |
168 # named changed on only one side? | 172 # named changed on only one side? |
169 if ca.path() == c.path() or ca.path() == c2.path(): | 173 if ca.path() == c.path() or ca.path() == c2.path(): |
170 fullcopy[c.path()] = of # remember for dir rename detection | |
171 if c == ca or c2 == ca: # no merge needed, ignore copy | 174 if c == ca or c2 == ca: # no merge needed, ignore copy |
172 continue | 175 continue |
173 copy[c.path()] = of | 176 copy[c.path()] = of |
174 | 177 |
175 if not repo.ui.configbool("merge", "followcopies", True): | 178 if not repo.ui.configbool("merge", "followcopies", True): |
176 return {} | 179 return {}, {} |
177 | 180 |
178 # avoid silly behavior for update from empty dir | 181 # avoid silly behavior for update from empty dir |
179 if not m1 or not m2 or not ma: | 182 if not m1 or not m2 or not ma: |
180 return {} | 183 return {}, {} |
181 | 184 |
182 u1 = nonoverlap(m1, m2, ma) | 185 u1 = nonoverlap(m1, m2, ma) |
183 u2 = nonoverlap(m2, m1, ma) | 186 u2 = nonoverlap(m2, m1, ma) |
184 | 187 |
185 for f in u1: | 188 for f in u1: |
186 checkcopies(ctx(f, m1[f]), m2) | 189 checkcopies(ctx(f, m1[f]), m2) |
187 | 190 |
188 for f in u2: | 191 for f in u2: |
189 checkcopies(ctx(f, m2[f]), m1) | 192 checkcopies(ctx(f, m2[f]), m1) |
190 | 193 |
194 d2 = {} | |
195 for of, fl in diverge.items(): | |
196 for f in fl: | |
197 fo = list(fl) | |
198 fo.remove(f) | |
199 d2[f] = (of, fo) | |
200 #diverge = d2 | |
201 | |
191 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True): | 202 if not fullcopy or not repo.ui.configbool("merge", "followdirs", True): |
192 return copy | 203 return copy, diverge |
193 | 204 |
194 # generate a directory move map | 205 # generate a directory move map |
195 d1, d2 = dirs(m1), dirs(m2) | 206 d1, d2 = dirs(m1), dirs(m2) |
196 invalid = {} | 207 invalid = {} |
197 dirmove = {} | 208 dirmove = {} |
221 del dirmove[i] | 232 del dirmove[i] |
222 | 233 |
223 del d1, d2, invalid | 234 del d1, d2, invalid |
224 | 235 |
225 if not dirmove: | 236 if not dirmove: |
226 return copy | 237 return copy, diverge |
227 | 238 |
228 # check unaccounted nonoverlapping files against directory moves | 239 # check unaccounted nonoverlapping files against directory moves |
229 for f in u1 + u2: | 240 for f in u1 + u2: |
230 if f not in fullcopy: | 241 if f not in fullcopy: |
231 for d in dirmove: | 242 for d in dirmove: |
232 if f.startswith(d): | 243 if f.startswith(d): |
233 # new file added in a directory that was moved, move it | 244 # new file added in a directory that was moved, move it |
234 copy[f] = dirmove[d] + f[len(d):] | 245 copy[f] = dirmove[d] + f[len(d):] |
235 break | 246 break |
236 | 247 |
237 return copy | 248 return copy, diverge |
238 | 249 |
239 def manifestmerge(repo, p1, p2, pa, overwrite, partial): | 250 def manifestmerge(repo, p1, p2, pa, overwrite, partial): |
240 """ | 251 """ |
241 Merge p1 and p2 with ancestor ma and generate merge action list | 252 Merge p1 and p2 with ancestor ma and generate merge action list |
242 | 253 |
252 m2 = p2.manifest() | 263 m2 = p2.manifest() |
253 ma = pa.manifest() | 264 ma = pa.manifest() |
254 backwards = (pa == p2) | 265 backwards = (pa == p2) |
255 action = [] | 266 action = [] |
256 copy = {} | 267 copy = {} |
268 diverge = {} | |
257 | 269 |
258 def fmerge(f, f2=None, fa=None): | 270 def fmerge(f, f2=None, fa=None): |
259 """merge flags""" | 271 """merge flags""" |
260 if not f2: | 272 if not f2: |
261 f2 = f | 273 f2 = f |
271 def act(msg, m, f, *args): | 283 def act(msg, m, f, *args): |
272 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) | 284 repo.ui.debug(" %s: %s -> %s\n" % (f, msg, m)) |
273 action.append((f, m) + args) | 285 action.append((f, m) + args) |
274 | 286 |
275 if not (backwards or overwrite): | 287 if not (backwards or overwrite): |
276 copy = findcopies(repo, m1, m2, ma, pa.rev()) | 288 copy, diverge = findcopies(repo, m1, m2, ma, pa.rev()) |
289 | |
290 for of, fl in diverge.items(): | |
291 act("divergent renames", "dr", of, fl) | |
292 | |
277 copied = dict.fromkeys(copy.values()) | 293 copied = dict.fromkeys(copy.values()) |
278 | 294 |
279 # Compare manifests | 295 # Compare manifests |
280 for f, n in m1.iteritems(): | 296 for f, n in m1.iteritems(): |
281 if partial and not partial(f): | 297 if partial and not partial(f): |
408 if f2: | 424 if f2: |
409 repo.ui.note(_("getting %s to %s\n") % (f2, fd)) | 425 repo.ui.note(_("getting %s to %s\n") % (f2, fd)) |
410 t = mctx.filectx(f2).data() | 426 t = mctx.filectx(f2).data() |
411 repo.wwrite(fd, t, flags) | 427 repo.wwrite(fd, t, flags) |
412 updated += 1 | 428 updated += 1 |
429 elif m == "dr": # divergent renames | |
430 fl = a[2] | |
431 repo.ui.warn("warning: detected divergent renames of %s to:\n" % f) | |
432 for nf in fl: | |
433 repo.ui.warn(" %s\n" % nf) | |
413 elif m == "e": # exec | 434 elif m == "e": # exec |
414 flags = a[2] | 435 flags = a[2] |
415 util.set_exec(repo.wjoin(f), flags) | 436 util.set_exec(repo.wjoin(f), flags) |
416 | 437 |
417 return updated, merged, removed, unresolved | 438 return updated, merged, removed, unresolved |