Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/merge.py @ 3303:488d3062d225
merge: eliminate nodes from action list
- eliminate my and other from merge and copy
- eliminate node from get
- use mctx for get
- fix bug flag = a[2:]
- pass mctx to recordupdates
- use new filectx.size in recordupdates
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 09 Oct 2006 23:23:25 -0500 |
parents | e7abcf3a7c5f |
children | 5c9806554d65 |
comparison
equal
deleted
inserted
replaced
3302:192085505f6f | 3303:488d3062d225 |
---|---|
14 """perform a 3-way merge in the working directory | 14 """perform a 3-way merge in the working directory |
15 | 15 |
16 fw = filename in the working directory and first parent | 16 fw = filename in the working directory and first parent |
17 fo = filename in other parent | 17 fo = filename in other parent |
18 fd = destination filename | 18 fd = destination filename |
19 my = fileid in first parent | |
20 other = fileid in second parent | |
21 wctx, mctx = working and merge changecontexts | 19 wctx, mctx = working and merge changecontexts |
22 move = whether to move or copy the file to the destination | 20 move = whether to move or copy the file to the destination |
23 | 21 |
24 TODO: | 22 TODO: |
25 if fw is copied in the working directory, we get confused | 23 if fw is copied in the working directory, we get confused |
210 # are files different? | 208 # are files different? |
211 if n != m2[f]: | 209 if n != m2[f]: |
212 a = ma.get(f, nullid) | 210 a = ma.get(f, nullid) |
213 # are both different from the ancestor? | 211 # are both different from the ancestor? |
214 if not overwrite and n != a and m2[f] != a: | 212 if not overwrite and n != a and m2[f] != a: |
215 act("versions differ", f, "m", fmerge(f), n[:20], m2[f]) | 213 act("versions differ", f, "m", fmerge(f)) |
216 # are we clobbering? | 214 # are we clobbering? |
217 # is remote's version newer? | 215 # is remote's version newer? |
218 # or are we going back in time and clean? | 216 # or are we going back in time and clean? |
219 elif overwrite or m2[f] != a or (backwards and not n[20:]): | 217 elif overwrite or m2[f] != a or (backwards and not n[20:]): |
220 act("remote is newer", f, "g", m2.execf(f), m2[f]) | 218 act("remote is newer", f, "g", m2.execf(f), m2[f]) |
227 act("update permissions", f, "e", m2.execf(f)) | 225 act("update permissions", f, "e", m2.execf(f)) |
228 elif f in copy: | 226 elif f in copy: |
229 f2 = copy[f] | 227 f2 = copy[f] |
230 if f in ma: # case 3,20 A/B/A | 228 if f in ma: # case 3,20 A/B/A |
231 act("remote moved", | 229 act("remote moved", |
232 f, "c", f2, f2, m1[f], m2[f2], fmerge(f, f2, f), True) | 230 f, "c", f2, f2, fmerge(f, f2, f), True) |
233 else: | 231 else: |
234 if f2 in m1: # case 2 A,B/B/B | 232 if f2 in m1: # case 2 A,B/B/B |
235 act("local copied", | 233 act("local copied", |
236 f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False) | 234 f, "c", f2, f, fmerge(f, f2, f2), False) |
237 else: # case 4,21 A/B/B | 235 else: # case 4,21 A/B/B |
238 act("local moved", | 236 act("local moved", |
239 f, "c", f2, f, m1[f], m2[f2], fmerge(f, f2, f2), False) | 237 f, "c", f2, f, fmerge(f, f2, f2), False) |
240 elif f in ma: | 238 elif f in ma: |
241 if n != ma[f] and not overwrite: | 239 if n != ma[f] and not overwrite: |
242 if repo.ui.prompt( | 240 if repo.ui.prompt( |
243 (_(" local changed %s which remote deleted\n") % f) + | 241 (_(" local changed %s which remote deleted\n") % f) + |
244 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"): | 242 _("(k)eep or (d)elete?"), _("[kd]"), _("k")) == _("d"): |
258 if f in copy: | 256 if f in copy: |
259 f2 = copy[f] | 257 f2 = copy[f] |
260 if f2 not in m2: # already seen | 258 if f2 not in m2: # already seen |
261 continue | 259 continue |
262 # rename case 1, A/A,B/A | 260 # rename case 1, A/A,B/A |
263 act("remote copied", | 261 act("remote copied", f2, "c", f, f, fmerge(f2, f, f2), False) |
264 f2, "c", f, f, m1[f2], m2[f], fmerge(f2, f, f2), False) | |
265 elif f in ma: | 262 elif f in ma: |
266 if overwrite or backwards: | 263 if overwrite or backwards: |
267 act("recreating", f, "g", m2.execf(f), n) | 264 act("recreating", f, "g", m2.execf(f), n) |
268 elif n != ma[f]: | 265 elif n != ma[f]: |
269 if repo.ui.prompt( | 266 if repo.ui.prompt( |
291 if inst.errno != errno.ENOENT: | 288 if inst.errno != errno.ENOENT: |
292 repo.ui.warn(_("update failed to remove %s: %s!\n") % | 289 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
293 (f, inst.strerror)) | 290 (f, inst.strerror)) |
294 removed +=1 | 291 removed +=1 |
295 elif m == "c": # copy | 292 elif m == "c": # copy |
296 f2, fd, my, other, flag, move = a[2:] | 293 f2, fd, flag, move = a[2:] |
297 repo.ui.status(_("merging %s and %s to %s\n") % (f, f2, fd)) | 294 repo.ui.status(_("merging %s and %s to %s\n") % (f, f2, fd)) |
298 if filemerge(repo, f, f2, fd, wctx, mctx, move): | 295 if filemerge(repo, f, f2, fd, wctx, mctx, move): |
299 unresolved += 1 | 296 unresolved += 1 |
300 util.set_exec(repo.wjoin(fd), flag) | 297 util.set_exec(repo.wjoin(fd), flag) |
301 merged += 1 | 298 merged += 1 |
302 elif m == "m": # merge | 299 elif m == "m": # merge |
303 flag, my, other = a[2:] | 300 flag = a[2] |
304 repo.ui.status(_("merging %s\n") % f) | 301 repo.ui.status(_("merging %s\n") % f) |
305 if filemerge(repo, f, f, f, wctx, mctx, False): | 302 if filemerge(repo, f, f, f, wctx, mctx, False): |
306 unresolved += 1 | 303 unresolved += 1 |
307 util.set_exec(repo.wjoin(f), flag) | 304 util.set_exec(repo.wjoin(f), flag) |
308 merged += 1 | 305 merged += 1 |
309 elif m == "g": # get | 306 elif m == "g": # get |
310 flag, node = a[2:] | 307 flag, node = a[2:] |
311 repo.ui.note(_("getting %s\n") % f) | 308 repo.ui.note(_("getting %s\n") % f) |
312 t = repo.file(f).read(node) | 309 t = mctx.filectx(f).data() |
313 repo.wwrite(f, t) | 310 repo.wwrite(f, t) |
314 util.set_exec(repo.wjoin(f), flag) | 311 util.set_exec(repo.wjoin(f), flag) |
315 updated += 1 | 312 updated += 1 |
316 elif m == "e": # exec | 313 elif m == "e": # exec |
317 flag = a[2:] | 314 flag = a[2] |
318 util.set_exec(repo.wjoin(f), flag) | 315 util.set_exec(repo.wjoin(f), flag) |
319 | 316 |
320 return updated, merged, removed, unresolved | 317 return updated, merged, removed, unresolved |
321 | 318 |
322 def recordupdates(repo, action, branchmerge): | 319 def recordupdates(repo, action, branchmerge, mctx): |
323 for a in action: | 320 for a in action: |
324 f, m = a[:2] | 321 f, m = a[:2] |
325 if m == "r": # remove | 322 if m == "r": # remove |
326 if branchmerge: | 323 if branchmerge: |
327 repo.dirstate.update([f], 'r') | 324 repo.dirstate.update([f], 'r') |
333 if branchmerge: | 330 if branchmerge: |
334 repo.dirstate.update([f], 'n', st_mtime=-1) | 331 repo.dirstate.update([f], 'n', st_mtime=-1) |
335 else: | 332 else: |
336 repo.dirstate.update([f], 'n') | 333 repo.dirstate.update([f], 'n') |
337 elif m == "m": # merge | 334 elif m == "m": # merge |
338 flag, my, other = a[2:] | 335 flag = a[2] |
339 if branchmerge: | 336 if branchmerge: |
340 # We've done a branch merge, mark this file as merged | 337 # We've done a branch merge, mark this file as merged |
341 # so that we properly record the merger later | 338 # so that we properly record the merger later |
342 repo.dirstate.update([f], 'm') | 339 repo.dirstate.update([f], 'm') |
343 else: | 340 else: |
345 # we set the dirstate to emulate a normal checkout | 342 # we set the dirstate to emulate a normal checkout |
346 # of that file some time in the past. Thus our | 343 # of that file some time in the past. Thus our |
347 # merge will appear as a normal local file | 344 # merge will appear as a normal local file |
348 # modification. | 345 # modification. |
349 fl = repo.file(f) | 346 fl = repo.file(f) |
350 f_len = fl.size(fl.rev(other)) | 347 f_len = mctx.filectx(f).size() |
351 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1) | 348 repo.dirstate.update([f], 'n', st_size=f_len, st_mtime=-1) |
352 elif m == "c": # copy | 349 elif m == "c": # copy |
353 f2, fd, my, other, flag, move = a[2:] | 350 f2, fd, flag, move = a[2:] |
354 if branchmerge: | 351 if branchmerge: |
355 # We've done a branch merge, mark this file as merged | 352 # We've done a branch merge, mark this file as merged |
356 # so that we properly record the merger later | 353 # so that we properly record the merger later |
357 repo.dirstate.update([fd], 'm') | 354 repo.dirstate.update([fd], 'm') |
358 else: | 355 else: |
360 # we set the dirstate to emulate a normal checkout | 357 # we set the dirstate to emulate a normal checkout |
361 # of that file some time in the past. Thus our | 358 # of that file some time in the past. Thus our |
362 # merge will appear as a normal local file | 359 # merge will appear as a normal local file |
363 # modification. | 360 # modification. |
364 fl = repo.file(f) | 361 fl = repo.file(f) |
365 f_len = fl.size(fl.rev(other)) | 362 f_len = mctx.filectx(f).size() |
366 repo.dirstate.update([fd], 'n', st_size=f_len, st_mtime=-1) | 363 repo.dirstate.update([fd], 'n', st_size=f_len, st_mtime=-1) |
367 if move: | 364 if move: |
368 repo.dirstate.update([f], 'r') | 365 repo.dirstate.update([f], 'r') |
369 if f != fd: | 366 if f != fd: |
370 repo.dirstate.copy(f, fd) | 367 repo.dirstate.copy(f, fd) |
435 | 432 |
436 updated, merged, removed, unresolved = applyupdates(repo, action, wc, p2) | 433 updated, merged, removed, unresolved = applyupdates(repo, action, wc, p2) |
437 | 434 |
438 # update dirstate | 435 # update dirstate |
439 if not partial: | 436 if not partial: |
440 recordupdates(repo, action, branchmerge) | 437 recordupdates(repo, action, branchmerge, p2) |
441 repo.dirstate.setparents(fp1, fp2) | 438 repo.dirstate.setparents(fp1, fp2) |
442 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved) | 439 repo.hook('update', parent1=xp1, parent2=xp2, error=unresolved) |
443 | 440 |
444 if show_stats: | 441 if show_stats: |
445 stats = ((updated, _("updated")), | 442 stats = ((updated, _("updated")), |