632 # do we need a resolve? |
633 # do we need a resolve? |
633 if self.changelog.ancestor(co, cn) != co: |
634 if self.changelog.ancestor(co, cn) != co: |
634 simple = False |
635 simple = False |
635 resolverev = self.changelog.count() |
636 resolverev = self.changelog.count() |
636 |
637 |
|
638 # resolve the manifest to determine which files |
|
639 # we care about merging |
|
640 self.ui.status("resolving manifests\n") |
|
641 ma = self.manifest.ancestor(mm, mo) |
|
642 omap = self.manifest.read(mo) # other |
|
643 amap = self.manifest.read(ma) # ancestor |
|
644 mmap = self.manifest.read(mm) # mine |
|
645 nmap = {} |
|
646 |
|
647 self.ui.debug(" ancestor %s local %s remote %s\n" % |
|
648 (short(ma), short(mm), short(mo))) |
|
649 |
|
650 for f, mid in mmap.iteritems(): |
|
651 if f in omap: |
|
652 if mid != omap[f]: |
|
653 self.ui.debug(" %s versions differ, do resolve\n" % f) |
|
654 need[f] = mid # use merged version or local version |
|
655 else: |
|
656 nmap[f] = mid # keep ours |
|
657 del omap[f] |
|
658 elif f in amap: |
|
659 if mid != amap[f]: |
|
660 r = self.ui.prompt( |
|
661 (" local changed %s which remote deleted\n" % f) + |
|
662 "(k)eep or (d)elete?", "[kd]", "k") |
|
663 if r == "k": nmap[f] = mid |
|
664 else: |
|
665 self.ui.debug("other deleted %s\n" % f) |
|
666 pass # other deleted it |
|
667 else: |
|
668 self.ui.debug("local created %s\n" %f) |
|
669 nmap[f] = mid # we created it |
|
670 |
|
671 del mmap |
|
672 |
|
673 for f, oid in omap.iteritems(): |
|
674 if f in amap: |
|
675 if oid != amap[f]: |
|
676 r = self.ui.prompt( |
|
677 ("remote changed %s which local deleted\n" % f) + |
|
678 "(k)eep or (d)elete?", "[kd]", "k") |
|
679 if r == "k": nmap[f] = oid |
|
680 else: |
|
681 pass # probably safe |
|
682 else: |
|
683 self.ui.debug("remote created %s, do resolve\n" % f) |
|
684 need[f] = oid |
|
685 |
|
686 del omap |
|
687 del amap |
|
688 |
|
689 new = need.keys() |
|
690 new.sort() |
|
691 |
637 # process the files |
692 # process the files |
638 self.ui.status("adding files\n") |
693 self.ui.status("adding files\n") |
639 new = {} |
|
640 while 1: |
694 while 1: |
641 f = getchunk(4) |
695 f = getchunk(4) |
642 if not f: break |
696 if not f: break |
643 fg = getchunk() |
697 fg = getchunk() |
644 self.ui.debug("adding %s revisions\n" % f) |
698 self.ui.debug("adding %s revisions\n" % f) |
645 fl = self.file(f) |
699 fl = self.file(f) |
646 o = fl.tip() |
700 o = fl.tip() |
647 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr) |
701 n = fl.addgroup(fg, lambda x: self.changelog.rev(x), tr) |
648 if not simple: |
702 if f in need: |
649 if o == n: continue |
703 del need[f] |
650 # this file has changed between branches, so it must be |
704 # manifest resolve determined we need to merge the tips |
651 # represented in the merge changeset |
705 nmap[f] = self.merge3(fl, f, o, n, tr, resolverev) |
652 new[f] = self.merge3(fl, f, o, n, tr, resolverev) |
706 |
|
707 if need: |
|
708 # we need to do trivial merges on local files |
|
709 for f in new: |
|
710 if f not in need: continue |
|
711 fl = self.file(f) |
|
712 nmap[f] = self.merge3(fl, f, need[f], fl.tip(), tr, resolverev) |
653 |
713 |
654 # For simple merges, we don't need to resolve manifests or changesets |
714 # For simple merges, we don't need to resolve manifests or changesets |
655 if simple: |
715 if simple: |
656 self.ui.debug("simple merge, skipping resolve\n") |
716 self.ui.debug("simple merge, skipping resolve\n") |
657 tr.close() |
717 tr.close() |
658 return |
718 return |
659 |
719 |
660 # resolve the manifest to point to all the merged files |
|
661 self.ui.status("resolving manifests\n") |
|
662 ma = self.manifest.ancestor(mm, mo) |
|
663 omap = self.manifest.read(mo) # other |
|
664 amap = self.manifest.read(ma) # ancestor |
|
665 mmap = self.manifest.read(mm) # mine |
|
666 self.ui.debug("ancestor %s local %s remote %s\n" % |
|
667 (short(ma), short(mm), short(mo))) |
|
668 nmap = {} |
|
669 |
|
670 for f, mid in mmap.iteritems(): |
|
671 if f in omap: |
|
672 if mid != omap[f]: |
|
673 self.ui.debug("%s versions differ\n" % f) |
|
674 if f in new: self.ui.debug("%s updated in resolve\n" % f) |
|
675 # use merged version or local version |
|
676 nmap[f] = new.get(f, mid) |
|
677 else: |
|
678 nmap[f] = mid # keep ours |
|
679 del omap[f] |
|
680 elif f in amap: |
|
681 if mid != amap[f]: |
|
682 r = self.ui.prompt( |
|
683 ("local changed %s which remote deleted\n" % f) + |
|
684 "(k)eep or (d)elete?", "[kd]", "k") |
|
685 if r == "k": nmap[f] = mid |
|
686 else: |
|
687 self.ui.debug("other deleted %s\n" % f) |
|
688 pass # other deleted it |
|
689 else: |
|
690 self.ui.debug("local created %s\n" %f) |
|
691 nmap[f] = mid # we created it |
|
692 |
|
693 del mmap |
|
694 |
|
695 for f, oid in omap.iteritems(): |
|
696 if f in amap: |
|
697 if oid != amap[f]: |
|
698 r = self.ui.prompt( |
|
699 ("remote changed %s which local deleted\n" % f) + |
|
700 "(k)eep or (d)elete?", "[kd]", "k") |
|
701 if r == "k": nmap[f] = oid |
|
702 else: |
|
703 pass # probably safe |
|
704 else: |
|
705 self.ui.debug("remote created %s\n" % f) |
|
706 nmap[f] = new.get(f, oid) # remote created it |
|
707 |
|
708 del omap |
|
709 del amap |
|
710 |
|
711 node = self.manifest.add(nmap, tr, resolverev, mm, mo) |
720 node = self.manifest.add(nmap, tr, resolverev, mm, mo) |
712 |
721 |
713 # Now all files and manifests are merged, we add the changed files |
722 # Now all files and manifests are merged, we add the changed files |
714 # and manifest id to the changelog |
723 # and manifest id to the changelog |
715 self.ui.status("committing merge changeset\n") |
724 self.ui.status("committing merge changeset\n") |
716 new = new.keys() |
|
717 new.sort() |
|
718 if co == cn: cn = -1 |
725 if co == cn: cn = -1 |
719 |
726 |
720 edittext = "\nHG: merge resolve\n" + \ |
727 edittext = "\nHG: merge resolve\n" + \ |
721 "".join(["HG: changed %s\n" % f for f in new]) |
728 "".join(["HG: changed %s\n" % f for f in new]) |
722 edittext = self.ui.edit(edittext) |
729 edittext = self.ui.edit(edittext) |