/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/weave.py

remove all trailing whitespace from bzr source

Show diffs side-by-side

added added

removed removed

Lines of Context:
61
61
# where the basis and destination are unchanged.
62
62
 
63
63
# FIXME: Sometimes we will be given a parents list for a revision
64
 
# that includes some redundant parents (i.e. already a parent of 
65
 
# something in the list.)  We should eliminate them.  This can 
 
64
# that includes some redundant parents (i.e. already a parent of
 
65
# something in the list.)  We should eliminate them.  This can
66
66
# be done fairly efficiently because the sequence numbers constrain
67
67
# the possible relationships.
68
68
 
131
131
 
132
132
class Weave(VersionedFile):
133
133
    """weave - versioned text file storage.
134
 
    
 
134
 
135
135
    A Weave manages versions of line-based text files, keeping track
136
136
    of the originating version for each line.
137
137
 
183
183
 
184
184
    * It doesn't seem very useful to have an active insertion
185
185
      inside an inactive insertion, but it might happen.
186
 
      
 
186
 
187
187
    * Therefore, all instructions are always"considered"; that
188
188
      is passed onto and off the stack.  An outer inactive block
189
189
      doesn't disable an inner block.
259
259
 
260
260
    def copy(self):
261
261
        """Return a deep copy of self.
262
 
        
 
262
 
263
263
        The copy can be modified without affecting the original weave."""
264
264
        other = Weave()
265
265
        other._weave = self._weave[:]
275
275
            return False
276
276
        return self._parents == other._parents \
277
277
               and self._weave == other._weave \
278
 
               and self._sha1s == other._sha1s 
279
 
    
 
278
               and self._sha1s == other._sha1s
 
279
 
280
280
    def __ne__(self, other):
281
281
        return not self.__eq__(other)
282
282
 
349
349
    def insert_record_stream(self, stream):
350
350
        """Insert a record stream into this versioned file.
351
351
 
352
 
        :param stream: A stream of records to insert. 
 
352
        :param stream: A stream of records to insert.
353
353
        :return: None
354
354
        :seealso VersionedFile.get_record_stream:
355
355
        """
399
399
 
400
400
    def _add(self, version_id, lines, parents, sha1=None, nostore_sha=None):
401
401
        """Add a single text on top of the weave.
402
 
  
 
402
 
403
403
        Returns the index number of the newly added version.
404
404
 
405
405
        version_id
408
408
 
409
409
        parents
410
410
            List or set of direct parent version numbers.
411
 
            
 
411
 
412
412
        lines
413
413
            Sequence of lines to be added in the new version.
414
414
 
436
436
        self._names.append(version_id)
437
437
        self._name_map[version_id] = new_version
438
438
 
439
 
            
 
439
 
440
440
        if not parents:
441
441
            # special case; adding with no parents revision; can do
442
442
            # this more quickly by just appending unconditionally.
453
453
            if sha1 == self._sha1s[pv]:
454
454
                # special case: same as the single parent
455
455
                return new_version
456
 
            
 
456
 
457
457
 
458
458
        ancestors = self._inclusions(parents)
459
459
 
508
508
                # i2; we want to insert after this region to make sure
509
509
                # we don't destroy ourselves
510
510
                i = i2 + offset
