~lifeless/bzr/index.range_map

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

  • Committer: Robert Collins
  • Date: 2008-06-19 01:17:19 UTC
  • mfrom: (3218.1.277 +trunk)
  • Revision ID: robertc@robertcollins.net-20080619011719-1c4g4uxzzhdls2wf
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
112
112
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None)
113
113
    >>> for path, entry in i.iter_entries():
114
114
    ...     print path
115
 
    ...     assert i.path2id(path)
116
115
    ... 
117
116
    <BLANKLINE>
118
117
    src
142
141
        """
143
142
        return False, False
144
143
 
145
 
    @deprecated_method(symbol_versioning.one_zero)
146
 
    def diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,
147
 
             output_to, reverse=False):
148
 
        """Perform a diff from this to to_entry.
149
 
 
150
 
        text_diff will be used for textual difference calculation.
151
 
        This is a template method, override _diff in child classes.
152
 
        """
153
 
        self._read_tree_state(tree.id2path(self.file_id), tree)
154
 
        if to_entry:
155
 
            # cannot diff from one kind to another - you must do a removal
156
 
            # and an addif they do not match.
157
 
            assert self.kind == to_entry.kind
158
 
            to_entry._read_tree_state(to_tree.id2path(to_entry.file_id),
159
 
                                      to_tree)
160
 
        self._diff(text_diff, from_label, tree, to_label, to_entry, to_tree,
161
 
                   output_to, reverse)
162
 
 
163
144
    def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,
164
145
             output_to, reverse=False):
165
146
        """Perform a diff between two entries of the same kind."""
179
160
        for inv in previous_inventories:
180
161
            if self.file_id in inv:
181
162
                ie = inv[self.file_id]
182
 
                assert ie.file_id == self.file_id
183
163
                if ie.revision in candidates:
184
164
                    # same revision value in two different inventories:
185
165
                    # correct possible inconsistencies:
191
171
                            ie.executable = False
192
172
                    except AttributeError:
193
173
                        pass
194
 
                    # must now be the same.
195
 
                    assert candidates[ie.revision] == ie
196
174
                else:
197
175
                    # add this revision as a candidate.
198
176
                    candidates[ie.revision] = ie
199
177
        return candidates
200
178
 
201
 
    @deprecated_method(symbol_versioning.zero_ninetyone)
202
 
    def find_previous_heads(self, previous_inventories,
203
 
                            versioned_file_store,
204
 
                            transaction,
205
 
                            entry_vf=None):
206
 
        """Return the revisions and entries that directly precede this.
207
 
 
208
 
        Returned as a map from revision to inventory entry.
209
 
 
210
 
        This is a map containing the file revisions in all parents
211
 
        for which the file exists, and its revision is not a parent of
212
 
        any other. If the file is new, the set will be empty.
213
 
 
214
 
        :param versioned_file_store: A store where ancestry data on this
215
 
                                     file id can be queried.
216
 
        :param transaction: The transaction that queries to the versioned 
217
 
                            file store should be completed under.
218
 
        :param entry_vf: The entry versioned file, if its already available.
