121
123
def has_filename(self, filename):
122
124
"""True if the tree has given filename."""
123
raise NotImplementedError()
125
raise NotImplementedError(self.has_filename)
125
127
def has_id(self, file_id):
126
128
file_id = osutils.safe_file_id(file_id)
208
210
def _get_inventory(self):
209
211
return self._inventory
211
def get_file(self, file_id):
212
"""Return a file object for the file file_id in the tree."""
213
def get_file(self, file_id, path=None):
214
"""Return a file object for the file file_id in the tree.
216
If both file_id and path are defined, it is implementation defined as
217
to which one is used.
213
219
raise NotImplementedError(self.get_file)
215
221
def get_file_mtime(self, file_id, path=None):
222
228
raise NotImplementedError(self.get_file_mtime)
224
230
def get_file_by_path(self, path):
225
return self.get_file(self._inventory.path2id(path))
231
return self.get_file(self._inventory.path2id(path), path)
233
def iter_files_bytes(self, desired_files):
234
"""Iterate through file contents.
236
Files will not necessarily be returned in the order they occur in
237
desired_files. No specific order is guaranteed.
239
Yields pairs of identifier, bytes_iterator. identifier is an opaque
240
value supplied by the caller as part of desired_files. It should
241
uniquely identify the file version in the caller's context. (Examples:
242
an index number or a TreeTransform trans_id.)
244
bytes_iterator is an iterable of bytestrings for the file. The
245
kind of iterable and length of the bytestrings are unspecified, but for
246
this implementation, it is a tuple containing a single bytestring with
247
the complete text of the file.
249
:param desired_files: a list of (file_id, identifier) pairs
251
for file_id, identifier in desired_files:
252
# We wrap the string in a tuple so that we can return an iterable
253
# of bytestrings. (Technically, a bytestring is also an iterable
254
# of bytestrings, but iterating through each character is not
256
cur_file = (self.get_file_text(file_id),)
257
yield identifier, cur_file
227
259
def get_symlink_target(self, file_id):
228
260
"""Get the target for a given file_id.
235
267
raise NotImplementedError(self.get_symlink_target)
237
269
def annotate_iter(self, file_id):
238
"""Return an iterator of revision_id, line tuples
270
"""Return an iterator of revision_id, line tuples.
240
272
For working trees (and mutable trees in general), the special
241
273
revision_id 'current:' will be used for lines that are new in this
245
277
raise NotImplementedError(self.annotate_iter)
279
def plan_file_merge(self, file_id, other):
280
"""Generate a merge plan based on annotations.
282
If the file contains uncommitted changes in this tree, they will be
283
attributed to the 'current:' pseudo-revision. If the file contains
284
uncommitted changes in the other tree, they will be assigned to the
285
'other:' pseudo-revision.
287
from bzrlib import merge
288
annotated_a = list(self.annotate_iter(file_id,
289
_mod_revision.CURRENT_REVISION))
290
annotated_b = list(other.annotate_iter(file_id, 'other:'))
291
ancestors_a = self._get_ancestors(_mod_revision.CURRENT_REVISION)
292
ancestors_b = other._get_ancestors('other:')
293
return merge._plan_annotate_merge(annotated_a, annotated_b,
294
ancestors_a, ancestors_b)
247
296
inventory = property(_get_inventory,
248
297
doc="Inventory of this Tree")
274
323
def paths2ids(self, paths, trees=[], require_versioned=True):
275
324
"""Return all the ids that can be reached by walking from paths.
277
Each path is looked up in each this tree and any extras provided in
326
Each path is looked up in this tree and any extras provided in
278
327
trees, and this is repeated recursively: the children in an extra tree
279
328
of a directory that has been renamed under a provided path in this tree
280
are all returned, even if none exist until a provided path in this
329
are all returned, even if none exist under a provided path in this
281
330
tree, and vice versa.
283
332
:param paths: An iterable of paths to start converting to ids from.
357
406
- lstat is the stat data *if* the file was statted.
358
407
- path_from_tree_root is the path from the root of the tree.
359
- file_id is the file_id is the entry is versioned.
408
- file_id is the file_id if the entry is versioned.
360
409
- versioned_kind is the kind of the file as last recorded in the
361
410
versioning system. If 'unknown' the file is not versioned.
362
411
One of 'kind' and 'versioned_kind' must not be 'unknown'.
496
545
:param trees: The trees to find file_ids within
497
546
:param require_versioned: if true, all specified filenames must occur in
498
547
at least one tree.
499
:return: a set of (path, file ids) for the specified filenames
548
:return: a set of file ids for the specified filenames
501
550
not_versioned = []
502
551
interesting_ids = set()
517
566
def _find_children_across_trees(specified_ids, trees):
518
"""Return a set including specified ids and their children
567
"""Return a set including specified ids and their children.
520
569
All matches in all trees will be used.
547
596
Its instances have methods like 'compare' and contain references to the
548
597
source and target trees these operations are to be carried out on.
550
clients of bzrlib should not need to use InterTree directly, rather they
599
Clients of bzrlib should not need to use InterTree directly, rather they
551
600
should use the convenience methods on Tree such as 'Tree.compare()' which
552
601
will pass through to InterTree as appropriate.
594
643
return delta._compare_trees(self.source, self.target, want_unchanged,
595
644
specific_files, include_root, extra_trees=extra_trees,
645
require_versioned=require_versioned,
596
646
want_unversioned=want_unversioned)
598
648
def _iter_changes(self, include_unchanged=False,
629
679
lookup_trees = [self.source]
631
681
lookup_trees.extend(extra_trees)
632
specific_file_ids = self.target.paths2ids(specific_files,
633
lookup_trees, require_versioned=require_versioned)
682
if specific_files == []:
683
specific_file_ids = []
685
specific_file_ids = self.target.paths2ids(specific_files,
686
lookup_trees, require_versioned=require_versioned)
634
687
if want_unversioned:
635
all_unversioned = sorted([(p.split('/'), p) for p in self.target.extras()
636
if not specific_files or
688
all_unversioned = sorted([(p.split('/'), p) for p in
690
if specific_files is None or
637
691
osutils.is_inside_any(specific_files, p)])
638
692
all_unversioned = deque(all_unversioned)