511
 
                self._weave[i:i] = ([('{', new_version)] 
512
 
                                    + lines[j1:j2] 
 
511
                self._weave[i:i] = ([('{', new_version)]
 
512
                                    + lines[j1:j2]
513
513
                                    + [('}', None)])
514
514
                offset += 2 + (j2 - j1)
515
515
        return new_version
542
542
            if not isinstance(l, basestring):
543
543
                raise ValueError("text line should be a string or unicode, not %s"
544
544
                                 % type(l))
545
 
        
 
545
 
546
546
 
547
547
 
548
548
    def _check_versions(self, indexes):
556
556
    def _compatible_parents(self, my_parents, other_parents):
557
557
        """During join check that other_parents are joinable with my_parents.
558
558
 
559
 
        Joinable is defined as 'is a subset of' - supersets may require 
 
559
        Joinable is defined as 'is a subset of' - supersets may require
560
560
        regeneration of diffs, but subsets do not.
561
561
        """
562
562
        return len(other_parents.difference(my_parents)) == 0
587
587
 
588
588
    def _walk_internal(self, version_ids=None):
589
589
        """Helper method for weave actions."""
590
 
        
 
590
 
591
591
        istack = []
592
592
        dset = set()
593
593
 
674
674
        for i in versions:
675
675
            if not isinstance(i, int):
676
676
                raise ValueError(i)
677
 
            
 
677
 
678
678
        included = self._inclusions(versions)
679
679
 
680
680
        istack = []
689
689
 
690
690
        WFE = WeaveFormatError
691
691
 
692
 
        # wow. 
 
692
        # wow.
693
693
        #  449       0   4474.6820   2356.5590   bzrlib.weave:556(_extract)
694
694
        #  +285282   0   1676.8040   1676.8040   +<isinstance>
695
695
        # 1.6 seconds in 'isinstance'.
701
701
        # we're still spending ~1/4 of the method in isinstance though.
702
702
        # so lets hard code the acceptable string classes we expect:
703
703
        #  449       0   1202.9420    786.2930   bzrlib.weave:556(_extract)
704
 
        # +71352     0    377.5560    377.5560   +<method 'append' of 'list' 
 
704
        # +71352     0    377.5560    377.5560   +<method 'append' of 'list'
705
705
        #                                          objects>
706
706
        # yay, down to ~1/4 the initial extract time, and our inline time
707
707
        # has shrunk again, with isinstance no longer dominating.
708
708
        # tweaking the stack inclusion test to use a set gives:
709
709
        #  449       0   1122.8030    713.0080   bzrlib.weave:556(_extract)
710
 
        # +71352     0    354.9980    354.9980   +<method 'append' of 'list' 
 
710
        # +71352     0    354.9980    354.9980   +<method 'append' of 'list'
711
711
        #                                          objects>
712
712
        # - a 5% win, or possibly just noise. However with large istacks that
713
713
        # 'in' test could dominate, so I'm leaving this change in place -
714
714
        # when its fast enough to consider profiling big datasets we can review.
715
715
 
716
 
              
717
 
             
 
716
 
 
717
 
718
718
 
719
719
        for l in self._weave:
720
720
            if l.__class__ == tuple:
749
749
 
750
750
    def _maybe_lookup(self, name_or_index):
751
751
        """Convert possible symbolic name to index, or pass through indexes.
752
 
        
 
752
 
753
753
        NOT FOR PUBLIC USE.
754
754
        """
755
755
        if isinstance(name_or_index, (int, long)):
765
765
        measured_sha1 = sha_strings(result)
766
766
        if measured_sha1 != expected_sha1:
767
767
            raise errors.WeaveInvalidChecksum(
768
 
                    'file %s, revision %s, expected: %s, measured %s' 
 
768
                    'file %s, revision %s, expected: %s, measured %s'
769
769
                    % (self._weave_name, version_id,
770
770
                       expected_sha1, measured_sha1))
771
771
        return result
813
813
 
814
814
            if set(new_inc) != set(self.get_ancestry(name)):
815
815
                raise AssertionError(
816
 
                    'failed %s != %s' 
 
816
                    'failed %s != %s'
817
817
                    % (set(new_inc), set(self.get_ancestry(name))))
818
818
            inclusions[name] = new_inc
819
819
 
857
857
            parent_name = other._names[parent_idx]
858
858
            if parent_name not in self._name_map:
859
859
                # should not be possible
860
 
                raise WeaveError("missing parent {%s} of {%s} in %r" 
 
860
                raise WeaveError("missing parent {%s} of {%s} in %r"
861
861
                                 % (parent_name, other._name_map[other_idx], self))
862
862
            new_parents.append(self._name_map[parent_name])
863
863
        return new_parents
870
870
         * the same text
871
871
         * the same direct parents (by name, not index, and disregarding
872
872
           order)
873
 
        
 
873
 
874
874
        If present & correct return True;
875
 
        if not present in self return False; 
 
875
        if not present in self return False;
876
876
        if inconsistent raise error."""
877
877
        this_idx = self._name_map.get(name, -1)
878
878
        if this_idx != -1:
911
911
    """A WeaveFile represents a Weave on disk and writes on change."""
912
912
 
913
913
    WEAVE_SUFFIX = '.weave'
914
 
    
 
914
 
915
915
    def __init__(self, name, transport, filemode=None, create=False, access_mode='w', get_scope=None):
916
916
        """Create a WeaveFile.
917
 
        
 
917
 
918
918
        :param create: If not True, only open an existing knit.
919
919
        """
920
920
        super(WeaveFile, self).__init__(name, access_mode, get_scope=get_scope,
981
981
def _reweave(wa, wb, pb=None, msg=None):
982
982
    """Combine two weaves and return the result.
983
983
 
984
 
    This works even if a revision R has different parents in 
 
984
    This works even if a revision R has different parents in
985
985
    wa and wb.  In the resulting weave all the parents are given.
986
986
 
987
 
    This is done by just building up a new weave, maintaining ordering 
 
987
    This is done by just building up a new weave, maintaining ordering
988
988
    of the versions in the two inputs.  More efficient approaches
989
 
    might be possible but it should only be necessary to do 
990
 
    this operation rarely, when a new previously ghost version is 
 
989
    might be possible but it should only be necessary to do
 
990
    this operation rarely, when a new previously ghost version is
991
991
    inserted.
992
992
 
993
993
    :param pb: An optional progress bar, indicating how far done we are
1029
1029
 
1030
1030
def _reweave_parent_graphs(wa, wb):
1031
1031
    """Return combined parent ancestry for two weaves.
1032
 
    
 
1032
 
1033
1033
    Returned as a list of (version_name, set(parent_names))"""
1034
1034
    combined = {}
1035
1035
    for weave in [wa, wb]:
1100
1100
        Display origin of each line.
1101
1101
    weave merge WEAVEFILE VERSION1 VERSION2 > OUT
1102
1102
        Auto-merge two versions and display conflicts.
1103
 
    weave diff WEAVEFILE VERSION1 VERSION2 
 
1103
    weave diff WEAVEFILE VERSION1 VERSION2
1104
1104
        Show differences between two versions.
1105
1105
 
1106
1106
example:
1123
1123
 
1124
1124
    % weave merge foo.weave 1 2 > foo.txt   (merge them)
1125
1125
    % vi foo.txt                            (resolve conflicts)
1126
 
    % weave add foo.weave merged 1 2 < foo.txt     (commit merged version)     
1127
 
    
 
1126
    % weave add foo.weave merged 1 2 < foo.txt     (commit merged version)
 
1127
 
1128
1128
"""
1129
 
    
 
1129
 
1130
1130
 
1131
1131
 
1132
1132
def main(argv):
1155
1155
 
1156
1156
    def readit():
1157
1157
        return read_weave(file(argv[2], 'rb'))
1158
 
    
 
1158
 
1159
1159
    if cmd == 'help':
1160
1160
        usage()
1161
1161
    elif cmd == 'add':
1176
1176
    elif cmd == 'get': # get one version
1177
1177
        w = readit()
1178
1178
        sys.stdout.writelines(w.get_iter(int(argv[3])))
1179
 
        
 
1179
 
1180
1180
    elif cmd == 'diff':
1181
1181
        w = readit()
1182
1182
        fn = argv[2]
1187
1187
                                '%s version %d' % (fn, v1),
1188
1188
                                '%s version %d' % (fn, v2))
1189
1189
        sys.stdout.writelines(diff_gen)
1190
 
            
 
1190
 
1191
1191
    elif cmd == 'annotate':
1192
1192
        w = readit()
1193
1193
        # newline is added to all lines regardless; too hard to get
1200
1200
            else:
1201
1201
                print '%5d | %s' % (origin, text)
1202
1202
                lasto = origin
1203
 
                
 
1203
 
1204
1204
    elif cmd == 'toc':
1205
1205
        weave_toc(readit())
1206
1206
 
1207
1207
    elif cmd == 'stats':
1208
1208
        weave_stats(argv[2], ProgressBar())
1209
 
        
 
1209
 
1210
1210
    elif cmd == 'check':
1211
1211
        w = readit()
1212
1212
        pb = ProgressBar()
1235
1235
        sys.stdout.writelines(w.weave_merge(p))
1236
1236
    else:
1237
1237
        raise ValueError('unknown command %r' % cmd)
1238
 
    
 
1238
 
1239
1239
 
1240
1240
if __name__ == '__main__':
1241
1241
    import sys