~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/versionedfile.py

  • Committer: Jelmer Vernooij
  • Date: 2007-09-16 19:29:00 UTC
  • mfrom: (2823 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2824.
  • Revision ID: jelmer@samba.org-20070916192900-fph1i2wsytberyyl
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
77
77
        """Returns whether version is present."""
78
78
        raise NotImplementedError(self.has_version)
79
79
 
80
 
    def add_delta(self, version_id, parents, delta_parent, sha1, noeol, delta):
81
 
        """Add a text to the versioned file via a pregenerated delta.
82
 
 
83
 
        :param version_id: The version id being added.
84
 
        :param parents: The parents of the version_id.
85
 
        :param delta_parent: The parent this delta was created against.
86
 
        :param sha1: The sha1 of the full text.
87
 
        :param delta: The delta instructions. See get_delta for details.
88
 
        """
89
 
        version_id = osutils.safe_revision_id(version_id)
90
 
        parents = [osutils.safe_revision_id(v) for v in parents]
91
 
        self._check_write_ok()
92
 
        if self.has_version(version_id):
93
 
            raise errors.RevisionAlreadyPresent(version_id, self)
94
 
        return self._add_delta(version_id, parents, delta_parent, sha1, noeol, delta)
95
 
 
96
 
    def _add_delta(self, version_id, parents, delta_parent, sha1, noeol, delta):
97
 
        """Class specific routine to add a delta.
98
 
 
99
 
        This generic version simply applies the delta to the delta_parent and
100
 
        then inserts it.
101
 
        """
102
 
        # strip annotation from delta
103
 
        new_delta = []
104
 
        for start, stop, delta_len, delta_lines in delta:
105
 
            new_delta.append((start, stop, delta_len, [text for origin, text in delta_lines]))
106
 
        if delta_parent is not None:
107
 
            parent_full = self.get_lines(delta_parent)
108
 
        else:
109
 
            parent_full = []
110
 
        new_full = self._apply_delta(parent_full, new_delta)
111
 
        # its impossible to have noeol on an empty file
112
 
        if noeol and new_full[-1][-1] == '\n':
113
 
            new_full[-1] = new_full[-1][:-1]
114
 
        self.add_lines(version_id, parents, new_full)
115
 
 
116
80
    def add_lines(self, version_id, parents, lines, parent_texts=None,
117
 
                  left_matching_blocks=None):
 
81
        left_matching_blocks=None, nostore_sha=None, random_id=False,
 
82
        check_content=True):
118
83
        """Add a single text on top of the versioned file.
119
84
 
120
85
        Must raise RevisionAlreadyPresent if the new version is
122
87
 
123
88
        Must raise RevisionNotPresent if any of the given parents are
124
89
        not present in file history.
 
90
 
 
91
        :param lines: A list of lines. Each line must be a bytestring. And all
 
92
            of them except the last must be terminated with \n and contain no
 
93
            other \n's. The last line may either contain no \n's or a single
 
94
            terminated \n. If the lines list does meet this constraint the add
 
95
            routine may error or may succeed - but you will be unable to read
 
96
            the data back accurately. (Checking the lines have been split
 
97
            correctly is expensive and extremely unlikely to catch bugs so it
 
98
            is not done at runtime unless check_content is True.)
125
99
        :param parent_texts: An optional dictionary containing the opaque 
126
 
             representations of some or all of the parents of 
127
 
             version_id to allow delta optimisations. 
128
 
             VERY IMPORTANT: the texts must be those returned
129
 
             by add_lines or data corruption can be caused.
 
100
            representations of some or all of the parents of version_id to
 
101
            allow delta optimisations.  VERY IMPORTANT: the texts must be those
 
102
            returned by add_lines or data corruption can be caused.
130
103
        :param left_matching_blocks: a hint about which areas are common
131
104
            between the text and its left-hand-parent.  The format is
132
105
            the SequenceMatcher.get_matching_blocks format.
 
106
        :param nostore_sha: Raise ExistingContent and do not add the lines to
 
107
            the versioned file if the digest of the lines matches this.
 
108
        :param random_id: If True a random id has been selected rather than
 
109
            an id determined by some deterministic process such as a converter
 
110
            from a foreign VCS. When True the backend may choose not to check
 
111
            for uniqueness of the resulting key within the versioned file, so
 
112
            this should only be done when the result is expected to be unique
 
113
            anyway.
 
114
        :param check_content: If True, the lines supplied are verified to be
 
115
            bytestrings that are correctly formed lines.
133
116
        :return: The text sha1, the number of bytes in the text, and an opaque
134
117
                 representation of the inserted version which can be provided
135
118
                 back to future add_lines calls in the parent_texts dictionary.
138
121
        parents = [osutils.safe_revision_id(v) for v in parents]
139
122
        self._check_write_ok()
140
123
        return self._add_lines(version_id, parents, lines, parent_texts,
141
 
                               left_matching_blocks)
 
124
            left_matching_blocks, nostore_sha, random_id, check_content)
142
125
 
143
126
    def _add_lines(self, version_id, parents, lines, parent_texts,
144
 
                   left_matching_blocks):
 
127
        left_matching_blocks, nostore_sha, random_id, check_content):
145
128
        """Helper to do the class specific add_lines."""
146
129
        raise NotImplementedError(self.add_lines)
147
130
 
148
131
    def add_lines_with_ghosts(self, version_id, parents, lines,
149
 
                              parent_texts=None):
 
132
        parent_texts=None, nostore_sha=None, random_id=False,
 
133
        check_content=True):
150
134
        """Add lines to the versioned file, allowing ghosts to be present.
