comparison mercurial/merge.py @ 3309: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
3308:192085505f6f 3309: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")),