~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

Merge in bzrdir work to enable checkout improvements.

Show diffs side-by-side

added added

removed removed

Lines of Context:
799
799
                       state
800
800
 
801
801
 
802
 
    def join(self, other):
 
802
    def join(self, other, pb=None, msg=None):
803
803
        import sys, time
804
804
        """Integrate versions from other into this weave.
805
805
 
809
809
 
810
810
        It is illegal for the two weaves to contain different values 
811
811
        or different parents for any version.  See also reweave().
 
812
 
 
813
        :param other: The other weave to pull into this one
 
814
        :param pb: An optional progress bar
 
815
        :param msg: An optional message to display for progress
812
816
        """
813
817
        if other.numversions() == 0:
814
818
            return          # nothing to update, easy
818
822
        for other_idx, name in enumerate(other._names):
819
823
            self._check_version_consistent(other, other_idx, name)
820
824
 
 
825
        if pb and not msg:
 
826
            msg = 'weave join'
 
827
 
821
828
        merged = 0
822
829
        processed = 0
823
830
        time0 = time.time( )
829
836
            sha1 = other._sha1s[other_idx]
830
837
 
831
838
            processed += 1
832
 
           
833
 
            if name in self._names:
 
839
 
 
840
            if name in self._name_map:
834
841
                idx = self.lookup(name)
835
 
                n1 = map(other.idx_to_name, other._parents[other_idx] )
836
 
                n2 = map(self.idx_to_name, self._parents[other_idx] )
 
842
                n1 = set(map(other.idx_to_name, other._parents[other_idx]))
 
843
                n2 = set(map(self.idx_to_name, self._parents[idx]))
837
844
                if sha1 ==  self._sha1s[idx] and n1 == n2:
838
845
                        continue
839
846
 
 
847
            if pb:
 
848
                pb.update(msg, other_idx, len(other._names))
 
849
           
840
850
            merged += 1
841
851
            lines = other.get_lines(other_idx)
842
852
            self.add(name, new_parents, lines, sha1)
879
889
                                 % (name))
880
890
            self_parents = self._parents[this_idx]
881
891
            other_parents = other._parents[other_idx]
882
 
            n1 = [self._names[i] for i in self_parents]
883
 
            n2 = [other._names[i] for i in other_parents]
884
 
            n1.sort()
885
 
            n2.sort()
 
892
            n1 = set([self._names[i] for i in self_parents])
 
893
            n2 = set([other._names[i] for i in other_parents])
886
894
            if n1 != n2:
887
895
                raise WeaveParentMismatch("inconsistent parents "
888
896
                    "for version {%s}: %s vs %s" % (name, n1, n2))
891
899
        else:
892
900
            return False
893
901
 
894
 
    def reweave(self, other):
895
 
        """Reweave self with other."""
896
 
        new_weave = reweave(self, other)
 
902
    def reweave(self, other, pb=None, msg=None):
 
903
        """Reweave self with other.
 
904
 
 
905
        :param other: The other weave to merge
 
906
        :param pb: An optional progress bar, indicating how far done we are
 
907
        :param msg: An optional message for the progress
 
908
        """
 
909
        new_weave = reweave(self, other, pb=pb, msg=msg)
897
910
        for attr in self.__slots__:
898
911
            setattr(self, attr, getattr(new_weave, attr))
899
912
 
900
913
 
901
 
def reweave(wa, wb):
 
914
def reweave(wa, wb, pb=None, msg=None):
902
915
    """Combine two weaves and return the result.
903
916
 
904
917
    This works even if a revision R has different parents in 
909
922
    might be possible but it should only be necessary to do 
910
923
    this operation rarely, when a new previously ghost version is 
911
924
    inserted.
 
925
 
 
926
    :param pb: An optional progress bar, indicating how far done we are
 
927
    :param msg: An optional message for the progress
912
928
    """
913
929
    wr = Weave()
914
930
    ia = ib = 0
920
936
    mutter("combined parents: %r", combined_parents)
921
937
    order = topo_sort(combined_parents.iteritems())
922
938
    mutter("order to reweave: %r", order)
923
 
    for name in order:
 
939
 
 
940
    if pb and not msg:
 
941
        msg = 'reweave'
 
942
 
 
943
    for idx, name in enumerate(order):
 
944
        if pb:
 
945
            pb.update(msg, idx, len(order))
924
946
        if name in wa._name_map:
925
947
            lines = wa.get_lines(name)
926
948
            if name in wb._name_map:
927
 
                assert lines == wb.get_lines(name)
 
949
                lines_b = wb.get_lines(name)
 
950
                if lines != lines_b:
 
951
                    mutter('Weaves differ on content. rev_id {%s}', name)
 
952
                    mutter('weaves: %s, %s', wa._weave_name, wb._weave_name)
 
953
                    import difflib
 
954
                    lines = list(difflib.unified_diff(lines, lines_b,
 
955
                            wa._weave_name, wb._weave_name))
 
956
                    mutter('lines:\n%s', ''.join(lines))
 
957
                    raise errors.WeaveTextDiffers(name, wa, wb)
928
958
        else:
929
959
            lines = wb.get_lines(name)
930
960
        wr.add(name, combined_parents[name], lines)