452 "dst: '%s'\n") % (f, df)) |
452 "dst: '%s'\n") % (f, df)) |
453 break |
453 break |
454 |
454 |
455 return copy, movewithdir, diverge, renamedelete |
455 return copy, movewithdir, diverge, renamedelete |
456 |
456 |
457 def _checkcopies(ctx, f, m1, m2, ca, limit, diverge, copy, fullcopy): |
457 def _checkcopies(ctx, f, m1, m2, base, limit, diverge, copy, fullcopy): |
458 """ |
458 """ |
459 check possible copies of f from m1 to m2 |
459 check possible copies of f from m1 to m2 |
460 |
460 |
461 ctx = starting context for f in m1 |
461 ctx = starting context for f in m1 |
462 f = the filename to check |
462 f = the filename to check |
463 m1 = the source manifest |
463 m1 = the source manifest |
464 m2 = the destination manifest |
464 m2 = the destination manifest |
465 ca = the changectx of the common ancestor |
465 base = the changectx used as a merge base |
466 limit = the rev number to not search beyond |
466 limit = the rev number to not search beyond |
467 diverge = record all diverges in this dict |
467 diverge = record all diverges in this dict |
468 copy = record all non-divergent copies in this dict |
468 copy = record all non-divergent copies in this dict |
469 fullcopy = record all copies in this dict |
469 fullcopy = record all copies in this dict |
470 |
470 |
472 irrelevant revisions will not be limited |
472 irrelevant revisions will not be limited |
473 there is no easy way to make this algorithm stop in a guaranteed way |
473 there is no easy way to make this algorithm stop in a guaranteed way |
474 once it "goes behind a certain revision". |
474 once it "goes behind a certain revision". |
475 """ |
475 """ |
476 |
476 |
477 ma = ca.manifest() |
477 mb = base.manifest() |
478 getfctx = _makegetfctx(ctx) |
478 getfctx = _makegetfctx(ctx) |
479 |
479 |
480 def _related(f1, f2, limit): |
480 def _related(f1, f2, limit): |
481 # Walk back to common ancestor to see if the two files originate |
481 # Walk back to common ancestor to see if the two files originate |
482 # from the same file. Since workingfilectx's rev() is None it messes |
482 # from the same file. Since workingfilectx's rev() is None it messes |
521 seen.add(of) |
521 seen.add(of) |
522 |
522 |
523 fullcopy[f] = of # remember for dir rename detection |
523 fullcopy[f] = of # remember for dir rename detection |
524 if of not in m2: |
524 if of not in m2: |
525 continue # no match, keep looking |
525 continue # no match, keep looking |
526 if m2[of] == ma.get(of): |
526 if m2[of] == mb.get(of): |
527 return # no merge needed, quit early |
527 return # no merge needed, quit early |
528 c2 = getfctx(of, m2[of]) |
528 c2 = getfctx(of, m2[of]) |
529 cr = _related(oc, c2, ca.rev()) |
529 cr = _related(oc, c2, base.rev()) |
530 if cr and (of == f or of == c2.path()): # non-divergent |
530 if cr and (of == f or of == c2.path()): # non-divergent |
531 copy[f] = of |
531 copy[f] = of |
532 return |
532 return |
533 |
533 |
534 if of in ma: |
534 if of in mb: |
535 diverge.setdefault(of, []).append(f) |
535 diverge.setdefault(of, []).append(f) |
536 |
536 |
537 def duplicatecopies(repo, rev, fromrev, skiprev=None): |
537 def duplicatecopies(repo, rev, fromrev, skiprev=None): |
538 '''reproduce copies from fromrev to rev in the dirstate |
538 '''reproduce copies from fromrev to rev in the dirstate |
539 |
539 |