Merge lp:~jelmer/brz/preview-tree into lp:brz/3.1

Proposed by Jelmer Vernooij on 2020-07-07
Status: Merged
Approved by: Jelmer Vernooij on 2020-07-07
Approved revision: 7582
Merge reported by: The Breezy Bot
Merged at revision: not available
Proposed branch: lp:~jelmer/brz/preview-tree
Merge into: lp:brz/3.1
Diff against target: 724 lines (+228/-215)
5 files modified
breezy/bzr/transform.py (+23/-190)
breezy/tests/per_tree/test_path_content_summary.py (+3/-3)
breezy/tests/per_tree/test_symlinks.py (+2/-2)
breezy/tests/per_workingtree/test_transform.py (+18/-20)
breezy/transform.py (+182/-0)
To merge this branch: bzr merge lp:~jelmer/brz/preview-tree
Reviewer Review Type Date Requested Status
Jelmer Vernooij Approve on 2020-07-07
Review via email: mp+387003@code.launchpad.net

Commit message

Factor out common PreviewTree functions.

Description of the change

Factor out common PreviewTree functions.

To post a comment you must log in.
Jelmer Vernooij (jelmer) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'breezy/bzr/transform.py'
2--- breezy/bzr/transform.py 2020-07-06 01:43:04 +0000
3+++ breezy/bzr/transform.py 2020-07-07 22:38:02 +0000
4@@ -51,6 +51,7 @@
5 ImmortalLimbo,
6 ReusingTransform,
7 MalformedTransform,
8+ PreviewTree,
9 )
10 from ..tree import TreeChange
11 from . import (
12@@ -1655,7 +1656,7 @@
13 The tree is a snapshot, and altering the TreeTransform will invalidate
14 it.
15 """
16- return _PreviewTree(self)
17+ return InventoryPreviewTree(self)
18
19 def _inventory_altered(self):
20 """Determine which trans_ids need new Inventory entries.
21@@ -1807,22 +1808,17 @@
22 raise NotImplementedError(self.new_orphan)
23
24
25-class _PreviewTree(inventorytree.InventoryTree):
26+class InventoryPreviewTree(PreviewTree, inventorytree.InventoryTree):
27 """Partial implementation of Tree to support show_diff_trees"""
28
29 def __init__(self, transform):
30- self._transform = transform
31+ PreviewTree.__init__(self, transform)
32 self._final_paths = FinalPaths(transform)
33- self.__by_parent = None
34- self._parent_ids = []
35- self._all_children_cache = {}
36- self._path2trans_id_cache = {}
37- self._final_name_cache = {}
38 self._iter_changes_cache = {
39 c.file_id: c for c in self._transform.iter_changes()}
40
41 def supports_tree_reference(self):
42- # TODO(jelmer): Support tree references in _PreviewTree.
43+ # TODO(jelmer): Support tree references in PreviewTree.
44 # return self._transform._tree.supports_tree_reference()
45 return False
46
47@@ -1831,19 +1827,6 @@
48 changes = self._iter_changes_cache.get(file_id)
49 return (changes is not None and changes.changed_content)
50
51- def _get_repository(self):
52- repo = getattr(self._transform._tree, '_repository', None)
53- if repo is None:
54- repo = self._transform._tree.branch.repository
55- return repo
56-
57- def _iter_parent_trees(self):
58- for revision_id in self.get_parent_ids():
59- try:
60- yield self.revision_tree(revision_id)
61- except errors.NoSuchRevisionInTree:
62- yield self._get_repository().revision_tree(revision_id)
63-
64 def _get_file_revision(self, path, file_id, vf, tree_revision):
65 parent_keys = [
66 (file_id, t.get_file_revision(t.id2path(file_id)))
67@@ -1860,12 +1843,6 @@
68 name = self._transform._limbo_name(trans_id)
69 return os.lstat(name)
70
71- @property
72- def _by_parent(self):
73- if self.__by_parent is None:
74- self.__by_parent = self._transform.by_parent()
75- return self.__by_parent
76-
77 def _comparison_data(self, entry, path):
78 kind, size, executable, link_or_sha1 = self.path_content_summary(path)
79 if kind == 'missing':
80@@ -1876,20 +1853,10 @@
81 executable = self.is_executable(path)
82 return kind, executable, None
83
84- def is_locked(self):
85- return False
86-
87- def lock_read(self):
88- # Perhaps in theory, this should lock the TreeTransform?
89- return lock.LogicalLockResult(self.unlock)
90-
91- def unlock(self):
92- pass
93-
94 @property
95 def root_inventory(self):
96 """This Tree does not use inventory as its backing data."""
97- raise NotImplementedError(_PreviewTree.root_inventory)
98+ raise NotImplementedError(PreviewTree.root_inventory)
99
100 def all_file_ids(self):
101 tree_ids = set(self._transform._tree.all_file_ids())
102@@ -1911,28 +1878,6 @@
103
104 return tree_paths
105
106- def _path2trans_id(self, path):
107- # We must not use None here, because that is a valid value to store.
108- trans_id = self._path2trans_id_cache.get(path, object)
109- if trans_id is not object:
110- return trans_id
111- segments = osutils.splitpath(path)
112- cur_parent = self._transform.root
113- for cur_segment in segments:
114- for child in self._all_children(cur_parent):
115- final_name = self._final_name_cache.get(child)
116- if final_name is None:
117- final_name = self._transform.final_name(child)
118- self._final_name_cache[child] = final_name
119- if final_name == cur_segment:
120- cur_parent = child
121- break
122- else:
123- self._path2trans_id_cache[path] = None
124- return None
125- self._path2trans_id_cache[path] = cur_parent
126- return cur_parent
127-
128 def path2id(self, path):
129 if isinstance(path, list):
130 if path == []:
131@@ -1947,17 +1892,6 @@
132 except NoFinalPath:
133 raise errors.NoSuchId(self, file_id)
134
135- def _all_children(self, trans_id):
136- children = self._all_children_cache.get(trans_id)
137- if children is not None:
138- return children
139- children = set(self._transform.iter_tree_children(trans_id))
140- # children in the _new_parent set are provided by _by_parent.
141- children.difference_update(self._transform._new_parent)
142- children.update(self._by_parent.get(trans_id, []))
143- self._all_children_cache[trans_id] = children
144- return children
145-
146 def extras(self):
147 possible_extras = set(self._transform.trans_id_tree_path(p) for p
148 in self._transform._tree.extras())
149@@ -2069,21 +2003,6 @@
150 for path, entry in entries:
151 yield path, 'V', entry.kind, entry
152
153- def kind(self, path):
154- trans_id = self._path2trans_id(path)
155- if trans_id is None:
156- raise errors.NoSuchFile(path)
157- return self._transform.final_kind(trans_id)
158-
159- def stored_kind(self, path):
160- trans_id = self._path2trans_id(path)
161- if trans_id is None:
162- raise errors.NoSuchFile(path)
163- try:
164- return self._transform._new_contents[trans_id]
165- except KeyError:
166- return self._transform._tree.stored_kind(path)
167-
168 def get_file_mtime(self, path):
169 """See Tree.get_file_mtime"""
170 file_id = self.path2id(path)
171@@ -2095,77 +2014,6 @@
172 trans_id = self._path2trans_id(path)
173 return self._stat_limbo_file(trans_id).st_mtime
174
175- def get_file_size(self, path):
176- """See Tree.get_file_size"""
177- trans_id = self._path2trans_id(path)
178- if trans_id is None:
179- raise errors.NoSuchFile(path)
180- kind = self._transform.final_kind(trans_id)
181- if kind != 'file':
182- return None
183- if trans_id in self._transform._new_contents:
184- return self._stat_limbo_file(trans_id).st_size
185- if self.kind(path) == 'file':
186- return self._transform._tree.get_file_size(path)
187- else:
188- return None
189-
190- def get_file_verifier(self, path, stat_value=None):
191- trans_id = self._path2trans_id(path)
192- if trans_id is None:
193- raise errors.NoSuchFile(path)
194- kind = self._transform._new_contents.get(trans_id)
195- if kind is None:
196- return self._transform._tree.get_file_verifier(path)
197- if kind == 'file':
198- with self.get_file(path) as fileobj:
199- return ("SHA1", osutils.sha_file(fileobj))
200-
201- def get_file_sha1(self, path, stat_value=None):
202- trans_id = self._path2trans_id(path)
203- if trans_id is None:
204- raise errors.NoSuchFile(path)
205- kind = self._transform._new_contents.get(trans_id)
206- if kind is None:
207- return self._transform._tree.get_file_sha1(path)
208- if kind == 'file':
209- with self.get_file(path) as fileobj:
210- return osutils.sha_file(fileobj)
211-
212- def get_reference_revision(self, path):
213- trans_id = self._path2trans_id(path)
214- if trans_id is None:
215- raise errors.NoSuchFile(path)
216- reference_revision = self._transform._new_reference_revision.get(trans_id)
217- if reference_revision is None:
218- return self._transform._tree.get_reference_revision(path)
219- return reference_revision
220-
221- def is_executable(self, path):
222- trans_id = self._path2trans_id(path)
223- if trans_id is None:
224- return False
225- try:
226- return self._transform._new_executability[trans_id]
227- except KeyError:
228- try:
229- return self._transform._tree.is_executable(path)
230- except OSError as e:
231- if e.errno == errno.ENOENT:
232- return False
233- raise
234- except errors.NoSuchFile:
235- return False
236-
237- def has_filename(self, path):
238- trans_id = self._path2trans_id(path)
239- if trans_id in self._transform._new_contents:
240- return True
241- elif trans_id in self._transform._removed_contents:
242- return False
243- else:
244- return self._transform._tree.has_filename(path)
245-
246 def path_content_summary(self, path):
247 trans_id = self._path2trans_id(path)
248 tt = self._transform
249@@ -2219,18 +2067,6 @@
250 raise ValueError('want_unversioned is not supported')
251 return self._transform.iter_changes()
252
253- def get_file(self, path):
254- """See Tree.get_file"""
255- file_id = self.path2id(path)
256- if not self._content_change(file_id):
257- return self._transform._tree.get_file(path)
258- trans_id = self._path2trans_id(path)
259- name = self._transform._limbo_name(trans_id)
260- return open(name, 'rb')
261-
262- def get_file_with_stat(self, path):
263- return self.get_file(path), None
264-
265 def annotate_iter(self, path,
266 default_revision=_mod_revision.CURRENT_REVISION):
267 file_id = self.path2id(path)
268@@ -2263,15 +2099,6 @@
269 self.get_file(path).readlines(),
270 default_revision)
271
272- def get_symlink_target(self, path):
273- """See Tree.get_symlink_target"""
274- file_id = self.path2id(path)
275- if not self._content_change(file_id):
276- return self._transform._tree.get_symlink_target(path)
277- trans_id = self._path2trans_id(path)
278- name = self._transform._limbo_name(trans_id)
279- return osutils.readlink(name)
280-
281 def walkdirs(self, prefix=''):
282 pending = [self._transform.root]
283 while len(pending) > 0:
284@@ -2302,14 +2129,20 @@
285 pending.extend(sorted(subdirs, key=self._final_paths.get_path,
286 reverse=True))
287
288- def get_parent_ids(self):
289- return self._parent_ids
290-
291- def set_parent_ids(self, parent_ids):
292- self._parent_ids = parent_ids
293-
294- def get_revision_tree(self, revision_id):
295- return self._transform._tree.get_revision_tree(revision_id)
296-
297-
298-
299+ def get_symlink_target(self, path):
300+ """See Tree.get_symlink_target"""
301+ file_id = self.path2id(path)
302+ if not self._content_change(file_id):
303+ return self._transform._tree.get_symlink_target(path)
304+ trans_id = self._path2trans_id(path)
305+ name = self._transform._limbo_name(trans_id)
306+ return osutils.readlink(name)
307+
308+ def get_file(self, path):
309+ """See Tree.get_file"""
310+ file_id = self.path2id(path)
311+ if not self._content_change(file_id):
312+ return self._transform._tree.get_file(path)
313+ trans_id = self._path2trans_id(path)
314+ name = self._transform._limbo_name(trans_id)
315+ return open(name, 'rb')
316
317=== modified file 'breezy/tests/per_tree/test_path_content_summary.py'
318--- breezy/tests/per_tree/test_path_content_summary.py 2020-07-04 12:29:00 +0000
319+++ breezy/tests/per_tree/test_path_content_summary.py 2020-07-07 22:38:02 +0000
320@@ -23,8 +23,8 @@
321 tests,
322 )
323
324-from breezy.bzr.transform import (
325- _PreviewTree,
326+from breezy.transform import (
327+ PreviewTree,
328 )
329 from breezy.tests import (
330 features,
331@@ -114,7 +114,7 @@
332 self.assertEqual('missing', summary[0])
333 self.assertIs(None, summary[2])
334 self.assertIs(None, summary[3])
335- elif isinstance(tree, _PreviewTree):
336+ elif isinstance(tree, PreviewTree):
337 self.expectFailure('PreviewTree returns "missing" for unversioned'
338 'files', self.assertEqual, 'file', summary[0])
339 self.assertEqual('file', summary[0])
340
341=== modified file 'breezy/tests/per_tree/test_symlinks.py'
342--- breezy/tests/per_tree/test_symlinks.py 2020-06-30 20:39:13 +0000
343+++ breezy/tests/per_tree/test_symlinks.py 2020-07-07 22:38:02 +0000
344@@ -27,7 +27,7 @@
345 )
346 from breezy.mutabletree import MutableTree
347 from breezy.tests import TestSkipped
348-from breezy.bzr.transform import _PreviewTree
349+from breezy.transform import PreviewTree
350 from breezy.tests import (
351 features,
352 )
353@@ -55,7 +55,7 @@
354 self.addCleanup(self.tree.unlock)
355
356 def test_symlink_target(self):
357- if isinstance(self.tree, (MutableTree, _PreviewTree)):
358+ if isinstance(self.tree, (MutableTree, PreviewTree)):
359 raise TestSkipped(
360 'symlinks not accurately represented in working trees and'
361 ' preview trees')
362
363=== modified file 'breezy/tests/per_workingtree/test_transform.py'
364--- breezy/tests/per_workingtree/test_transform.py 2020-07-06 01:43:04 +0000
365+++ breezy/tests/per_workingtree/test_transform.py 2020-07-07 22:38:02 +0000
366@@ -1140,7 +1140,7 @@
367 self.assertEqual([bar1_abspath], stat_paths)
368
369 def test_iter_changes(self):
370- self.wt.set_root_id(b'eert_toor')
371+ root_id = self.wt.path2id('')
372 transform, root = self.transform()
373 transform.new_file('old', root, [b'blah'], b'id-1', True)
374 transform.apply()
375@@ -1150,13 +1150,13 @@
376 old = transform.trans_id_tree_path('old')
377 transform.unversion_file(old)
378 self.assertEqual([(b'id-1', ('old', None), False, (True, False),
379- (b'eert_toor', b'eert_toor'),
380+ (root_id, root_id),
381 ('old', 'old'), ('file', 'file'),
382 (True, True), False)],
383 list(transform.iter_changes()))
384 transform.new_directory('new', root, b'id-1')
385 self.assertEqual([(b'id-1', ('old', 'new'), True, (True, True),
386- (b'eert_toor', b'eert_toor'), ('old', 'new'),
387+ (root_id, root_id), ('old', 'new'),
388 ('file', 'directory'),
389 (True, False), False)],
390 list(transform.iter_changes()))
391@@ -1164,7 +1164,7 @@
392 transform.finalize()
393
394 def test_iter_changes_new(self):
395- self.wt.set_root_id(b'eert_toor')
396+ root_id = self.wt.path2id('')
397 transform, root = self.transform()
398 transform.new_file('old', root, [b'blah'])
399 transform.apply()
400@@ -1173,7 +1173,7 @@
401 old = transform.trans_id_tree_path('old')
402 transform.version_file(old, file_id=b'id-1')
403 self.assertEqual([(b'id-1', (None, 'old'), False, (False, True),
404- (b'eert_toor', b'eert_toor'),
405+ (root_id, root_id),
406 ('old', 'old'), ('file', 'file'),
407 (False, False), False)],
408 list(transform.iter_changes()))
409@@ -1181,7 +1181,7 @@
410 transform.finalize()
411
412 def test_iter_changes_modifications(self):
413- self.wt.set_root_id(b'eert_toor')
414+ root_id = self.wt.path2id('')
415 transform, root = self.transform()
416 transform.new_file('old', root, [b'blah'], b'id-1')
417 transform.new_file('new', root, [b'blah'])
418@@ -1197,7 +1197,7 @@
419 # content deletion
420 transform.delete_contents(old)
421 self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
422- (b'eert_toor', b'eert_toor'),
423+ (root_id, root_id),
424 ('old', 'old'), ('file', None),
425 (False, False), False)],
426 list(transform.iter_changes()))
427@@ -1205,13 +1205,13 @@
428 # content change
429 transform.create_file([b'blah'], old)
430 self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
431- (b'eert_toor', b'eert_toor'),
432+ (root_id, root_id),
433 ('old', 'old'), ('file', 'file'),
434 (False, False), False)],
435 list(transform.iter_changes()))
436 transform.cancel_deletion(old)
437 self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
438- (b'eert_toor', b'eert_toor'),
439+ (root_id, root_id),
440 ('old', 'old'), ('file', 'file'),
441 (False, False), False)],
442 list(transform.iter_changes()))
443@@ -1223,7 +1223,7 @@
444 transform.version_file(new, file_id=b'id-1')
445 transform.adjust_path('old', root, new)
446 self.assertEqual([(b'id-1', ('old', 'old'), True, (True, True),
447- (b'eert_toor', b'eert_toor'),
448+ (root_id, root_id),
449 ('old', 'old'), ('file', 'file'),
450 (False, False), False)],
451 list(transform.iter_changes()))
452@@ -1234,7 +1234,7 @@
453 self.assertEqual([], list(transform.iter_changes()))
454 transform.set_executability(True, old)
455 self.assertEqual([(b'id-1', ('old', 'old'), False, (True, True),
456- (b'eert_toor', b'eert_toor'),
457+ (root_id, root_id),
458 ('old', 'old'), ('file', 'file'),
459 (False, True), False)],
460 list(transform.iter_changes()))
461@@ -1245,7 +1245,7 @@
462 transform.adjust_path('new', root, old)
463 transform._new_parent = {}
464 self.assertEqual([(b'id-1', ('old', 'new'), False, (True, True),
465- (b'eert_toor', b'eert_toor'),
466+ (root_id, root_id),
467 ('old', 'new'), ('file', 'file'),
468 (False, False), False)],
469 list(transform.iter_changes()))
470@@ -1256,8 +1256,7 @@
471 transform.adjust_path('new', subdir, old)
472 transform._new_name = {}
473 self.assertEqual([(b'id-1', ('old', 'subdir/old'), False,
474- (True, True), (b'eert_toor',
475- b'subdir-id'), ('old', 'old'),
476+ (True, True), (root_id, b'subdir-id'), ('old', 'old'),
477 ('file', 'file'), (False, False), False)],
478 list(transform.iter_changes()))
479 transform._new_path = {}
480@@ -1266,7 +1265,7 @@
481 transform.finalize()
482
483 def test_iter_changes_modified_bleed(self):
484- self.wt.set_root_id(b'eert_toor')
485+ root_id = self.wt.path2id('')
486 """Modified flag should not bleed from one change to another"""
487 # unfortunately, we have no guarantee that file1 (which is modified)
488 # will be applied before file2. And if it's applied after file2, it
489@@ -1283,10 +1282,10 @@
490 transform.trans_id_file_id(b'id-2'))
491 self.assertEqual(
492 [(b'id-1', (u'file1', u'file1'), True, (True, True),
493- (b'eert_toor', b'eert_toor'), ('file1', u'file1'),
494+ (root_id, root_id), ('file1', u'file1'),
495 ('file', None), (False, False), False),
496 (b'id-2', (u'file2', u'file2'), False, (True, True),
497- (b'eert_toor', b'eert_toor'), ('file2', u'file2'),
498+ (root_id, root_id), ('file2', u'file2'),
499 ('file', 'file'), (False, True), False)],
500 list(transform.iter_changes()))
501 finally:
502@@ -1294,7 +1293,7 @@
503
504 def test_iter_changes_move_missing(self):
505 """Test moving ids with no files around"""
506- self.wt.set_root_id(b'toor_eert')
507+ root_id = self.wt.path2id('')
508 # Need two steps because versioning a non-existant file is a conflict.
509 transform, root = self.transform()
510 transform.new_directory('floater', root, b'floater-id')
511@@ -1308,7 +1307,7 @@
512 transform.adjust_path('flitter', root, floater)
513 self.assertEqual([(b'floater-id', ('floater', 'flitter'), False,
514 (True, True),
515- (b'toor_eert', b'toor_eert'),
516+ (root_id, root_id),
517 ('floater', 'flitter'),
518 (None, None), (False, False), False)],
519 list(transform.iter_changes()))
520@@ -1317,7 +1316,6 @@
521
522 def test_iter_changes_pointless(self):
523 """Ensure that no-ops are not treated as modifications"""
524- self.wt.set_root_id(b'eert_toor')
525 transform, root = self.transform()
526 transform.new_file('old', root, [b'blah'], b'id-1')
527 transform.new_directory('subdir', root, b'subdir-id')
528
529=== modified file 'breezy/transform.py'
530--- breezy/transform.py 2020-07-06 01:43:04 +0000
531+++ breezy/transform.py 2020-07-07 22:38:02 +0000
532@@ -26,6 +26,7 @@
533 controldir,
534 errors,
535 lazy_import,
536+ lock,
537 osutils,
538 registry,
539 trace,
540@@ -1350,3 +1351,184 @@
541 tt.delete_contents(trans_id)
542 tt.create_hardlink(source_tree.abspath(change.path[0]), trans_id)
543 tt.apply()
544+
545+
546+class PreviewTree(object):
547+ """Preview tree."""
548+
549+ def __init__(self, transform):
550+ self._transform = transform
551+ self._parent_ids = []
552+ self.__by_parent = None
553+ self._path2trans_id_cache = {}
554+ self._all_children_cache = {}
555+ self._final_name_cache = {}
556+
557+ @property
558+ def _by_parent(self):
559+ if self.__by_parent is None:
560+ self.__by_parent = self._transform.by_parent()
561+ return self.__by_parent
562+
563+ def get_parent_ids(self):
564+ return self._parent_ids
565+
566+ def set_parent_ids(self, parent_ids):
567+ self._parent_ids = parent_ids
568+
569+ def get_revision_tree(self, revision_id):
570+ return self._transform._tree.get_revision_tree(revision_id)
571+
572+ def is_locked(self):
573+ return False
574+
575+ def lock_read(self):
576+ # Perhaps in theory, this should lock the TreeTransform?
577+ return lock.LogicalLockResult(self.unlock)
578+
579+ def unlock(self):
580+ pass
581+
582+ def _path2trans_id(self, path):
583+ # We must not use None here, because that is a valid value to store.
584+ trans_id = self._path2trans_id_cache.get(path, object)
585+ if trans_id is not object:
586+ return trans_id
587+ segments = osutils.splitpath(path)
588+ cur_parent = self._transform.root
589+ for cur_segment in segments:
590+ for child in self._all_children(cur_parent):
591+ final_name = self._final_name_cache.get(child)
592+ if final_name is None:
593+ final_name = self._transform.final_name(child)
594+ self._final_name_cache[child] = final_name
595+ if final_name == cur_segment:
596+ cur_parent = child
597+ break
598+ else:
599+ self._path2trans_id_cache[path] = None
600+ return None
601+ self._path2trans_id_cache[path] = cur_parent
602+ return cur_parent
603+
604+ def _all_children(self, trans_id):
605+ children = self._all_children_cache.get(trans_id)
606+ if children is not None:
607+ return children
608+ children = set(self._transform.iter_tree_children(trans_id))
609+ # children in the _new_parent set are provided by _by_parent.
610+ children.difference_update(self._transform._new_parent)
611+ children.update(self._by_parent.get(trans_id, []))
612+ self._all_children_cache[trans_id] = children
613+ return children
614+
615+ def get_file_with_stat(self, path):
616+ return self.get_file(path), None
617+
618+ def is_executable(self, path):
619+ trans_id = self._path2trans_id(path)
620+ if trans_id is None:
621+ return False
622+ try:
623+ return self._transform._new_executability[trans_id]
624+ except KeyError:
625+ try:
626+ return self._transform._tree.is_executable(path)
627+ except OSError as e:
628+ if e.errno == errno.ENOENT:
629+ return False
630+ raise
631+ except errors.NoSuchFile:
632+ return False
633+
634+ def has_filename(self, path):
635+ trans_id = self._path2trans_id(path)
636+ if trans_id in self._transform._new_contents:
637+ return True
638+ elif trans_id in self._transform._removed_contents:
639+ return False
640+ else:
641+ return self._transform._tree.has_filename(path)
642+
643+ def get_file_sha1(self, path, stat_value=None):
644+ trans_id = self._path2trans_id(path)
645+ if trans_id is None:
646+ raise errors.NoSuchFile(path)
647+ kind = self._transform._new_contents.get(trans_id)
648+ if kind is None:
649+ return self._transform._tree.get_file_sha1(path)
650+ if kind == 'file':
651+ with self.get_file(path) as fileobj:
652+ return osutils.sha_file(fileobj)
653+
654+ def get_file_verifier(self, path, stat_value=None):
655+ trans_id = self._path2trans_id(path)
656+ if trans_id is None:
657+ raise errors.NoSuchFile(path)
658+ kind = self._transform._new_contents.get(trans_id)
659+ if kind is None:
660+ return self._transform._tree.get_file_verifier(path)
661+ if kind == 'file':
662+ with self.get_file(path) as fileobj:
663+ return ("SHA1", osutils.sha_file(fileobj))
664+
665+ def kind(self, path):
666+ trans_id = self._path2trans_id(path)
667+ if trans_id is None:
668+ raise errors.NoSuchFile(path)
669+ return self._transform.final_kind(trans_id)
670+
671+ def stored_kind(self, path):
672+ trans_id = self._path2trans_id(path)
673+ if trans_id is None:
674+ raise errors.NoSuchFile(path)
675+ try:
676+ return self._transform._new_contents[trans_id]
677+ except KeyError:
678+ return self._transform._tree.stored_kind(path)
679+
680+ def _get_repository(self):
681+ repo = getattr(self._transform._tree, '_repository', None)
682+ if repo is None:
683+ repo = self._transform._tree.branch.repository
684+ return repo
685+
686+ def _iter_parent_trees(self):
687+ for revision_id in self.get_parent_ids():
688+ try:
689+ yield self.revision_tree(revision_id)
690+ except errors.NoSuchRevisionInTree:
691+ yield self._get_repository().revision_tree(revision_id)
692+
693+ def get_file_size(self, path):
694+ """See Tree.get_file_size"""
695+ trans_id = self._path2trans_id(path)
696+ if trans_id is None:
697+ raise errors.NoSuchFile(path)
698+ kind = self._transform.final_kind(trans_id)
699+ if kind != 'file':
700+ return None
701+ if trans_id in self._transform._new_contents:
702+ return self._stat_limbo_file(trans_id).st_size
703+ if self.kind(path) == 'file':
704+ return self._transform._tree.get_file_size(path)
705+ else:
706+ return None
707+
708+ def get_reference_revision(self, path):
709+ trans_id = self._path2trans_id(path)
710+ if trans_id is None:
711+ raise errors.NoSuchFile(path)
712+ reference_revision = self._transform._new_reference_revision.get(trans_id)
713+ if reference_revision is None:
714+ return self._transform._tree.get_reference_revision(path)
715+ return reference_revision
716+
717+ def tree_kind(self, trans_id):
718+ path = self._tree_id_paths.get(trans_id)
719+ if path is None:
720+ return None
721+ kind = self._tree.path_content_summary(path)[0]
722+ if kind == 'missing':
723+ kind = None
724+ return kind

Subscribers

People subscribed via source and target branches