520 else: |
520 else: |
521 _checkcollision(repo, m1, actions) |
521 _checkcollision(repo, m1, actions) |
522 |
522 |
523 return actions |
523 return actions |
524 |
524 |
525 def batchremove(repo, actions): |
|
526 """apply removes to the working directory |
|
527 |
|
528 yields tuples for progress updates |
|
529 """ |
|
530 verbose = repo.ui.verbose |
|
531 unlink = util.unlinkpath |
|
532 wjoin = repo.wjoin |
|
533 audit = repo.wopener.audit |
|
534 i = 0 |
|
535 for f, args, msg in actions: |
|
536 repo.ui.debug(" %s: %s -> r\n" % (f, msg)) |
|
537 if verbose: |
|
538 repo.ui.note(_("removing %s\n") % f) |
|
539 audit(f) |
|
540 try: |
|
541 unlink(wjoin(f), ignoremissing=True) |
|
542 except OSError, inst: |
|
543 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
|
544 (f, inst.strerror)) |
|
545 if i == 100: |
|
546 yield i, f |
|
547 i = 0 |
|
548 i += 1 |
|
549 if i > 0: |
|
550 yield i, f |
|
551 |
|
552 def batchget(repo, mctx, actions): |
|
553 """apply gets to the working directory |
|
554 |
|
555 mctx is the context to get from |
|
556 |
|
557 yields tuples for progress updates |
|
558 """ |
|
559 verbose = repo.ui.verbose |
|
560 fctx = mctx.filectx |
|
561 wwrite = repo.wwrite |
|
562 i = 0 |
|
563 for f, args, msg in actions: |
|
564 repo.ui.debug(" %s: %s -> g\n" % (f, msg)) |
|
565 if verbose: |
|
566 repo.ui.note(_("getting %s\n") % f) |
|
567 wwrite(f, fctx(f).data(), args[0]) |
|
568 if i == 100: |
|
569 yield i, f |
|
570 i = 0 |
|
571 i += 1 |
|
572 if i > 0: |
|
573 yield i, f |
|
574 |
|
575 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None): |
|
576 """apply the merge action list to the working directory |
|
577 |
|
578 wctx is the working copy context |
|
579 mctx is the context to be merged into the working copy |
|
580 |
|
581 Return a tuple of counts (updated, merged, removed, unresolved) that |
|
582 describes how many files were affected by the update. |
|
583 """ |
|
584 |
|
585 updated, merged, removed, unresolved = 0, 0, 0, 0 |
|
586 ms = mergestate(repo) |
|
587 ms.reset(wctx.p1().node(), mctx.node()) |
|
588 moves = [] |
|
589 for m, l in actions.items(): |
|
590 l.sort() |
|
591 |
|
592 # prescan for merges |
|
593 for f, args, msg in actions['m']: |
|
594 f1, f2, fa, move, anc = args |
|
595 if f == '.hgsubstate': # merged internally |
|
596 continue |
|
597 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f)) |
|
598 fcl = wctx[f1] |
|
599 fco = mctx[f2] |
|
600 actx = repo[anc] |
|
601 if fa in actx: |
|
602 fca = actx[fa] |
|
603 else: |
|
604 fca = repo.filectx(f1, fileid=nullrev) |
|
605 ms.add(fcl, fco, fca, f) |
|
606 if f1 != f and move: |
|
607 moves.append(f1) |
|
608 |
|
609 audit = repo.wopener.audit |
|
610 _updating = _('updating') |
|
611 _files = _('files') |
|
612 progress = repo.ui.progress |
|
613 |
|
614 # remove renamed files after safely stored |
|
615 for f in moves: |
|
616 if os.path.lexists(repo.wjoin(f)): |
|
617 repo.ui.debug("removing %s\n" % f) |
|
618 audit(f) |
|
619 util.unlinkpath(repo.wjoin(f)) |
|
620 |
|
621 numupdates = sum(len(l) for m, l in actions.items() if m != 'k') |
|
622 |
|
623 if [a for a in actions['r'] if a[0] == '.hgsubstate']: |
|
624 subrepo.submerge(repo, wctx, mctx, wctx, overwrite) |
|
625 |
|
626 # remove in parallel (must come first) |
|
627 z = 0 |
|
628 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r']) |
|
629 for i, item in prog: |
|
630 z += i |
|
631 progress(_updating, z, item=item, total=numupdates, unit=_files) |
|
632 removed = len(actions['r']) |
|
633 |
|
634 # get in parallel |
|
635 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g']) |
|
636 for i, item in prog: |
|
637 z += i |
|
638 progress(_updating, z, item=item, total=numupdates, unit=_files) |
|
639 updated = len(actions['g']) |
|
640 |
|
641 if [a for a in actions['g'] if a[0] == '.hgsubstate']: |
|
642 subrepo.submerge(repo, wctx, mctx, wctx, overwrite) |
|
643 |
|
644 # forget (manifest only, just log it) (must come first) |
|
645 for f, args, msg in actions['f']: |
|
646 repo.ui.debug(" %s: %s -> f\n" % (f, msg)) |
|
647 z += 1 |
|
648 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
649 |
|
650 # re-add (manifest only, just log it) |
|
651 for f, args, msg in actions['a']: |
|
652 repo.ui.debug(" %s: %s -> a\n" % (f, msg)) |
|
653 z += 1 |
|
654 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
655 |
|
656 # keep (noop, just log it) |
|
657 for f, args, msg in actions['k']: |
|
658 repo.ui.debug(" %s: %s -> k\n" % (f, msg)) |
|
659 # no progress |
|
660 |
|
661 # merge |
|
662 for f, args, msg in actions['m']: |
|
663 repo.ui.debug(" %s: %s -> m\n" % (f, msg)) |
|
664 z += 1 |
|
665 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
666 f1, f2, fa, move, anc = args |
|
667 if f == '.hgsubstate': # subrepo states need updating |
|
668 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), |
|
669 overwrite) |
|
670 continue |
|
671 audit(f) |
|
672 r = ms.resolve(f, wctx, labels=labels) |
|
673 if r is not None and r > 0: |
|
674 unresolved += 1 |
|
675 else: |
|
676 if r is None: |
|
677 updated += 1 |
|
678 else: |
|
679 merged += 1 |
|
680 |
|
681 # directory rename, move local |
|
682 for f, args, msg in actions['dm']: |
|
683 repo.ui.debug(" %s: %s -> dm\n" % (f, msg)) |
|
684 z += 1 |
|
685 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
686 f0, flags = args |
|
687 repo.ui.note(_("moving %s to %s\n") % (f0, f)) |
|
688 audit(f) |
|
689 repo.wwrite(f, wctx.filectx(f0).data(), flags) |
|
690 util.unlinkpath(repo.wjoin(f0)) |
|
691 updated += 1 |
|
692 |
|
693 # local directory rename, get |
|
694 for f, args, msg in actions['dg']: |
|
695 repo.ui.debug(" %s: %s -> dg\n" % (f, msg)) |
|
696 z += 1 |
|
697 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
698 f0, flags = args |
|
699 repo.ui.note(_("getting %s to %s\n") % (f0, f)) |
|
700 repo.wwrite(f, mctx.filectx(f0).data(), flags) |
|
701 updated += 1 |
|
702 |
|
703 # divergent renames |
|
704 for f, args, msg in actions['dr']: |
|
705 repo.ui.debug(" %s: %s -> dr\n" % (f, msg)) |
|
706 z += 1 |
|
707 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
708 fl, = args |
|
709 repo.ui.warn(_("note: possible conflict - %s was renamed " |
|
710 "multiple times to:\n") % f) |
|
711 for nf in fl: |
|
712 repo.ui.warn(" %s\n" % nf) |
|
713 |
|
714 # rename and delete |
|
715 for f, args, msg in actions['rd']: |
|
716 repo.ui.debug(" %s: %s -> rd\n" % (f, msg)) |
|
717 z += 1 |
|
718 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
719 fl, = args |
|
720 repo.ui.warn(_("note: possible conflict - %s was deleted " |
|
721 "and renamed to:\n") % f) |
|
722 for nf in fl: |
|
723 repo.ui.warn(" %s\n" % nf) |
|
724 |
|
725 # exec |
|
726 for f, args, msg in actions['e']: |
|
727 repo.ui.debug(" %s: %s -> e\n" % (f, msg)) |
|
728 z += 1 |
|
729 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
730 flags, = args |
|
731 audit(f) |
|
732 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) |
|
733 updated += 1 |
|
734 |
|
735 ms.commit() |
|
736 progress(_updating, None, total=numupdates, unit=_files) |
|
737 |
|
738 return updated, merged, removed, unresolved |
|
739 |
|
740 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, partial, |
525 def calculateupdates(repo, wctx, mctx, ancestors, branchmerge, force, partial, |
741 acceptremote, followcopies): |
526 acceptremote, followcopies): |
742 "Calculate the actions needed to merge mctx into wctx using ancestors" |
527 "Calculate the actions needed to merge mctx into wctx using ancestors" |
743 |
528 |
744 if len(ancestors) == 1: # default |
529 if len(ancestors) == 1: # default |
834 actions['r'].extend(ractions) |
619 actions['r'].extend(ractions) |
835 actions['f'].extend(factions) |
620 actions['f'].extend(factions) |
836 |
621 |
837 return actions |
622 return actions |
838 |
623 |
|
624 def batchremove(repo, actions): |
|
625 """apply removes to the working directory |
|
626 |
|
627 yields tuples for progress updates |
|
628 """ |
|
629 verbose = repo.ui.verbose |
|
630 unlink = util.unlinkpath |
|
631 wjoin = repo.wjoin |
|
632 audit = repo.wopener.audit |
|
633 i = 0 |
|
634 for f, args, msg in actions: |
|
635 repo.ui.debug(" %s: %s -> r\n" % (f, msg)) |
|
636 if verbose: |
|
637 repo.ui.note(_("removing %s\n") % f) |
|
638 audit(f) |
|
639 try: |
|
640 unlink(wjoin(f), ignoremissing=True) |
|
641 except OSError, inst: |
|
642 repo.ui.warn(_("update failed to remove %s: %s!\n") % |
|
643 (f, inst.strerror)) |
|
644 if i == 100: |
|
645 yield i, f |
|
646 i = 0 |
|
647 i += 1 |
|
648 if i > 0: |
|
649 yield i, f |
|
650 |
|
651 def batchget(repo, mctx, actions): |
|
652 """apply gets to the working directory |
|
653 |
|
654 mctx is the context to get from |
|
655 |
|
656 yields tuples for progress updates |
|
657 """ |
|
658 verbose = repo.ui.verbose |
|
659 fctx = mctx.filectx |
|
660 wwrite = repo.wwrite |
|
661 i = 0 |
|
662 for f, args, msg in actions: |
|
663 repo.ui.debug(" %s: %s -> g\n" % (f, msg)) |
|
664 if verbose: |
|
665 repo.ui.note(_("getting %s\n") % f) |
|
666 wwrite(f, fctx(f).data(), args[0]) |
|
667 if i == 100: |
|
668 yield i, f |
|
669 i = 0 |
|
670 i += 1 |
|
671 if i > 0: |
|
672 yield i, f |
|
673 |
|
674 def applyupdates(repo, actions, wctx, mctx, overwrite, labels=None): |
|
675 """apply the merge action list to the working directory |
|
676 |
|
677 wctx is the working copy context |
|
678 mctx is the context to be merged into the working copy |
|
679 |
|
680 Return a tuple of counts (updated, merged, removed, unresolved) that |
|
681 describes how many files were affected by the update. |
|
682 """ |
|
683 |
|
684 updated, merged, removed, unresolved = 0, 0, 0, 0 |
|
685 ms = mergestate(repo) |
|
686 ms.reset(wctx.p1().node(), mctx.node()) |
|
687 moves = [] |
|
688 for m, l in actions.items(): |
|
689 l.sort() |
|
690 |
|
691 # prescan for merges |
|
692 for f, args, msg in actions['m']: |
|
693 f1, f2, fa, move, anc = args |
|
694 if f == '.hgsubstate': # merged internally |
|
695 continue |
|
696 repo.ui.debug(" preserving %s for resolve of %s\n" % (f1, f)) |
|
697 fcl = wctx[f1] |
|
698 fco = mctx[f2] |
|
699 actx = repo[anc] |
|
700 if fa in actx: |
|
701 fca = actx[fa] |
|
702 else: |
|
703 fca = repo.filectx(f1, fileid=nullrev) |
|
704 ms.add(fcl, fco, fca, f) |
|
705 if f1 != f and move: |
|
706 moves.append(f1) |
|
707 |
|
708 audit = repo.wopener.audit |
|
709 _updating = _('updating') |
|
710 _files = _('files') |
|
711 progress = repo.ui.progress |
|
712 |
|
713 # remove renamed files after safely stored |
|
714 for f in moves: |
|
715 if os.path.lexists(repo.wjoin(f)): |
|
716 repo.ui.debug("removing %s\n" % f) |
|
717 audit(f) |
|
718 util.unlinkpath(repo.wjoin(f)) |
|
719 |
|
720 numupdates = sum(len(l) for m, l in actions.items() if m != 'k') |
|
721 |
|
722 if [a for a in actions['r'] if a[0] == '.hgsubstate']: |
|
723 subrepo.submerge(repo, wctx, mctx, wctx, overwrite) |
|
724 |
|
725 # remove in parallel (must come first) |
|
726 z = 0 |
|
727 prog = worker.worker(repo.ui, 0.001, batchremove, (repo,), actions['r']) |
|
728 for i, item in prog: |
|
729 z += i |
|
730 progress(_updating, z, item=item, total=numupdates, unit=_files) |
|
731 removed = len(actions['r']) |
|
732 |
|
733 # get in parallel |
|
734 prog = worker.worker(repo.ui, 0.001, batchget, (repo, mctx), actions['g']) |
|
735 for i, item in prog: |
|
736 z += i |
|
737 progress(_updating, z, item=item, total=numupdates, unit=_files) |
|
738 updated = len(actions['g']) |
|
739 |
|
740 if [a for a in actions['g'] if a[0] == '.hgsubstate']: |
|
741 subrepo.submerge(repo, wctx, mctx, wctx, overwrite) |
|
742 |
|
743 # forget (manifest only, just log it) (must come first) |
|
744 for f, args, msg in actions['f']: |
|
745 repo.ui.debug(" %s: %s -> f\n" % (f, msg)) |
|
746 z += 1 |
|
747 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
748 |
|
749 # re-add (manifest only, just log it) |
|
750 for f, args, msg in actions['a']: |
|
751 repo.ui.debug(" %s: %s -> a\n" % (f, msg)) |
|
752 z += 1 |
|
753 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
754 |
|
755 # keep (noop, just log it) |
|
756 for f, args, msg in actions['k']: |
|
757 repo.ui.debug(" %s: %s -> k\n" % (f, msg)) |
|
758 # no progress |
|
759 |
|
760 # merge |
|
761 for f, args, msg in actions['m']: |
|
762 repo.ui.debug(" %s: %s -> m\n" % (f, msg)) |
|
763 z += 1 |
|
764 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
765 f1, f2, fa, move, anc = args |
|
766 if f == '.hgsubstate': # subrepo states need updating |
|
767 subrepo.submerge(repo, wctx, mctx, wctx.ancestor(mctx), |
|
768 overwrite) |
|
769 continue |
|
770 audit(f) |
|
771 r = ms.resolve(f, wctx, labels=labels) |
|
772 if r is not None and r > 0: |
|
773 unresolved += 1 |
|
774 else: |
|
775 if r is None: |
|
776 updated += 1 |
|
777 else: |
|
778 merged += 1 |
|
779 |
|
780 # directory rename, move local |
|
781 for f, args, msg in actions['dm']: |
|
782 repo.ui.debug(" %s: %s -> dm\n" % (f, msg)) |
|
783 z += 1 |
|
784 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
785 f0, flags = args |
|
786 repo.ui.note(_("moving %s to %s\n") % (f0, f)) |
|
787 audit(f) |
|
788 repo.wwrite(f, wctx.filectx(f0).data(), flags) |
|
789 util.unlinkpath(repo.wjoin(f0)) |
|
790 updated += 1 |
|
791 |
|
792 # local directory rename, get |
|
793 for f, args, msg in actions['dg']: |
|
794 repo.ui.debug(" %s: %s -> dg\n" % (f, msg)) |
|
795 z += 1 |
|
796 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
797 f0, flags = args |
|
798 repo.ui.note(_("getting %s to %s\n") % (f0, f)) |
|
799 repo.wwrite(f, mctx.filectx(f0).data(), flags) |
|
800 updated += 1 |
|
801 |
|
802 # divergent renames |
|
803 for f, args, msg in actions['dr']: |
|
804 repo.ui.debug(" %s: %s -> dr\n" % (f, msg)) |
|
805 z += 1 |
|
806 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
807 fl, = args |
|
808 repo.ui.warn(_("note: possible conflict - %s was renamed " |
|
809 "multiple times to:\n") % f) |
|
810 for nf in fl: |
|
811 repo.ui.warn(" %s\n" % nf) |
|
812 |
|
813 # rename and delete |
|
814 for f, args, msg in actions['rd']: |
|
815 repo.ui.debug(" %s: %s -> rd\n" % (f, msg)) |
|
816 z += 1 |
|
817 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
818 fl, = args |
|
819 repo.ui.warn(_("note: possible conflict - %s was deleted " |
|
820 "and renamed to:\n") % f) |
|
821 for nf in fl: |
|
822 repo.ui.warn(" %s\n" % nf) |
|
823 |
|
824 # exec |
|
825 for f, args, msg in actions['e']: |
|
826 repo.ui.debug(" %s: %s -> e\n" % (f, msg)) |
|
827 z += 1 |
|
828 progress(_updating, z, item=f, total=numupdates, unit=_files) |
|
829 flags, = args |
|
830 audit(f) |
|
831 util.setflags(repo.wjoin(f), 'l' in flags, 'x' in flags) |
|
832 updated += 1 |
|
833 |
|
834 ms.commit() |
|
835 progress(_updating, None, total=numupdates, unit=_files) |
|
836 |
|
837 return updated, merged, removed, unresolved |
|
838 |
839 def recordupdates(repo, actions, branchmerge): |
839 def recordupdates(repo, actions, branchmerge): |
840 "record merge actions to the dirstate" |
840 "record merge actions to the dirstate" |
841 # remove (must come first) |
841 # remove (must come first) |
842 for f, args, msg in actions['r']: |
842 for f, args, msg in actions['r']: |
843 if branchmerge: |
843 if branchmerge: |