~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-04-13 09:52:51 UTC
  • mfrom: (1654.1.5 integration)
  • Revision ID: pqm@pqm.ubuntu.com-20060413095251-762ef0074ed6104a
Make knit indexs safe if the sftp link gets corrupted at a bad time.

Show diffs side-by-side

added added

removed removed

Lines of Context:
830
830
            raise KnitCorrupt(self._filename, 'misaligned after writing header')
831
831
 
832
832
    def check_header(self, fp):
833
 
        line = fp.read(len(self.HEADER))
 
833
        line = fp.readline()
834
834
        if line != self.HEADER:
835
835
            raise KnitHeaderError(badline=line)
836
836
 
863
863
    this allows updates to correct version and parent information. 
864
864
    Note that the two entries may share the delta, and that successive
865
865
    annotations and references MUST point to the first entry.
 
866
 
 
867
    The index file on disc contains a header, followed by one line per knit
 
868
    record. The same revision can be present in an index file more than once.
 
869
    The first occurence gets assigned a sequence number starting from 0. 
 
870
    
 
871
    The format of a single line is
 
872
    REVISION_ID FLAGS BYTE_OFFSET LENGTH( PARENT_ID|PARENT_SEQUENCE_ID)* :\n
 
873
    REVISION_ID is a utf8-encoded revision id
 
874
    FLAGS is a comma separated list of flags about the record. Values include 
 
875
        no-eol, line-delta, fulltext.
 
876
    BYTE_OFFSET is the ascii representation of the byte offset in the data file
 
877
        that the the compressed data starts at.
 
878
    LENGTH is the ascii representation of the length of the data file.
 
879
    PARENT_ID a utf-8 revision id prefixed by a '.' that is a parent of
 
880
        REVISION_ID.
 
881
    PARENT_SEQUENCE_ID the ascii representation of the sequence number of a
 
882
        revision id already in the knit that is a parent of REVISION_ID.
 
883
    The ' :' marker is the end of record marker.
 
884
    
 
885
    partial writes:
 
886
    when a write is interrupted to the index file, it will result in a line that
 
887
    does not end in ' :'. If the ' :' is not present at the end of a line, or at
 
888
    the end of the file, then the record that is missing it will be ignored by
 
889
    the parser.
 
890
 
 
891
    When writing new records to the index file, the data is preceeded by '\n'
 
892
    to ensure that records always start on new lines even if the last write was
 
893
    interrupted. As a result its normal for the last line in the index to be
 
894
    missing a trailing newline. One can be added with no harmful effects.
866
895
    """
867
896
 
868
897
    HEADER = "# bzr knit index 7\n"
917
946
                # a check for local vs non local indexes,
918
947
                for l in fp.readlines():
919
948
                    rec = l.split()
 
949
                    if len(rec) < 5 or rec[-1] != ':':
 
950
                        # corrupt line.
 
951
                        # FIXME: in the future we should determine if its a
 
952
                        # short write - and ignore it 
 
953
                        # or a different failure, and raise. RBC 20060407
 
954
                        continue
920
955
                    count += 1
921
956
                    total += 1
922
957
                    #pb.update('read knit index', count, total)
923
958
                    # See self._parse_parents
924
959
                    parents = []
925
 
                    for value in rec[4:]:
 
960
                    for value in rec[4:-1]:
926
961
                        if '.' == value[0]:
927
962
                            # uncompressed reference
928
963
                            parents.append(value[1:])
1061
1096
        """Add a version record to the index."""
1062
1097
        self._cache_version(version_id, options, pos, size, parents)
1063
1098
 
1064
 
        content = "%s %s %s %s %s\n" % (version_id.encode('utf-8'),
 
1099
        content = "\n%s %s %s %s %s :" % (version_id.encode('utf-8'),
1065
1100
                                        ','.join(options),
1066
1101
                                        pos,
1067
1102
                                        size,