~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Aaron Bentley
  • Date: 2006-02-22 14:39:42 UTC
  • mto: (2027.1.2 revert-subpath-56549)
  • mto: This revision was merged to the branch mainline in revision 1570.
  • Revision ID: abentley@panoramicfeedback.com-20060222143942-ae72299f2de66767
Fixed build_tree with symlinks

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
815
819
        # two loops so that we do not change ourselves before verifying it
816
820
        # will be ok
817
821
        # work through in index order to make sure we get all dependencies
 
822
        names_to_join = []
 
823
        processed = 0
818
824
        for other_idx, name in enumerate(other._names):
819
825
            self._check_version_consistent(other, other_idx, name)
 
826
            sha1 = other._sha1s[other_idx]
 
827
 
 
828
            processed += 1
 
829
 
 
830
            if name in self._name_map:
 
831
                idx = self.lookup(name)
 
832
                n1 = set(map(other.idx_to_name, other._parents[other_idx]))
 
833
                n2 = set(map(self.idx_to_name, self._parents[idx]))
 
834
                if sha1 ==  self._sha1s[idx] and n1 == n2:
 
835
                        continue
 
836
 
 
837
            names_to_join.append((other_idx, name))
 
838
 
 
839
        if pb and not msg:
 
840
            msg = 'weave join'
820
841
 
821
842
        merged = 0
822
 
        processed = 0
823
843
        time0 = time.time( )
824
 
        for other_idx, name in enumerate(other._names):
 
844
        for other_idx, name in names_to_join:
825
845
            # TODO: If all the parents of the other version are already
826
846
            # present then we can avoid some work by just taking the delta
827
847
            # and adjusting the offsets.
828
848
            new_parents = self._imported_parents(other, other_idx)
829
849
            sha1 = other._sha1s[other_idx]
830
850
 
831
 
            processed += 1
 
851
            merged += 1
 
852
 
 
853
            if pb:
 
854
                pb.update(msg, merged, len(names_to_join))
832
855
           
833
 
            if name in self._names:
834
 
                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] )
837
 
                if sha1 ==  self._sha1s[idx] and n1 == n2:
838
 
                        continue
839
 
 
840
 
            merged += 1
841
856
            lines = other.get_lines(other_idx)
842
857
            self.add(name, new_parents, lines, sha1)
843
858
 
844
859
        mutter("merged = %d, processed = %d, file_id=%s; deltat=%d"%(
845
 
                merged,processed,self._weave_name, time.time( )-time0))
846
 
 
847
 
 
848
 
 
 
860
                merged, processed, self._weave_name, time.time( )-time0))
849
861
 
850
862
    def _imported_parents(self, other, other_idx):
851
863
        """Return list of parents in self corresponding to indexes in other."""
879
891
                                 % (name))
880
892
            self_parents = self._parents[this_idx]
881
893
            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()
 
894
            n1 = set([self._names[i] for i in self_parents])
 
895
            n2 = set([other._names[i] for i in other_parents])
886
896
            if n1 != n2:
887
897
                raise WeaveParentMismatch("inconsistent parents "
888
898
                    "for version {%s}: %s vs %s" % (name, n1, n2))
891
901
        else:
892
902
            return False
893
903
 
894
 
    def reweave(self, other):
895
 
        """Reweave self with other."""
896
 
        new_weave = reweave(self, other)
 
904
    def reweave(self, other, pb=None, msg=None):
 
905
        """Reweave self with other.
 
906
 
 
907
        :param other: The other weave to merge
 
908
        :param pb: An optional progress bar, indicating how far done we are
 
909
        :param msg: An optional message for the progress
 
910
        """
 
911
        new_weave = reweave(self, other, pb=pb, msg=msg)
897
912
        for attr in self.__slots__:
898
913
            setattr(self, attr, getattr(new_weave, attr))
899
914
 
900
915
 
901
 
def reweave(wa, wb):
 
916
def reweave(wa, wb, pb=None, msg=None):
902
917
    """Combine two weaves and return the result.
903
918
 
904
919
    This works even if a revision R has different parents in 
909
924
    might be possible but it should only be necessary to do 
910
925
    this operation rarely, when a new previously ghost version is 
911
926
    inserted.
 
927
 
 
928
    :param pb: An optional progress bar, indicating how far done we are
 
929
    :param msg: An optional message for the progress
912
930
    """
913
931
    wr = Weave()
914
932
    ia = ib = 0
920
938
    mutter("combined parents: %r", combined_parents)
921
939
    order = topo_sort(combined_parents.iteritems())
922
940
    mutter("order to reweave: %r", order)
923
 
    for name in order:
 
941
 
 
942
    if pb and not msg:
 
943
        msg = 'reweave'
 
944
 
 
945
    for idx, name in enumerate(order):
 
946
        if pb:
 
947
            pb.update(msg, idx, len(order))
924
948
        if name in wa._name_map:
925
949
            lines = wa.get_lines(name)
926
950
            if name in wb._name_map:
927
 
                assert lines == wb.get_lines(name)
 
951
                lines_b = wb.get_lines(name)
 
952
                if lines != lines_b:
 
953
                    mutter('Weaves differ on content. rev_id {%s}', name)
 
954
                    mutter('weaves: %s, %s', wa._weave_name, wb._weave_name)
 
955
                    import difflib
 
956
                    lines = list(difflib.unified_diff(lines, lines_b,
 
957
                            wa._weave_name, wb._weave_name))
 
958
                    mutter('lines:\n%s', ''.join(lines))
 
959
                    raise errors.WeaveTextDiffers(name, wa, wb)
928
960
        else:
929
961
            lines = wb.get_lines(name)
930
962
        wr.add(name, combined_parents[name], lines)