1359
1356
yield self.trans_id_tree_path(childpath)
1362
class _PreviewTree(object):
1359
class _PreviewTree(tree.Tree):
1363
1360
"""Partial implementation of Tree to support show_diff_trees"""
1365
1362
def __init__(self, transform):
1366
1363
self._transform = transform
1364
self._final_paths = FinalPaths(transform)
1366
def _changes(self, file_id):
1367
for changes in self._transform.iter_changes():
1368
if changes[0] == file_id:
1371
def _content_change(self, file_id):
1372
"""Return True if the content of this file changed"""
1373
changes = self._changes(file_id)
1374
# changes[2] is true if the file content changed. See
1375
# InterTree.iter_changes.
1376
return (changes is not None and changes[2])
1378
def _get_file_revision(self, file_id, vf, tree_revision):
1379
return self._transform._tree._get_file_revision(file_id, vf,
1382
def _stat_limbo_file(self, file_id):
1383
trans_id = self._transform.trans_id_file_id(file_id)
1384
name = self._transform._limbo_name(trans_id)
1385
return os.lstat(name)
1368
1387
def lock_read(self):
1369
1388
# Perhaps in theory, this should lock the TreeTransform?
1372
1391
def unlock(self):
1395
def inventory(self):
1396
"""This Tree does not use inventory as its backing data."""
1397
raise NotImplementedError(_PreviewTree.inventory)
1399
def get_root_id(self):
1400
return self._transform.final_file_id(self._transform.root)
1402
def all_file_ids(self):
1403
return self._transform._tree.all_file_ids()
1406
return iter(self.all_file_ids())
1408
def paths2ids(self, specific_files, trees=None, require_versioned=False):
1409
"""See Tree.paths2ids"""
1410
to_find = set(specific_files)
1412
for (file_id, paths, changed, versioned, parent, name, kind,
1413
executable) in self._transform.iter_changes():
1414
if paths[1] in to_find:
1415
result.append(file_id)
1416
to_find.remove(paths[1])
1417
result.update(self._transform._tree.paths2ids(to_find,
1418
trees=[], require_versioned=require_versioned))
1421
def path2id(self, path):
1422
return self._transform._tree.path2id(path)
1424
def id2path(self, file_id):
1425
trans_id = self._transform.trans_id_file_id(file_id)
1427
return self._final_paths._determine_path(trans_id)
1429
raise errors.NoSuchId(self, file_id)
1431
def iter_entries_by_dir(self, specific_file_ids=None):
1432
return self._transform._tree.iter_entries_by_dir(specific_file_ids)
1434
def kind(self, file_id):
1435
trans_id = self._transform.trans_id_file_id(file_id)
1436
return self._transform.final_kind(trans_id)
1438
def stored_kind(self, file_id):
1439
return self._transform._tree.stored_kind(file_id)
1441
def get_file_mtime(self, file_id, path=None):
1442
"""See Tree.get_file_mtime"""
1443
if not self._content_change(file_id):
1444
return self._transform._tree.get_file_mtime(file_id, path)
1445
return self._stat_limbo_file(file_id).st_mtime
1447
def get_file_size(self, file_id):
1448
"""See Tree.get_file_size"""
1449
if self.kind(file_id) == 'file':
1450
return self._transform._tree.get_file_size(file_id)
1454
def get_file_sha1(self, file_id, path=None, stat_value=None):
1455
return self._transform._tree.get_file_sha1(file_id)
1457
def is_executable(self, file_id, path=None):
1458
return self._transform._tree.is_executable(file_id, path)
1460
def path_content_summary(self, path):
1461
return self._transform._tree.path_content_summary(path)
1375
1463
def iter_changes(self, from_tree, include_unchanged=False,
1376
1464
specific_files=None, pb=None, extra_trees=None,
1377
1465
require_versioned=True, want_unversioned=False):
1391
1479
raise ValueError('want_unversioned is not supported')
1392
1480
return self._transform.iter_changes()
1394
def kind(self, file_id):
1395
trans_id = self._transform.trans_id_file_id(file_id)
1396
return self._transform.final_kind(trans_id)
1398
def get_file_mtime(self, file_id, path=None):
1399
"""See Tree.get_file_mtime"""
1400
trans_id = self._transform.trans_id_file_id(file_id)
1401
name = self._transform._limbo_name(trans_id)
1402
return os.stat(name).st_mtime
1404
def get_file(self, file_id):
1482
def get_file(self, file_id, path=None):
1405
1483
"""See Tree.get_file"""
1484
if not self._content_change(file_id):
1485
return self._transform._tree.get_file(file_id, path)
1406
1486
trans_id = self._transform.trans_id_file_id(file_id)
1407
1487
name = self._transform._limbo_name(trans_id)
1408
1488
return open(name, 'rb')
1490
def get_file_text(self, file_id):
1491
text_file = self.get_file(file_id)
1493
return text_file.read()
1497
def annotate_iter(self, file_id,
1498
default_revision=_mod_revision.CURRENT_REVISION):
1499
return self._transform._tree.annotate_iter(file_id,
1500
default_revision=default_revision)
1410
1502
def get_symlink_target(self, file_id):
1411
1503
"""See Tree.get_symlink_target"""
1504
if not self._content_change(file_id):
1505
return self._transform._tree.get_symlink_target(file_id)
1412
1506
trans_id = self._transform.trans_id_file_id(file_id)
1413
1507
name = self._transform._limbo_name(trans_id)
1414
1508
return os.readlink(name)
1416
def paths2ids(self, specific_files, trees=None, require_versioned=False):
1417
"""See Tree.paths2ids"""
1510
def list_files(self, include_root=False):
1511
return self._transform._tree.list_files(include_root)
1513
def walkdirs(self, prefix=""):
1514
return self._transform._tree.walkdirs(prefix)
1516
def get_parent_ids(self):
1517
return self._transform._tree.get_parent_ids()
1519
def get_revision_tree(self, revision_id):
1520
return self._transform._tree.get_revision_tree(revision_id)
1421
1523
def joinpath(parent, child):
1664
1766
new_conflicts = set()
1665
1767
for c_type, conflict in ((c[0], c) for c in conflicts):
1666
1768
# Anything but a 'duplicate' would indicate programmer error
1667
assert c_type == 'duplicate', c_type
1769
if c_type != 'duplicate':
1770
raise AssertionError(c_type)
1668
1771
# Now figure out which is new and which is old
1669
1772
if tt.new_contents(conflict[1]):
1670
1773
new_file = conflict[1]
1728
1831
tt.set_executability(entry.executable, trans_id)
1731
@deprecated_function(zero_fifteen)
1732
def find_interesting(working_tree, target_tree, filenames):
1733
"""Find the ids corresponding to specified filenames.
1735
Deprecated: Please use tree1.paths2ids(filenames, [tree2]).
1737
working_tree.lock_read()
1739
target_tree.lock_read()
1741
return working_tree.paths2ids(filenames, [target_tree])
1743
target_tree.unlock()
1745
working_tree.unlock()
1748
@deprecated_function(zero_ninety)
1749
def change_entry(tt, file_id, working_tree, target_tree,
1750
trans_id_file_id, backups, trans_id, by_parent):
1751
"""Replace a file_id's contents with those from a target tree."""
1752
if file_id is None and target_tree is None:
1753
# skip the logic altogether in the deprecation test
1755
e_trans_id = trans_id_file_id(file_id)
1756
entry = target_tree.inventory[file_id]
1757
has_contents, contents_mod, meta_mod, = _entry_changes(file_id, entry,
1760
mode_id = e_trans_id
1763
tt.delete_contents(e_trans_id)
1765
parent_trans_id = trans_id_file_id(entry.parent_id)
1766
backup_name = get_backup_name(entry, by_parent,
1767
parent_trans_id, tt)
1768
tt.adjust_path(backup_name, parent_trans_id, e_trans_id)
1769
tt.unversion_file(e_trans_id)
1770
e_trans_id = tt.create_path(entry.name, parent_trans_id)
1771
tt.version_file(file_id, e_trans_id)
1772
trans_id[file_id] = e_trans_id
1773
create_by_entry(tt, entry, target_tree, e_trans_id, mode_id=mode_id)
1774
create_entry_executability(tt, entry, e_trans_id)
1777
tt.set_executability(entry.executable, e_trans_id)
1778
if tt.final_name(e_trans_id) != entry.name:
1781
parent_id = tt.final_parent(e_trans_id)
1782
parent_file_id = tt.final_file_id(parent_id)
1783
if parent_file_id != entry.parent_id:
1788
parent_trans_id = trans_id_file_id(entry.parent_id)
1789
tt.adjust_path(entry.name, parent_trans_id, e_trans_id)
1792
1834
def get_backup_name(entry, by_parent, parent_trans_id, tt):
1793
1835
return _get_backup_name(entry.name, by_parent, parent_trans_id, tt)
1942
1984
# preserve the execute bit when backing up
1943
1985
if keep_content and executable[0] == executable[1]:
1944
1986
tt.set_executability(executable[1], trans_id)
1946
assert kind[1] is None
1987
elif kind[1] is not None:
1988
raise AssertionError(kind[1])
1947
1989
if versioned == (False, True):
1948
1990
tt.version_file(file_id, trans_id)
1949
1991
if versioned == (True, False):