34
35
ExistingLimbo, ImmortalLimbo, NoFinalPath,
35
36
UnableCreateSymlink)
36
37
from bzrlib.inventory import InventoryEntry
37
from bzrlib.osutils import (file_kind, supports_executable, pathjoin, lexists,
38
delete_any, has_symlinks)
38
from bzrlib.osutils import (
39
47
from bzrlib.progress import DummyProgress, ProgressPhase
40
48
from bzrlib.symbol_versioning import (
41
49
deprecated_function,
1432
1450
return self._transform.final_file_id(self._transform.root)
1434
1452
def all_file_ids(self):
1435
return self._transform._tree.all_file_ids()
1453
tree_ids = set(self._transform._tree.all_file_ids())
1454
tree_ids.difference_update(self._transform.tree_file_id(t)
1455
for t in self._transform._removed_id)
1456
tree_ids.update(self._transform._new_id.values())
1437
1459
def __iter__(self):
1438
1460
return iter(self.all_file_ids())
1450
1472
trees=[], require_versioned=require_versioned))
1475
def _path2trans_id(self, path):
1476
segments = splitpath(path)
1477
cur_parent = self._transform.root
1478
for cur_segment in segments:
1479
for child in self._all_children(cur_parent):
1480
if self._transform.final_name(child) == cur_segment:
1453
1487
def path2id(self, path):
1454
return self._transform._tree.path2id(path)
1488
return self._transform.final_file_id(self._path2trans_id(path))
1456
1490
def id2path(self, file_id):
1457
1491
trans_id = self._transform.trans_id_file_id(file_id)
1460
1494
except NoFinalPath:
1461
1495
raise errors.NoSuchId(self, file_id)
1497
def _all_children(self, trans_id):
1498
children = set(self._transform.iter_tree_children(trans_id))
1499
# children in the _new_parent set are provided by _by_parent.
1500
children.difference_update(self._transform._new_parent.keys())
1501
children.update(self._by_parent.get(trans_id, []))
1504
def _make_inv_entries(self, ordered_entries, specific_file_ids):
1505
for trans_id, parent_file_id in ordered_entries:
1506
file_id = self._transform.final_file_id(trans_id)
1509
if (specific_file_ids is not None
1510
and file_id not in specific_file_ids):
1513
kind = self._transform.final_kind(trans_id)
1515
kind = self._transform._tree.stored_kind(file_id)
1516
new_entry = inventory.make_entry(
1518
self._transform.final_name(trans_id),
1519
parent_file_id, file_id)
1520
yield new_entry, trans_id
1463
1522
def iter_entries_by_dir(self, specific_file_ids=None):
1464
return self._transform._tree.iter_entries_by_dir(specific_file_ids)
1523
# This may not be a maximally efficient implementation, but it is
1524
# reasonably straightforward. An implementation that grafts the
1525
# TreeTransform changes onto the tree's iter_entries_by_dir results
1526
# might be more efficient, but requires tricky inferences about stack
1528
todo = [ROOT_PARENT]
1530
while len(todo) > 0:
1532
parent_file_id = self._transform.final_file_id(parent)
1533
children = list(self._all_children(parent))
1534
paths = dict(zip(children, self._final_paths.get_paths(children)))
1535
children.sort(key=paths.get)
1536
todo.extend(reversed(children))
1537
for trans_id in children:
1538
ordered_ids.append((trans_id, parent_file_id))
1539
for entry, trans_id in self._make_inv_entries(ordered_ids,
1541
yield unicode(self._final_paths.get_path(trans_id)), entry
1466
1543
def kind(self, file_id):
1467
1544
trans_id = self._transform.trans_id_file_id(file_id)
1468
1545
return self._transform.final_kind(trans_id)
1470
1547
def stored_kind(self, file_id):
1471
return self._transform._tree.stored_kind(file_id)
1548
trans_id = self._transform.trans_id_file_id(file_id)
1550
return self._transform._new_contents[trans_id]
1552
return self._transform._tree.stored_kind(file_id)
1473
1554
def get_file_mtime(self, file_id, path=None):
1474
1555
"""See Tree.get_file_mtime"""
1487
1568
return self._transform._tree.get_file_sha1(file_id)
1489
1570
def is_executable(self, file_id, path=None):
1490
return self._transform._tree.is_executable(file_id, path)
1571
trans_id = self._transform.trans_id_file_id(file_id)
1573
return self._transform._new_executability[trans_id]
1575
return self._transform._tree.is_executable(file_id, path)
1492
1577
def path_content_summary(self, path):
1493
return self._transform._tree.path_content_summary(path)
1578
trans_id = self._path2trans_id(path)
1579
tt = self._transform
1580
tree_path = tt._tree_id_paths.get(trans_id)
1581
kind = tt._new_contents.get(trans_id)
1583
if tree_path is None or trans_id in tt._removed_contents:
1584
return 'missing', None, None, None
1585
summary = tt._tree.path_content_summary(tree_path)
1586
kind, size, executable, link_or_sha1 = summary
1589
limbo_name = tt._limbo_name(trans_id)
1590
if trans_id in tt._new_reference_revision:
1591
kind = 'tree-reference'
1593
statval = os.lstat(limbo_name)
1594
size = statval.st_size
1595
if not supports_executable():
1598
executable = statval.st_mode & S_IEXEC
1602
if kind == 'symlink':
1603
link_or_sha1 = os.readlink(limbo_name)
1604
if supports_executable():
1605
executable = tt._new_executability.get(trans_id, executable)
1606
return kind, size, executable, link_or_sha1
1495
1608
def iter_changes(self, from_tree, include_unchanged=False,
1496
1609
specific_files=None, pb=None, extra_trees=None,
1529
1642
def annotate_iter(self, file_id,
1530
1643
default_revision=_mod_revision.CURRENT_REVISION):
1531
return self._transform._tree.annotate_iter(file_id,
1532
default_revision=default_revision)
1644
changes = self._changes(file_id)
1648
changed_content, versioned, kind = (changes[2], changes[3],
1652
get_old = (kind[0] == 'file' and versioned[0])
1654
old_annotation = self._transform._tree.annotate_iter(file_id,
1655
default_revision=default_revision)
1659
return old_annotation
1660
if not changed_content:
1661
return old_annotation
1662
return annotate.reannotate([old_annotation],
1663
self.get_file(file_id).readlines(),
1534
1666
def get_symlink_target(self, file_id):
1535
1667
"""See Tree.get_symlink_target"""