151
135
        
152
 
        This takes the same parameters as add_lines.
 
136
        This takes the same parameters as add_lines and returns the same.
153
137
        """
154
138
        version_id = osutils.safe_revision_id(version_id)
155
139
        parents = [osutils.safe_revision_id(v) for v in parents]
156
140
        self._check_write_ok()
157
141
        return self._add_lines_with_ghosts(version_id, parents, lines,
158
 
                                           parent_texts)
 
142
            parent_texts, nostore_sha, random_id, check_content)
159
143
 
160
 
    def _add_lines_with_ghosts(self, version_id, parents, lines, parent_texts):
 
144
    def _add_lines_with_ghosts(self, version_id, parents, lines, parent_texts,
 
145
        nostore_sha, random_id, check_content):
161
146
        """Helper to do class specific add_lines_with_ghosts."""
162
147
        raise NotImplementedError(self.add_lines_with_ghosts)
163
148
 
241
226
        """Helper for fix_parents."""
242
227
        raise NotImplementedError(self.fix_parents)
243
228
 
244
 
    def get_delta(self, version):
245
 
        """Get a delta for constructing version from some other version.
246
 
        
247
 
        :return: (delta_parent, sha1, noeol, delta)
248
 
        Where delta_parent is a version id or None to indicate no parent.
249
 
        """
250
 
        raise NotImplementedError(self.get_delta)
251
 
 
252
 
    def get_deltas(self, version_ids):
253
 
        """Get multiple deltas at once for constructing versions.
254
 
        
255
 
        :return: dict(version_id:(delta_parent, sha1, noeol, delta))
256
 
        Where delta_parent is a version id or None to indicate no parent, and
257
 
        version_id is the version_id created by that delta.
258
 
        """
259
 
        result = {}
260
 
        for version_id in version_ids:
261
 
            result[version_id] = self.get_delta(version_id)
262
 
        return result
263
 
 
264
229
    def get_format_signature(self):
265
230
        """Get a text description of the data encoding in this file.
266
231
        
684
649
            # TODO: remove parent texts when they are not relevant any more for 
685
650
            # memory pressure reduction. RBC 20060313
686
651
            # pb.update('Converting versioned data', 0, len(order))
687
 
            # deltas = self.source.get_deltas(order)
688
652
            for index, version in enumerate(order):
689
653
                pb.update('Converting versioned data', index, len(order))
690
654
                _, _, parent_text = target.add_lines(version,
692
656
                                               self.source.get_lines(version),
693
657
                                               parent_texts=parent_texts)
694
658
                parent_texts[version] = parent_text
695
 
                #delta_parent, sha1, noeol, delta = deltas[version]
696
 
                #target.add_delta(version,
697
 
                #                 self.source.get_parents(version),
698
 
                #                 delta_parent,
699
 
                #                 sha1,
700
 
                #                 noeol,
701
 
                #                 delta)
702
 
                #target.get_lines(version)
703
659
            
704
660
            # this should hit the native code path for target
705
661
            if target is not self.target: