~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

  • Committer: Robert Collins
  • Date: 2005-10-04 04:49:21 UTC
  • Revision ID: robertc@robertcollins.net-20051004044921-45fd2dc3f70abe59
remove debug print statement

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
"""Weave - storage of related text file versions"""
23
23
 
24
24
 
 
25
# TODO: Perhaps have copy method for Weave instances?
 
26
 
25
27
# XXX: If we do weaves this way, will a merge still behave the same
26
28
# way if it's done in a different order?  That's a pretty desirable
27
29
# property.
57
59
# variant that is passed a pre-cooked version of the single basis
58
60
# version?
59
61
 
60
 
# TODO: Have a way to go back and insert a revision V1 that is a parent 
61
 
# of an already-stored revision V2.  This means some lines previously 
62
 
# counted as new in V2 will be discovered to have actually come from V1.  
63
 
# It is probably necessary to insert V1, then compute a whole new diff 
64
 
# from the mashed ancestors to V2.  This must be repeated for every 
65
 
# direct child of V1.  The deltas from V2 to its descendents won't change,
66
 
# although their location within the weave may change.  It may be possible
67
 
# to just adjust the location of those instructions rather than 
68
 
# re-weaving the whole thing.  This is expected to be a fairly rare
69
 
# operation, only used when inserting data that was previously a ghost.
70
 
 
71
 
 
72
62
 
73
63
 
74
64
import sha
186
176
        self._weave_name = weave_name
187
177
 
188
178
 
189
 
    def copy(self):
190
 
        """Return a deep copy of self.
191
 
        
192
 
        The copy can be modified without affecting the original weave."""
193
 
        other = Weave()
194
 
        other._weave = self._weave[:]
195
 
        other._parents = self._parents[:]
196
 
        other._sha1s = self._sha1s[:]
197
 
        other._names = self._names[:]
198
 
        other._name_map = self._name_map.copy()
199
 
        other._weave_name = self._weave_name
200
 
        return other
201
 
 
202
179
    def __eq__(self, other):
203
180
        if not isinstance(other, Weave):
204
181
            return False
228
205
                             (name, self._weave_name))
229
206
 
230
207
 
231
 
    def iter_names(self):
232
 
        """Yield a list of all names in this weave."""
233
 
        return iter(self._names)
234
 
 
235
208
    def idx_to_name(self, version):
236
209
        return self._names[version]
237
210
 
641
614
        If there is a chunk of the file where there's no diagreement,
642
615
        only one alternative is given.
643
616
        """
 
617
 
644
618
        # approach: find the included versions common to all the
645
619
        # merged versions
646
620
        raise NotImplementedError()
666
640
        If line1=line2, this is a pure insert; if newlines=[] this is a
667
641
        pure delete.  (Similar to difflib.)
668
642
        """
669
 
        raise NotImplementedError()
 
643
 
670
644
 
671
645
            
672
646
    def plan_merge(self, ver_a, ver_b):
766
740
                       state
767
741
 
768
742
                
769
 
    def join(self, other):
770
 
        """Integrate versions from other into this weave.
771
 
 
772
 
        The resulting weave contains all the history of both weaves; 
773
 
        any version you could retrieve from either self or other can be 
774
 
        retrieved from self after this call.
775
 
 
776
 
        It is illegal for the two weaves to contain different values 
777
 
        for any version.
778
 
        """
779
 
        if other.numversions() == 0:
780
 
            return          # nothing to update, easy
781
 
        # work through in index order to make sure we get all dependencies
782
 
        for other_idx, name in enumerate(other._names):
783
 
            # TODO: If all the parents of the other version are already 
784
 
            # present then we can avoid some work by just taking the delta
785
 
            # and adjusting the offsets.
786
 
            if self._check_version_consistent(other, other_idx, name):
787
 
                continue
788
 
            new_parents = self._imported_parents(other, other_idx)
789
 
            lines = other.get_lines(other_idx)
790
 
            sha1 = other._sha1s[other_idx]
791
 
            self.add(name, new_parents, lines, sha1)
792
 
 
793
 
 
794
 
    def _imported_parents(self, other, other_idx):
795
 
        """Return list of parents in self corresponding to indexes in other."""
796
 
        new_parents = []
797
 
        for parent_idx in other._parents[other_idx]:
798
 
            parent_name = other._names[parent_idx]
799
 
            if parent_name not in self._names:
800
 
                # should not be possible
801
 
                raise WeaveError("missing parent {%s} of {%s} in %r" 
802
 
                                 % (parent_name, other._name_map[other_idx], self))
803
 
            new_parents.append(self._name_map[parent_name])
804
 
        return new_parents
805
 
 
806
 
    def _check_version_consistent(self, other, other_idx, name):
807
 
        """Check if a version in consistent in this and other.
808
 
 
809
 
        To be consistent it must have:
810
 
 
811
 
         * the same text
812
 
         * the same direct parents (by name, not index, and disregarding
813
 
           order)
814
 
        
815
 
        If present & correct return True;
816
 
        if not present in self return False; 
817
 
        if inconsistent raise error."""
818
 
        this_idx = self._name_map.get(name, -1)
819
 
        if this_idx != -1:
820
 
            if self._sha1s[this_idx] != other._sha1s[other_idx]:
821
 
                raise WeaveError("inconsistent texts for version {%s} "
822
 
                                 "when joining weaves"
823
 
                                 % (name))
824
 
            self_parents = self._parents[this_idx]
825
 
            other_parents = other._parents[other_idx]
826
 
            n1 = [self._names[i] for i in self_parents]
827
 
            n2 = [other._names[i] for i in other_parents]
828
 
            n1.sort()
829
 
            n2.sort()
830
 
            if n1 != n2:
831
 
                raise WeaveError("inconsistent parents for version {%s}: "
832
 
                                 "%s vs %s"
833
 
                                 % (name, n1, n2))
834
 
            else:
835
 
                return True         # ok!
836
 
        else:
837
 
            return False
 
743
 
 
744
 
 
745
 
838
746
 
839
747
 
840
748
def weave_toc(w):