219
 
        """
220
 
        candidates = self.parent_candidates(previous_inventories)
221
 
 
222
 
        # revision:ie mapping with one revision for each head.
223
 
        heads = {}
224
 
        # common case optimisation
225
 
        if len(candidates) == 1:
226
 
            # if there is only one candidate revision found
227
 
            # then we can avoid opening the versioned file to access ancestry:
228
 
            # there cannot be any ancestors to eliminate when there is 
229
 
            # only one revision available.
230
 
            return candidates
231
 
        
232
 
        # --- what follows is now encapsulated in repository.get_graph.heads(), 
233
 
        #     but that is not accessible from here as we have no repository
234
 
        #     pointer. Note that the repository.get_graph.heads() call can return
235
 
        #     different results *at the moment* because of the kind-changing check
236
 
        #     we have in parent_candidates().
237
 
 
238
 
        # eliminate ancestors amongst the available candidates:
239
 
        # heads are those that are not an ancestor of any other candidate
240
 
        # - this provides convergence at a per-file level.
241
 
        def get_ancestors(weave, entry):
242
 
            return set(weave.get_ancestry(entry.revision, topo_sorted=False))
243
 
        # revision: ancestor list for each head
244
 
        head_ancestors = {}
245
 
        for ie in candidates.values():
246
 
            # may be an ancestor of a known head:
247
 
            already_present = 0 != len(
248
 
                [head for head in heads 
249
 
                 if ie.revision in head_ancestors[head]])
250
 
            if already_present:
251
 
                # an ancestor of an analyzed candidate.
252
 
                continue
253
 
            # not an ancestor of a known head:
254
 
            # load the versioned file for this file id if needed
255
 
            if entry_vf is None:
256
 
                entry_vf = versioned_file_store.get_weave_or_empty(
257
 
                    self.file_id, transaction)
258
 
            ancestors = get_ancestors(entry_vf, ie)
259
 
            # may knock something else out:
260
 
            check_heads = list(heads.keys())
261
 
            for head in check_heads:
262
 
                if head in ancestors:
263
 
                    # this previously discovered 'head' is not
264
 
                    # really a head - its an ancestor of the newly 
265
 
                    # found head,
266
 
                    heads.pop(head)
267
 
            head_ancestors[ie.revision] = ancestors
268
 
            heads[ie.revision] = ie
269
 
        return heads
270
 
 
271
179
    def get_tar_item(self, root, dp, now, tree):
272
180
        """Get a tarfile item and a file stream for its content."""
273
181
        item = tarfile.TarInfo(osutils.pathjoin(root, dp).encode('utf8'))
303
211
        Traceback (most recent call last):
304
212
        InvalidEntryName: Invalid entry name: src/hello.c
305
213
        """
306
 
        assert isinstance(name, basestring), name
307
214
        if '/' in name or '\\' in name:
308
215
            raise errors.InvalidEntryName(name=name)
309
216
        self.executable = False
311
218
        self.text_sha1 = None
312
219
        self.text_size = None
313
220
        self.file_id = file_id
314
 
        assert isinstance(file_id, (str, None.__class__)), \
315
 
            'bad type %r for %r' % (type(file_id), file_id)
316
221
        self.name = name
317
222
        self.text_id = text_id
318
223
        self.parent_id = parent_id
595
500
        # We can't check the length, because Weave doesn't store that
596
501
        # information, and the whole point of looking at the weave's
597
502
        # sha1sum is that we don't have to extract the text.
598
 
        if self.text_sha1 != w.get_sha1(self.revision):
 
503
        if self.text_sha1 != w.get_sha1s([self.revision])[0]:
599
504
            raise BzrCheckError('text {%s} version {%s} wrong sha1' 
600
505
                                % (self.file_id, self.revision))
601
506
        checker.checked_texts[t] = self.text_sha1
611
516
 
612
517
    def detect_changes(self, old_entry):
613
518
        """See InventoryEntry.detect_changes."""
614
 
        assert self.text_sha1 is not None
615
 
        assert old_entry.text_sha1 is not None
616
519
        text_modified = (self.text_sha1 != old_entry.text_sha1)
617
520
        meta_modified = (self.executable != old_entry.executable)
618
521
        return text_modified, meta_modified
868
771
        an id of None.
869
772
        """
870
773
        if root_id is not None:
871
 
            assert root_id.__class__ == str
872
774
            self._set_root(InventoryDirectory(root_id, u'', None))
873
775
        else:
874
776
            self.root = None
1173
1075
                                         self._byid[entry.file_id])
1174
1076
 
1175
1077
        if entry.parent_id is None:
1176
 
            assert self.root is None and len(self._byid) == 0
1177
1078
            self.root = entry
1178
1079
        else:
1179
1080
            try:
1225
1126
        False
1226
1127
        """
1227
1128
        ie = self[file_id]
1228
 
 
1229
 
        assert ie.parent_id is None or \
1230
 
            self[ie.parent_id].children[ie.name] == ie
1231
 
        
1232
1129
        del self._byid[file_id]
1233
1130
        if ie.parent_id is not None:
1234
1131
            del self[ie.parent_id].children[ie.name]
1322
1219
                if children is None:
1323
1220
                    return None
1324
1221
                cie = children[f]
1325
 
                assert cie.name == f
1326
 
                assert cie.parent_id == parent.file_id
1327
1222
                parent = cie
1328
1223
            except KeyError:
1329
1224
                # or raise an error?