##// END OF EJS Templates
copies: calculate mergecopies() based on pathcopies()...
Martin von Zweigbergk -
r42793:57203e02 default
parent child Browse files
Show More
@@ -373,57 +373,6 b' def _computenonoverlap(repo, c1, c2, add'
373 373
374 374 return u1, u2
375 375
376 def _makegetfctx(ctx):
377 """return a 'getfctx' function suitable for _checkcopies usage
378
379 We have to re-setup the function building 'filectx' for each
380 '_checkcopies' to ensure the linkrev adjustment is properly setup for
381 each. Linkrev adjustment is important to avoid bug in rename
382 detection. Moreover, having a proper '_ancestrycontext' setup ensures
383 the performance impact of this adjustment is kept limited. Without it,
384 each file could do a full dag traversal making the time complexity of
385 the operation explode (see issue4537).
386
387 This function exists here mostly to limit the impact on stable. Feel
388 free to refactor on default.
389 """
390 rev = ctx.rev()
391 repo = ctx._repo
392 ac = getattr(ctx, '_ancestrycontext', None)
393 if ac is None:
394 revs = [rev]
395 if rev is None:
396 revs = [p.rev() for p in ctx.parents()]
397 ac = repo.changelog.ancestors(revs, inclusive=True)
398 ctx._ancestrycontext = ac
399 def makectx(f, n):
400 if n in node.wdirfilenodeids: # in a working context?
401 if ctx.rev() is None:
402 return ctx.filectx(f)
403 return repo[None][f]
404 fctx = repo.filectx(f, fileid=n)
405 # setup only needed for filectx not create from a changectx
406 fctx._ancestrycontext = ac
407 fctx._descendantrev = rev
408 return fctx
409 return util.lrucachefunc(makectx)
410
411 def _combinecopies(copyfrom, copyto, finalcopy, diverge, incompletediverge):
412 """combine partial copy paths"""
413 remainder = {}
414 for f in copyfrom:
415 if f in copyto:
416 finalcopy[copyto[f]] = copyfrom[f]
417 del copyto[f]
418 for f in incompletediverge:
419 assert f not in diverge
420 ic = incompletediverge[f]
421 if ic[0] in copyto:
422 diverge[f] = [copyto[ic[0]], ic[1]]
423 else:
424 remainder[f] = ic
425 return remainder
426
427 376 def mergecopies(repo, c1, c2, base):
428 377 """
429 378 Finds moves and copies between context c1 and c2 that are relevant for
@@ -518,6 +467,23 b' def _isfullcopytraceable(repo, c1, base)'
518 467 return commits < sourcecommitlimit
519 468 return False
520 469
470 def _checksinglesidecopies(src, dsts1, m1, m2, mb, c2, base,
471 copy, renamedelete):
472 if src not in m2:
473 # deleted on side 2
474 if src not in m1:
475 # renamed on side 1, deleted on side 2
476 renamedelete[src] = dsts1
477 elif m2[src] != mb[src]:
478 if not _related(c2[src], base[src]):
479 return
480 # modified on side 2
481 for dst in dsts1:
482 if dst not in m2:
483 # dst not added on side 2 (handle as regular
484 # "both created" case in manifestmerge otherwise)
485 copy[dst] = src
486
521 487 def _fullcopytracing(repo, c1, c2, base):
522 488 """ The full copytracing algorithm which finds all the new files that were
523 489 added from merge base up to the top commit and for each file it checks if
@@ -526,168 +492,73 b' def _fullcopytracing(repo, c1, c2, base)'
526 492 This is pretty slow when a lot of changesets are involved but will track all
527 493 the copies.
528 494 """
529 # In certain scenarios (e.g. graft, update or rebase), base can be
530 # overridden We still need to know a real common ancestor in this case We
531 # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
532 # can be multiple common ancestors, e.g. in case of bidmerge. Because our
533 # caller may not know if the revision passed in lieu of the CA is a genuine
534 # common ancestor or not without explicitly checking it, it's better to
535 # determine that here.
536 #
537 # base.isancestorof(wc) is False, work around that
538 _c1 = c1.p1() if c1.rev() is None else c1
539 _c2 = c2.p1() if c2.rev() is None else c2
540 # an endpoint is "dirty" if it isn't a descendant of the merge base
541 # if we have a dirty endpoint, we need to trigger graft logic, and also
542 # keep track of which endpoint is dirty
543 dirtyc1 = not base.isancestorof(_c1)
544 dirtyc2 = not base.isancestorof(_c2)
545 graft = dirtyc1 or dirtyc2
546 tca = base
547 if graft:
548 tca = _c1.ancestor(_c2)
549
550 limit = _findlimit(repo, c1, c2)
551
552 495 m1 = c1.manifest()
553 496 m2 = c2.manifest()
554 497 mb = base.manifest()
555 498
556 # gather data from _checkcopies:
557 # - diverge = record all diverges in this dict
558 # - copy = record all non-divergent copies in this dict
559 # - fullcopy = record all copies in this dict
560 # - incomplete = record non-divergent partial copies here
561 # - incompletediverge = record divergent partial copies here
562 diverge = {} # divergence data is shared
563 incompletediverge = {}
564 data1 = {'copy': {},
565 'fullcopy': {},
566 'incomplete': {},
567 'diverge': diverge,
568 'incompletediverge': incompletediverge,
569 }
570 data2 = {'copy': {},
571 'fullcopy': {},
572 'incomplete': {},
573 'diverge': diverge,
574 'incompletediverge': incompletediverge,
575 }
499 copies1 = pathcopies(base, c1)
500 copies2 = pathcopies(base, c2)
501
502 inversecopies1 = {}
503 inversecopies2 = {}
504 for dst, src in copies1.items():
505 inversecopies1.setdefault(src, []).append(dst)
506 for dst, src in copies2.items():
507 inversecopies2.setdefault(src, []).append(dst)
508
509 copy = {}
510 diverge = {}
511 renamedelete = {}
512 allsources = set(inversecopies1) | set(inversecopies2)
513 for src in allsources:
514 dsts1 = inversecopies1.get(src)
515 dsts2 = inversecopies2.get(src)
516 if dsts1 and dsts2:
517 # copied/renamed on both sides
518 if src not in m1 and src not in m2:
519 # renamed on both sides
520 dsts1 = set(dsts1)
521 dsts2 = set(dsts2)
522 # If there's some overlap in the rename destinations, we
523 # consider it not divergent. For example, if side 1 copies 'a'
524 # to 'b' and 'c' and deletes 'a', and side 2 copies 'a' to 'c'
525 # and 'd' and deletes 'a'.
526 if dsts1 & dsts2:
527 for dst in (dsts1 & dsts2):
528 copy[dst] = src
529 else:
530 diverge[src] = sorted(dsts1 | dsts2)
531 elif src in m1 and src in m2:
532 # copied on both sides
533 dsts1 = set(dsts1)
534 dsts2 = set(dsts2)
535 for dst in (dsts1 & dsts2):
536 copy[dst] = src
537 # TODO: Handle cases where it was renamed on one side and copied
538 # on the other side
539 elif dsts1:
540 # copied/renamed only on side 1
541 _checksinglesidecopies(src, dsts1, m1, m2, mb, c2, base,
542 copy, renamedelete)
543 elif dsts2:
544 # copied/renamed only on side 2
545 _checksinglesidecopies(src, dsts2, m2, m1, mb, c1, base,
546 copy, renamedelete)
547
548 renamedeleteset = set()
549 divergeset = set()
550 for src, dsts in diverge.items():
551 divergeset.update(dsts)
552 for src, dsts in renamedelete.items():
553 renamedeleteset.update(dsts)
576 554
577 555 # find interesting file sets from manifests
578 556 addedinm1 = m1.filesnotin(mb, repo.narrowmatch())
579 557 addedinm2 = m2.filesnotin(mb, repo.narrowmatch())
580 bothnew = sorted(addedinm1 & addedinm2)
581 if tca == base:
582 # unmatched file from base
583 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
584 u1u, u2u = u1r, u2r
585 else:
586 # unmatched file from base (DAG rotation in the graft case)
587 u1r, u2r = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
588 # unmatched file from topological common ancestors (no DAG rotation)
589 # need to recompute this for directory move handling when grafting
590 mta = tca.manifest()
591 u1u, u2u = _computenonoverlap(repo, c1, c2,
592 m1.filesnotin(mta, repo.narrowmatch()),
593 m2.filesnotin(mta, repo.narrowmatch()),
594 debug=False)
595
596 for f in u1u:
597 _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1)
598
599 for f in u2u:
600 _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2)
601
602 copy = dict(data1['copy'])
603 copy.update(data2['copy'])
604 fullcopy = dict(data1['fullcopy'])
605 fullcopy.update(data2['fullcopy'])
606
607 if dirtyc1:
608 _combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
609 incompletediverge)
610 if dirtyc2:
611 _combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
612 incompletediverge)
613
614 renamedelete = {}
615 renamedeleteset = set()
616 divergeset = set()
617 for of, fl in list(diverge.items()):
618 if len(fl) == 1 or of in c1 or of in c2:
619 del diverge[of] # not actually divergent, or not a rename
620 if of not in c1 and of not in c2:
621 # renamed on one side, deleted on the other side, but filter
622 # out files that have been renamed and then deleted
623 renamedelete[of] = [f for f in fl if f in c1 or f in c2]
624 renamedeleteset.update(fl) # reverse map for below
625 else:
626 divergeset.update(fl) # reverse map for below
558 u1, u2 = _computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
627 559
628 bothdiverge = {}
629 bothincompletediverge = {}
630 remainder = {}
631 both1 = {'copy': {},
632 'fullcopy': {},
633 'incomplete': {},
634 'diverge': bothdiverge,
635 'incompletediverge': bothincompletediverge
636 }
637 both2 = {'copy': {},
638 'fullcopy': {},
639 'incomplete': {},
640 'diverge': bothdiverge,
641 'incompletediverge': bothincompletediverge
642 }
643 for f in bothnew:
644 _checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
645 _checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
646 if dirtyc1 and dirtyc2:
647 remainder = _combinecopies(both2['incomplete'], both1['incomplete'],
648 copy, bothdiverge, bothincompletediverge)
649 remainder1 = _combinecopies(both1['incomplete'], both2['incomplete'],
650 copy, bothdiverge, bothincompletediverge)
651 remainder.update(remainder1)
652 elif dirtyc1:
653 # incomplete copies may only be found on the "dirty" side for bothnew
654 assert not both2['incomplete']
655 remainder = _combinecopies({}, both1['incomplete'], copy, bothdiverge,
656 bothincompletediverge)
657 elif dirtyc2:
658 assert not both1['incomplete']
659 remainder = _combinecopies({}, both2['incomplete'], copy, bothdiverge,
660 bothincompletediverge)
661 else:
662 # incomplete copies and divergences can't happen outside grafts
663 assert not both1['incomplete']
664 assert not both2['incomplete']
665 assert not bothincompletediverge
666 for f in remainder:
667 assert f not in bothdiverge
668 ic = remainder[f]
669 if ic[0] in (m1 if dirtyc1 else m2):
670 # backed-out rename on one side, but watch out for deleted files
671 bothdiverge[f] = ic
672 for of, fl in bothdiverge.items():
673 if len(fl) == 2 and fl[0] == fl[1]:
674 copy[fl[0]] = of # not actually divergent, just matching renames
675
676 # Sometimes we get invalid copies here (the "and not remotebase" in
677 # _checkcopies() seems suspicious). Filter them out.
678 for dst, src in fullcopy.copy().items():
679 if src not in mb:
680 del fullcopy[dst]
681 # Sometimes we forget to add entries from "copy" to "fullcopy", so fix
682 # that up here
683 for dst, src in copy.items():
684 fullcopy[dst] = src
685 # Sometimes we forget to add entries from "diverge" to "fullcopy", so fix
686 # that up here
687 for src, dsts in diverge.items():
688 for dst in dsts:
689 fullcopy[dst] = src
690
560 fullcopy = copies1.copy()
561 fullcopy.update(copies2)
691 562 if not fullcopy:
692 563 return copy, {}, diverge, renamedelete, {}
693 564
@@ -752,7 +623,7 b' def _fullcopytracing(repo, c1, c2, base)'
752 623
753 624 movewithdir = {}
754 625 # check unaccounted nonoverlapping files against directory moves
755 for f in u1r + u2r:
626 for f in u1 + u2:
756 627 if f not in fullcopy:
757 628 for d in dirmove:
758 629 if f.startswith(d):
@@ -899,99 +770,6 b' def _related(f1, f2):'
899 770 except StopIteration:
900 771 return False
901 772
902 def _checkcopies(srcctx, dstctx, f, base, tca, remotebase, limit, data):
903 """
904 check possible copies of f from msrc to mdst
905
906 srcctx = starting context for f in msrc
907 dstctx = destination context for f in mdst
908 f = the filename to check (as in msrc)
909 base = the changectx used as a merge base
910 tca = topological common ancestor for graft-like scenarios
911 remotebase = True if base is outside tca::srcctx, False otherwise
912 limit = the rev number to not search beyond
913 data = dictionary of dictionary to store copy data. (see mergecopies)
914
915 note: limit is only an optimization, and provides no guarantee that
916 irrelevant revisions will not be visited
917 there is no easy way to make this algorithm stop in a guaranteed way
918 once it "goes behind a certain revision".
919 """
920
921 msrc = srcctx.manifest()
922 mdst = dstctx.manifest()
923 mb = base.manifest()
924 mta = tca.manifest()
925 # Might be true if this call is about finding backward renames,
926 # This happens in the case of grafts because the DAG is then rotated.
927 # If the file exists in both the base and the source, we are not looking
928 # for a rename on the source side, but on the part of the DAG that is
929 # traversed backwards.
930 #
931 # In the case there is both backward and forward renames (before and after
932 # the base) this is more complicated as we must detect a divergence.
933 # We use 'backwards = False' in that case.
934 backwards = not remotebase and base != tca and f in mb
935 getsrcfctx = _makegetfctx(srcctx)
936 getdstfctx = _makegetfctx(dstctx)
937
938 if msrc[f] == mb.get(f) and not remotebase:
939 # Nothing to merge
940 return
941
942 of = None
943 seen = {f}
944 for oc in getsrcfctx(f, msrc[f]).ancestors():
945 of = oc.path()
946 if of in seen:
947 # check limit late - grab last rename before
948 if oc.linkrev() < limit:
949 break
950 continue
951 seen.add(of)
952
953 # remember for dir rename detection
954 if backwards:
955 data['fullcopy'][of] = f # grafting backwards through renames
956 else:
957 data['fullcopy'][f] = of
958 if of not in mdst:
959 continue # no match, keep looking
960 if mdst[of] == mb.get(of):
961 return # no merge needed, quit early
962 c2 = getdstfctx(of, mdst[of])
963 # c2 might be a plain new file on added on destination side that is
964 # unrelated to the droids we are looking for.
965 cr = _related(oc, c2)
966 if cr and (of == f or of == c2.path()): # non-divergent
967 if backwards:
968 data['copy'][of] = f
969 elif of in mb:
970 data['copy'][f] = of
971 elif remotebase: # special case: a <- b <- a -> b "ping-pong" rename
972 data['copy'][of] = f
973 del data['fullcopy'][f]
974 data['fullcopy'][of] = f
975 else: # divergence w.r.t. graft CA on one side of topological CA
976 for sf in seen:
977 if sf in mb:
978 assert sf not in data['diverge']
979 data['diverge'][sf] = [f, of]
980 break
981 return
982
983 if of in mta:
984 if backwards or remotebase:
985 data['incomplete'][of] = f
986 else:
987 for sf in seen:
988 if sf in mb:
989 if tca == base:
990 data['diverge'].setdefault(sf, []).append(f)
991 else:
992 data['incompletediverge'][sf] = [of, f]
993 return
994
995 773 def duplicatecopies(repo, wctx, rev, fromrev, skiprev=None):
996 774 """reproduce copies from fromrev to rev in the dirstate
997 775
@@ -273,37 +273,10 b' annotate after merge with -l'
273 273 > EOF
274 274 $ hg ci -mc -d '3 0'
275 275 created new head
276 BROKEN: 'a' was copied to 'b' on both sides. We should not get a merge conflict here
277 276 $ hg merge
278 277 merging b
279 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
280 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
281 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
282 [1]
283 $ cat b
284 <<<<<<< working copy: b80e3e32f75a - test: c
285 a
286 z
287 a
288 ||||||| base
289 =======
290 a
291 a
292 a
293 b4
294 c
295 b5
296 >>>>>>> merge rev: 64afcdf8e29e - test: mergeb
297 $ cat <<EOF > b
298 > a
299 > z
300 > a
301 > b4
302 > c
303 > b5
304 > EOF
305 $ hg resolve --mark -q
306 $ rm b.orig
278 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
279 (branch merge, don't forget to commit)
307 280 $ echo d >> b
308 281 $ hg ci -mmerge2 -d '4 0'
309 282
@@ -787,12 +787,11 b' Amend a merge changeset (with renames du'
787 787 Update to p1 with 'aaa' modified. 'aaa' was renamed from 'aa' in p2. 'aa' exists
788 788 in p1 too, but it was recorded as copied from p2.
789 789 $ echo modified >> aaa
790 BROKEN: should not be follow the rename back to 'aa' here, since the rename
791 happened compared to p2
792 790 $ hg co -m '.^' -t :merge3
793 merging aaa and aa to aa
794 warning: conflicts while merging aa! (edit, then use 'hg resolve --mark')
795 0 files updated, 0 files merged, 1 files removed, 1 files unresolved
791 file 'aaa' was deleted in other [destination] but was modified in local [working copy].
792 What do you want to do?
793 use (c)hanged version, (d)elete, or leave (u)nresolved? u
794 1 files updated, 0 files merged, 1 files removed, 1 files unresolved
796 795 use 'hg resolve' to retry unresolved file merges
797 796 [1]
798 797 $ hg co -C tip
@@ -549,9 +549,6 b' test reflect that for this particular ca'
549 549
550 550 Grafting revision 4 on top of revision 2, showing that it respect the rename:
551 551
552 TODO: Make this work with copy info in changesets (probably by writing a
553 changeset-centric version of copies.mergecopies())
554 #if no-changeset
555 552 $ hg up 2 -q
556 553 $ hg graft -r 4 --base 3 --hidden
557 554 grafting 4:af28412ec03c "added d, modified b" (tip)
@@ -560,15 +557,14 b' changeset-centric version of copies.merg'
560 557 $ hg l -l1 -p
561 558 @ 5 added d, modified b
562 559 | b1
563 ~ diff -r 5a4825cc2926 -r 94a2f1a0e8e2 b1
560 ~ diff -r 5a4825cc2926 -r 94a2f1a0e8e2 b1 (no-changeset !)
561 ~ diff -r f5474f5023a8 -r ef7c02d69f3d b1 (changeset !)
564 562 --- a/b1 Thu Jan 01 00:00:00 1970 +0000
565 563 +++ b/b1 Thu Jan 01 00:00:00 1970 +0000
566 564 @@ -1,1 +1,2 @@
567 565 b
568 566 +baba
569 567
570 #endif
571
572 568 Test to make sure that fullcopytracing algorithm don't fail when both the merging csets are dirty
573 569 (a dirty cset is one who is not the descendant of merge base)
574 570 -------------------------------------------------------------------------------------------------
@@ -273,37 +273,10 b' annotate after merge with -l'
273 273 > EOF
274 274 $ hg ci -mc -d '3 0'
275 275 created new head
276 BROKEN: 'a' was copied to 'b' on both sides. We should not get a merge conflict here
277 276 $ hg merge
278 277 merging b
279 warning: conflicts while merging b! (edit, then use 'hg resolve --mark')
280 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
281 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
282 [1]
283 $ cat b
284 <<<<<<< working copy: b80e3e32f75a - test: c
285 a
286 z
287 a
288 ||||||| base
289 =======
290 a
291 a
292 a
293 b4
294 c
295 b5
296 >>>>>>> merge rev: 64afcdf8e29e - test: mergeb
297 $ cat <<EOF > b
298 > a
299 > z
300 > a
301 > b4
302 > c
303 > b5
304 > EOF
305 $ hg resolve --mark -q
306 $ rm b.orig
278 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
279 (branch merge, don't forget to commit)
307 280 $ echo d >> b
308 281 $ hg ci -mmerge2 -d '4 0'
309 282
@@ -75,6 +75,8 b' Specifying child as --base revision fail'
75 75
76 76 $ hg graft -r 2 --base 3
77 77 grafting 2:5c095ad7e90f "2"
78 note: possible conflict - c was deleted and renamed to:
79 a
78 80 note: graft of 2:5c095ad7e90f created no changes to commit
79 81
80 82 Can't continue without starting:
@@ -220,6 +222,9 b' Graft out of order, skipping a merge and'
220 222 committing changelog
221 223 updating the branch cache
222 224 grafting 5:97f8bfe72746 "5"
225 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
226 src: 'c' -> dst: 'b'
227 checking for directory renames
223 228 resolving manifests
224 229 branchmerge: True, force: True, partial: False
225 230 ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746
@@ -233,6 +238,9 b' Graft out of order, skipping a merge and'
233 238 $ HGEDITOR=cat hg graft 4 3 --log --debug
234 239 scanning for duplicate grafts
235 240 grafting 4:9c233e8e184d "4"
241 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
242 src: 'c' -> dst: 'b'
243 checking for directory renames
236 244 resolving manifests
237 245 branchmerge: True, force: True, partial: False
238 246 ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d
@@ -1129,7 +1137,6 b' and A.3 with a local content change to b'
1129 1137 grafting 2:f58c7e2b28fa "C0"
1130 1138 merging f1e and f1b to f1e
1131 1139 merging f2a and f2c to f2c
1132 merging f5b and f5a to f5a
1133 1140
1134 1141 Test the cases A.1 (f4x) and A.7 (f3x).
1135 1142
@@ -1688,13 +1688,8 b' Check debug output for copy tracing'
1688 1688 Check that merging across the rename works
1689 1689
1690 1690 $ echo modified >> renamed
1691 BROKEN: This should propagate the change to 'f'
1692 1691 $ hg co -m 4
1693 file 'renamed' was deleted in other [destination] but was modified in local [working copy].
1694 What do you want to do?
1695 use (c)hanged version, (d)elete, or leave (u)nresolved? u
1696 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1697 use 'hg resolve' to retry unresolved file merges
1698 [1]
1692 merging renamed and f to f
1693 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
1699 1694
1700 1695 $ cd ..
@@ -433,6 +433,9 b' m "um a c" "um x c" " " "10 do merg'
433 433 --------------
434 434 test L:nc a b R:up b W: - 12 merge b no ancestor
435 435 --------------
436 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
437 src: 'a' -> dst: 'b'
438 checking for directory renames
436 439 resolving manifests
437 440 branchmerge: True, force: False, partial: False
438 441 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: af30c7647fc7
@@ -469,6 +472,9 b' m "um a c" "um x c" " " "10 do merg'
469 472 --------------
470 473 test L:up b R:nm a b W: - 13 merge b no ancestor
471 474 --------------
475 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
476 src: 'a' -> dst: 'b'
477 checking for directory renames
472 478 resolving manifests
473 479 branchmerge: True, force: False, partial: False
474 480 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
@@ -506,6 +512,9 b' m "um a c" "um x c" " " "10 do merg'
506 512 --------------
507 513 test L:nc a b R:up a b W: - 14 merge b no ancestor
508 514 --------------
515 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
516 src: 'a' -> dst: 'b'
517 checking for directory renames
509 518 resolving manifests
510 519 branchmerge: True, force: False, partial: False
511 520 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
@@ -543,6 +552,9 b' m "um a c" "um x c" " " "10 do merg'
543 552 --------------
544 553 test L:up b R:nm a b W: - 15 merge b no ancestor, remove a
545 554 --------------
555 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
556 src: 'a' -> dst: 'b'
557 checking for directory renames
546 558 resolving manifests
547 559 branchmerge: True, force: False, partial: False
548 560 ancestor: 924404dff337, local: 59318016310c+, remote: bdb19105162a
@@ -580,6 +592,9 b' m "um a c" "um x c" " " "10 do merg'
580 592 --------------
581 593 test L:nc a b R:up a b W: - 16 get a, merge b no ancestor
582 594 --------------
595 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
596 src: 'a' -> dst: 'b'
597 checking for directory renames
583 598 resolving manifests
584 599 branchmerge: True, force: False, partial: False
585 600 ancestor: 924404dff337, local: 86a2aa42fc76+, remote: 8dbce441892a
@@ -617,6 +632,9 b' m "um a c" "um x c" " " "10 do merg'
617 632 --------------
618 633 test L:up a b R:nc a b W: - 17 keep a, merge b no ancestor
619 634 --------------
635 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
636 src: 'a' -> dst: 'b'
637 checking for directory renames
620 638 resolving manifests
621 639 branchmerge: True, force: False, partial: False
622 640 ancestor: 924404dff337, local: 0b76e65c8289+, remote: 4ce40f5aca24
@@ -653,6 +671,9 b' m "um a c" "um x c" " " "10 do merg'
653 671 --------------
654 672 test L:nm a b R:up a b W: - 18 merge b no ancestor
655 673 --------------
674 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
675 src: 'a' -> dst: 'b'
676 checking for directory renames
656 677 resolving manifests
657 678 branchmerge: True, force: False, partial: False
658 679 ancestor: 924404dff337, local: 02963e448370+, remote: 8dbce441892a
@@ -695,6 +716,9 b' m "um a c" "um x c" " " "10 do merg'
695 716 --------------
696 717 test L:up a b R:nm a b W: - 19 merge b no ancestor, prompt remove a
697 718 --------------
719 all copies found (* = to merge, ! = divergent, % = renamed and deleted):
720 src: 'a' -> dst: 'b'
721 checking for directory renames
698 722 resolving manifests
699 723 branchmerge: True, force: False, partial: False
700 724 ancestor: 924404dff337, local: 0b76e65c8289+, remote: bdb19105162a
General Comments 0
You need to be logged in to leave comments. Login now