1269
1195
self.finalize()
1270
1196
return _TransformResults(modified_paths, self.rename_count)
1272
def _generate_inventory_delta(self):
1273
"""Generate an inventory delta for the current transform."""
1274
inventory_delta = []
1275
child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1276
new_paths = self._inventory_altered()
1277
total_entries = len(new_paths) + len(self._removed_id)
1279
for num, trans_id in enumerate(self._removed_id):
1281
child_pb.update('removing file', num, total_entries)
1282
if trans_id == self._new_root:
1283
file_id = self._tree.get_root_id()
1285
file_id = self.tree_file_id(trans_id)
1286
# File-id isn't really being deleted, just moved
1287
if file_id in self._r_new_id:
1289
path = self._tree_id_paths[trans_id]
1290
inventory_delta.append((path, None, file_id, None))
1291
new_path_file_ids = dict((t, self.final_file_id(t)) for p, t in
1293
entries = self._tree.iter_entries_by_dir(
1294
new_path_file_ids.values())
1295
old_paths = dict((e.file_id, p) for p, e in entries)
1297
for num, (path, trans_id) in enumerate(new_paths):
1299
child_pb.update('adding file',
1300
num + len(self._removed_id), total_entries)
1301
file_id = new_path_file_ids[trans_id]
1306
kind = self.final_kind(trans_id)
1308
kind = self._tree.stored_kind(file_id)
1309
parent_trans_id = self.final_parent(trans_id)
1310
parent_file_id = new_path_file_ids.get(parent_trans_id)
1311
if parent_file_id is None:
1312
parent_file_id = self.final_file_id(parent_trans_id)
1313
if trans_id in self._new_reference_revision:
1314
new_entry = inventory.TreeReference(
1316
self._new_name[trans_id],
1317
self.final_file_id(self._new_parent[trans_id]),
1318
None, self._new_reference_revision[trans_id])
1320
new_entry = inventory.make_entry(kind,
1321
self.final_name(trans_id),
1322
parent_file_id, file_id)
1323
old_path = old_paths.get(new_entry.file_id)
1324
new_executability = self._new_executability.get(trans_id)
1325
if new_executability is not None:
1326
new_entry.executable = new_executability
1327
inventory_delta.append(
1328
(old_path, path, new_entry.file_id, new_entry))
1331
return inventory_delta
1333
def _apply_removals(self, mover):
1198
def _apply_removals(self, inv, inventory_delta, mover):
1334
1199
"""Perform tree operations that remove directory/inventory names.
1336
1201
That is, delete files that are to be deleted, and put any files that
1337
1202
need renaming into limbo. This must be done in strict child-to-parent
1340
If inventory_delta is None, no inventory delta generation is performed.
1342
1205
tree_paths = list(self._tree_path_ids.iteritems())
1343
1206
tree_paths.sort(reverse=True)
1361
1224
self.rename_count += 1
1225
if trans_id in self._removed_id:
1226
if trans_id == self._new_root:
1227
file_id = self._tree.get_root_id()
1229
file_id = self.tree_file_id(trans_id)
1230
if file_id is not None:
1231
inventory_delta.append((path, None, file_id, None))
1363
1233
child_pb.finished()
1365
def _apply_insertions(self, mover):
1235
def _apply_insertions(self, inv, inventory_delta, mover):
1366
1236
"""Perform tree operations that insert directory/inventory names.
1368
1238
That is, create any files that need to be created, and restore from
1369
1239
limbo any files that needed renaming. This must be done in strict
1370
1240
parent-to-child order.
1372
If inventory_delta is None, no inventory delta is calculated, and
1373
no list of modified paths is returned.
1375
new_paths = self.new_paths(filesystem_only=True)
1242
new_paths = self.new_paths()
1376
1243
modified_paths = []
1377
new_path_file_ids = dict((t, self.final_file_id(t)) for p, t in
1379
1244
child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1381
1247
for num, (path, trans_id) in enumerate(new_paths):
1383
child_pb.update('adding file', num, len(new_paths))
1384
full_path = self._tree.abspath(path)
1385
if trans_id in self._needs_rename:
1387
mover.rename(self._limbo_name(trans_id), full_path)
1389
# We may be renaming a dangling inventory id
1390
if e.errno != errno.ENOENT:
1393
self.rename_count += 1
1394
if (trans_id in self._new_contents or
1395
self.path_changed(trans_id)):
1249
child_pb.update('adding file', num, len(new_paths))
1251
kind = self._new_contents[trans_id]
1253
kind = contents = None
1254
if trans_id in self._new_contents or \
1255
self.path_changed(trans_id):
1256
full_path = self._tree.abspath(path)
1257
if trans_id in self._needs_rename:
1259
mover.rename(self._limbo_name(trans_id), full_path)
1261
# We may be renaming a dangling inventory id
1262
if e.errno != errno.ENOENT:
1265
self.rename_count += 1
1396
1266
if trans_id in self._new_contents:
1397
1267
modified_paths.append(full_path)
1268
completed_new.append(trans_id)
1270
if trans_id in self._new_id:
1272
kind = file_kind(self._tree.abspath(path))
1273
if trans_id in self._new_reference_revision:
1274
new_entry = inventory.TreeReference(
1275
self._new_id[trans_id],
1276
self._new_name[trans_id],
1277
self.final_file_id(self._new_parent[trans_id]),
1278
None, self._new_reference_revision[trans_id])
1280
new_entry = inventory.make_entry(kind,
1281
self.final_name(trans_id),
1282
self.final_file_id(self.final_parent(trans_id)),
1283
self._new_id[trans_id])
1285
if trans_id in self._new_name or trans_id in\
1286
self._new_parent or\
1287
trans_id in self._new_executability:
1288
file_id = self.final_file_id(trans_id)
1289
if file_id is not None:
1290
entry = inv[file_id]
1291
new_entry = entry.copy()
1293
if trans_id in self._new_name or trans_id in\
1295
if new_entry is not None:
1296
new_entry.name = self.final_name(trans_id)
1297
parent = self.final_parent(trans_id)
1298
parent_id = self.final_file_id(parent)
1299
new_entry.parent_id = parent_id
1398
1301
if trans_id in self._new_executability:
1399
self._set_executability(path, trans_id)
1302
self._set_executability(path, new_entry, trans_id)
1303
if new_entry is not None:
1304
if new_entry.file_id in inv:
1305
old_path = inv.id2path(new_entry.file_id)
1308
inventory_delta.append((old_path, path,
1401
1312
child_pb.finished()
1402
self._new_contents.clear()
1313
for trans_id in completed_new:
1314
del self._new_contents[trans_id]
1403
1315
return modified_paths
1442
1354
except KeyError:
1444
1356
file_id = self.tree_file_id(parent_id)
1447
entry = self._tree.iter_entries_by_dir([file_id]).next()[1]
1448
children = getattr(entry, 'children', {})
1449
for child in children:
1357
for child in self._tree.inventory[file_id].children.iterkeys():
1450
1358
childpath = joinpath(path, child)
1451
1359
yield self.trans_id_tree_path(childpath)
1454
class _PreviewTree(tree.Tree):
1362
class _PreviewTree(object):
1455
1363
"""Partial implementation of Tree to support show_diff_trees"""
1457
1365
def __init__(self, transform):
1458
1366
self._transform = transform
1459
self._final_paths = FinalPaths(transform)
1460
self.__by_parent = None
1461
self._parent_ids = []
1462
self._all_children_cache = {}
1463
self._path2trans_id_cache = {}
1464
self._final_name_cache = {}
1466
def _changes(self, file_id):
1467
for changes in self._transform.iter_changes():
1468
if changes[0] == file_id:
1471
def _content_change(self, file_id):
1472
"""Return True if the content of this file changed"""
1473
changes = self._changes(file_id)
1474
# changes[2] is true if the file content changed. See
1475
# InterTree.iter_changes.
1476
return (changes is not None and changes[2])
1478
def _get_repository(self):
1479
repo = getattr(self._transform._tree, '_repository', None)
1481
repo = self._transform._tree.branch.repository
1484
def _iter_parent_trees(self):
1485
for revision_id in self.get_parent_ids():
1487
yield self.revision_tree(revision_id)
1488
except errors.NoSuchRevisionInTree:
1489
yield self._get_repository().revision_tree(revision_id)
1491
def _get_file_revision(self, file_id, vf, tree_revision):
1492
parent_keys = [(file_id, self._file_revision(t, file_id)) for t in
1493
self._iter_parent_trees()]
1494
vf.add_lines((file_id, tree_revision), parent_keys,
1495
self.get_file(file_id).readlines())
1496
repo = self._get_repository()
1497
base_vf = repo.texts
1498
if base_vf not in vf.fallback_versionedfiles:
1499
vf.fallback_versionedfiles.append(base_vf)
1500
return tree_revision
1502
def _stat_limbo_file(self, file_id):
1503
trans_id = self._transform.trans_id_file_id(file_id)
1504
name = self._transform._limbo_name(trans_id)
1505
return os.lstat(name)
1508
def _by_parent(self):
1509
if self.__by_parent is None:
1510
self.__by_parent = self._transform.by_parent()
1511
return self.__by_parent
1513
def _comparison_data(self, entry, path):
1514
kind, size, executable, link_or_sha1 = self.path_content_summary(path)
1515
if kind == 'missing':
1519
file_id = self._transform.final_file_id(self._path2trans_id(path))
1520
executable = self.is_executable(file_id, path)
1521
return kind, executable, None
1523
1368
def lock_read(self):
1524
1369
# Perhaps in theory, this should lock the TreeTransform?
1527
1372
def unlock(self):
1531
def inventory(self):
1532
"""This Tree does not use inventory as its backing data."""
1533
raise NotImplementedError(_PreviewTree.inventory)
1535
def get_root_id(self):
1536
return self._transform.final_file_id(self._transform.root)
1538
def all_file_ids(self):
1539
tree_ids = set(self._transform._tree.all_file_ids())
1540
tree_ids.difference_update(self._transform.tree_file_id(t)
1541
for t in self._transform._removed_id)
1542
tree_ids.update(self._transform._new_id.values())
1546
return iter(self.all_file_ids())
1548
def has_id(self, file_id):
1549
if file_id in self._transform._r_new_id:
1551
elif file_id in self._transform._removed_id:
1554
return self._transform._tree.has_id(file_id)
1556
def _path2trans_id(self, path):
1557
# We must not use None here, because that is a valid value to store.
1558
trans_id = self._path2trans_id_cache.get(path, object)
1559
if trans_id is not object:
1561
segments = splitpath(path)
1562
cur_parent = self._transform.root
1563
for cur_segment in segments:
1564
for child in self._all_children(cur_parent):
1565
final_name = self._final_name_cache.get(child)
1566
if final_name is None:
1567
final_name = self._transform.final_name(child)
1568
self._final_name_cache[child] = final_name
1569
if final_name == cur_segment:
1573
self._path2trans_id_cache[path] = None
1575
self._path2trans_id_cache[path] = cur_parent
1578
def path2id(self, path):
1579
return self._transform.final_file_id(self._path2trans_id(path))
1581
def id2path(self, file_id):
1582
trans_id = self._transform.trans_id_file_id(file_id)
1584
return self._final_paths._determine_path(trans_id)
1586
raise errors.NoSuchId(self, file_id)
1588
def _all_children(self, trans_id):
1589
children = self._all_children_cache.get(trans_id)
1590
if children is not None:
1592
children = set(self._transform.iter_tree_children(trans_id))
1593
# children in the _new_parent set are provided by _by_parent.
1594
children.difference_update(self._transform._new_parent.keys())
1595
children.update(self._by_parent.get(trans_id, []))
1596
self._all_children_cache[trans_id] = children
1599
def iter_children(self, file_id):
1600
trans_id = self._transform.trans_id_file_id(file_id)
1601
for child_trans_id in self._all_children(trans_id):
1602
yield self._transform.final_file_id(child_trans_id)
1605
possible_extras = set(self._transform.trans_id_tree_path(p) for p
1606
in self._transform._tree.extras())
1607
possible_extras.update(self._transform._new_contents)
1608
possible_extras.update(self._transform._removed_id)
1609
for trans_id in possible_extras:
1610
if self._transform.final_file_id(trans_id) is None:
1611
yield self._final_paths._determine_path(trans_id)
1613
def _make_inv_entries(self, ordered_entries, specific_file_ids):
1614
for trans_id, parent_file_id in ordered_entries:
1615
file_id = self._transform.final_file_id(trans_id)
1618
if (specific_file_ids is not None
1619
and file_id not in specific_file_ids):
1622
kind = self._transform.final_kind(trans_id)
1624
kind = self._transform._tree.stored_kind(file_id)
1625
new_entry = inventory.make_entry(
1627
self._transform.final_name(trans_id),
1628
parent_file_id, file_id)
1629
yield new_entry, trans_id
1631
def _list_files_by_dir(self):
1632
todo = [ROOT_PARENT]
1634
while len(todo) > 0:
1636
parent_file_id = self._transform.final_file_id(parent)
1637
children = list(self._all_children(parent))
1638
paths = dict(zip(children, self._final_paths.get_paths(children)))
1639
children.sort(key=paths.get)
1640
todo.extend(reversed(children))
1641
for trans_id in children:
1642
ordered_ids.append((trans_id, parent_file_id))
1645
def iter_entries_by_dir(self, specific_file_ids=None):
1646
# This may not be a maximally efficient implementation, but it is
1647
# reasonably straightforward. An implementation that grafts the
1648
# TreeTransform changes onto the tree's iter_entries_by_dir results
1649
# might be more efficient, but requires tricky inferences about stack
1651
ordered_ids = self._list_files_by_dir()
1652
for entry, trans_id in self._make_inv_entries(ordered_ids,
1654
yield unicode(self._final_paths.get_path(trans_id)), entry
1656
def list_files(self, include_root=False):
1657
"""See Tree.list_files."""
1658
# XXX This should behave like WorkingTree.list_files, but is really
1659
# more like RevisionTree.list_files.
1660
for path, entry in self.iter_entries_by_dir():
1661
if entry.name == '' and not include_root:
1663
yield path, 'V', entry.kind, entry.file_id, entry
1375
def _iter_changes(self, from_tree, include_unchanged=False,
1376
specific_files=None, pb=None, extra_trees=None,
1377
require_versioned=True, want_unversioned=False):
1378
"""See InterTree._iter_changes.
1380
This implementation does not support include_unchanged, specific_files,
1381
or want_unversioned. extra_trees, require_versioned, and pb are
1384
if from_tree is not self._transform._tree:
1385
raise ValueError('from_tree must be transform source tree.')
1386
if include_unchanged:
1387
raise ValueError('include_unchanged is not supported')
1388
if specific_files is not None:
1389
raise ValueError('specific_files is not supported')
1390
if want_unversioned:
1391
raise ValueError('want_unversioned is not supported')
1392
return self._transform._iter_changes()
1665
1394
def kind(self, file_id):
1666
1395
trans_id = self._transform.trans_id_file_id(file_id)
1667
1396
return self._transform.final_kind(trans_id)
1669
def stored_kind(self, file_id):
1670
trans_id = self._transform.trans_id_file_id(file_id)
1672
return self._transform._new_contents[trans_id]
1674
return self._transform._tree.stored_kind(file_id)
1676
1398
def get_file_mtime(self, file_id, path=None):
1677
1399
"""See Tree.get_file_mtime"""
1678
if not self._content_change(file_id):
1679
return self._transform._tree.get_file_mtime(file_id, path)
1680
return self._stat_limbo_file(file_id).st_mtime
1682
def _file_size(self, entry, stat_value):
1683
return self.get_file_size(entry.file_id)
1685
def get_file_size(self, file_id):
1686
"""See Tree.get_file_size"""
1687
if self.kind(file_id) == 'file':
1688
return self._transform._tree.get_file_size(file_id)
1692
def get_file_sha1(self, file_id, path=None, stat_value=None):
1693
trans_id = self._transform.trans_id_file_id(file_id)
1694
kind = self._transform._new_contents.get(trans_id)
1696
return self._transform._tree.get_file_sha1(file_id)
1698
fileobj = self.get_file(file_id)
1700
return sha_file(fileobj)
1704
def is_executable(self, file_id, path=None):
1707
trans_id = self._transform.trans_id_file_id(file_id)
1709
return self._transform._new_executability[trans_id]
1712
return self._transform._tree.is_executable(file_id, path)
1714
if e.errno == errno.ENOENT:
1717
except errors.NoSuchId:
1720
def path_content_summary(self, path):
1721
trans_id = self._path2trans_id(path)
1722
tt = self._transform
1723
tree_path = tt._tree_id_paths.get(trans_id)
1724
kind = tt._new_contents.get(trans_id)
1726
if tree_path is None or trans_id in tt._removed_contents:
1727
return 'missing', None, None, None
1728
summary = tt._tree.path_content_summary(tree_path)
1729
kind, size, executable, link_or_sha1 = summary
1732
limbo_name = tt._limbo_name(trans_id)
1733
if trans_id in tt._new_reference_revision:
1734
kind = 'tree-reference'
1736
statval = os.lstat(limbo_name)
1737
size = statval.st_size
1738
if not supports_executable():
1741
executable = statval.st_mode & S_IEXEC
1745
if kind == 'symlink':
1746
link_or_sha1 = os.readlink(limbo_name)
1747
if supports_executable():
1748
executable = tt._new_executability.get(trans_id, executable)
1749
return kind, size, executable, link_or_sha1
1751
def iter_changes(self, from_tree, include_unchanged=False,
1752
specific_files=None, pb=None, extra_trees=None,
1753
require_versioned=True, want_unversioned=False):
1754
"""See InterTree.iter_changes.
1756
This has a fast path that is only used when the from_tree matches
1757
the transform tree, and no fancy options are supplied.
1759
if (from_tree is not self._transform._tree or include_unchanged or
1760
specific_files or want_unversioned):
1761
return tree.InterTree(from_tree, self).iter_changes(
1762
include_unchanged=include_unchanged,
1763
specific_files=specific_files,
1765
extra_trees=extra_trees,
1766
require_versioned=require_versioned,
1767
want_unversioned=want_unversioned)
1768
if want_unversioned:
1769
raise ValueError('want_unversioned is not supported')
1770
return self._transform.iter_changes()
1772
def get_file(self, file_id, path=None):
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):
1773
1405
"""See Tree.get_file"""
1774
if not self._content_change(file_id):
1775
return self._transform._tree.get_file(file_id, path)
1776
1406
trans_id = self._transform.trans_id_file_id(file_id)
1777
1407
name = self._transform._limbo_name(trans_id)
1778
1408
return open(name, 'rb')
1780
def annotate_iter(self, file_id,
1781
default_revision=_mod_revision.CURRENT_REVISION):
1782
changes = self._changes(file_id)
1786
changed_content, versioned, kind = (changes[2], changes[3],
1790
get_old = (kind[0] == 'file' and versioned[0])
1792
old_annotation = self._transform._tree.annotate_iter(file_id,
1793
default_revision=default_revision)
1797
return old_annotation
1798
if not changed_content:
1799
return old_annotation
1800
return annotate.reannotate([old_annotation],
1801
self.get_file(file_id).readlines(),
1804
def get_symlink_target(self, file_id):
1805
"""See Tree.get_symlink_target"""
1806
if not self._content_change(file_id):
1807
return self._transform._tree.get_symlink_target(file_id)
1808
trans_id = self._transform.trans_id_file_id(file_id)
1809
name = self._transform._limbo_name(trans_id)
1810
return os.readlink(name)
1812
def walkdirs(self, prefix=''):
1813
pending = [self._transform.root]
1814
while len(pending) > 0:
1815
parent_id = pending.pop()
1818
prefix = prefix.rstrip('/')
1819
parent_path = self._final_paths.get_path(parent_id)
1820
parent_file_id = self._transform.final_file_id(parent_id)
1821
for child_id in self._all_children(parent_id):
1822
path_from_root = self._final_paths.get_path(child_id)
1823
basename = self._transform.final_name(child_id)
1824
file_id = self._transform.final_file_id(child_id)
1826
kind = self._transform.final_kind(child_id)
1827
versioned_kind = kind
1830
versioned_kind = self._transform._tree.stored_kind(file_id)
1831
if versioned_kind == 'directory':
1832
subdirs.append(child_id)
1833
children.append((path_from_root, basename, kind, None,
1834
file_id, versioned_kind))
1836
if parent_path.startswith(prefix):
1837
yield (parent_path, parent_file_id), children
1838
pending.extend(sorted(subdirs, key=self._final_paths.get_path,
1841
def get_parent_ids(self):
1842
return self._parent_ids
1844
def set_parent_ids(self, parent_ids):
1845
self._parent_ids = parent_ids
1847
def get_revision_tree(self, revision_id):
1848
return self._transform._tree.get_revision_tree(revision_id)
1410
def paths2ids(self, specific_files, trees=None, require_versioned=False):
1411
"""See Tree.paths2ids"""
1851
1415
def joinpath(parent, child):
2037
1588
wt.add_conflicts(conflicts)
2038
1589
except errors.UnsupportedOperation:
2040
result = tt.apply(no_conflicts=True,
2041
precomputed_delta=precomputed_delta)
1591
result = tt.apply(no_conflicts=True)
2044
1594
top_pb.finished()
2048
def _create_files(tt, tree, desired_files, pb, offset, accelerator_tree,
2050
total = len(desired_files) + offset
1598
def _iter_files_bytes_accelerated(tree, accelerator_tree, desired_files):
2051
1599
if accelerator_tree is None:
2052
1600
new_desired_files = desired_files
2054
iter = accelerator_tree.iter_changes(tree, include_unchanged=True)
1602
iter = accelerator_tree._iter_changes(tree, include_unchanged=True)
2055
1603
unchanged = dict((f, p[1]) for (f, p, c, v, d, n, k, e)
2056
in iter if not (c or e[0] != e[1]))
2057
1605
new_desired_files = []
2059
for file_id, trans_id in desired_files:
1606
for file_id, identifier in desired_files:
2060
1607
accelerator_path = unchanged.get(file_id)
2061
1608
if accelerator_path is None:
2062
new_desired_files.append((file_id, trans_id))
1609
new_desired_files.append((file_id, identifier))
2064
pb.update('Adding file contents', count + offset, total)
2066
tt.create_hardlink(accelerator_tree.abspath(accelerator_path),
2069
contents = accelerator_tree.get_file(file_id, accelerator_path)
2071
tt.create_file(contents, trans_id)
2076
for count, (trans_id, contents) in enumerate(tree.iter_files_bytes(
2077
new_desired_files)):
2078
tt.create_file(contents, trans_id)
2079
pb.update('Adding file contents', count + offset, total)
1611
contents = accelerator_tree.get_file(file_id, accelerator_path)
1614
contents_bytes = (contents.read(),)
1617
yield identifier, contents_bytes
1618
for result in tree.iter_files_bytes(new_desired_files):
2082
1622
def _reparent_children(tt, old_parent, new_parent):
2170
1704
tt.create_directory(trans_id)
2173
def create_from_tree(tt, trans_id, tree, file_id, bytes=None):
2174
"""Create new file contents according to tree contents."""
2175
kind = tree.kind(file_id)
2176
if kind == 'directory':
2177
tt.create_directory(trans_id)
2178
elif kind == "file":
2180
tree_file = tree.get_file(file_id)
2182
bytes = tree_file.readlines()
2185
tt.create_file(bytes, trans_id)
2186
elif kind == "symlink":
2187
tt.create_symlink(tree.get_symlink_target(file_id), trans_id)
2189
raise AssertionError('Unknown kind %r' % kind)
2192
1707
def create_entry_executability(tt, entry, trans_id):
2193
1708
"""Set the executability of a trans_id according to an inventory entry"""
2194
1709
if entry.kind == "file":
2195
1710
tt.set_executability(entry.executable, trans_id)
1713
@deprecated_function(zero_fifteen)
1714
def find_interesting(working_tree, target_tree, filenames):
1715
"""Find the ids corresponding to specified filenames.
1717
Deprecated: Please use tree1.paths2ids(filenames, [tree2]).
1719
working_tree.lock_read()
1721
target_tree.lock_read()
1723
return working_tree.paths2ids(filenames, [target_tree])
1725
target_tree.unlock()
1727
working_tree.unlock()
1730
@deprecated_function(zero_ninety)
1731
def change_entry(tt, file_id, working_tree, target_tree,
1732
trans_id_file_id, backups, trans_id, by_parent):
1733
"""Replace a file_id's contents with those from a target tree."""
1734
if file_id is None and target_tree is None:
1735
# skip the logic altogether in the deprecation test
1737
e_trans_id = trans_id_file_id(file_id)
1738
entry = target_tree.inventory[file_id]
1739
has_contents, contents_mod, meta_mod, = _entry_changes(file_id, entry,
1742
mode_id = e_trans_id
1745
tt.delete_contents(e_trans_id)
1747
parent_trans_id = trans_id_file_id(entry.parent_id)
1748
backup_name = get_backup_name(entry, by_parent,
1749
parent_trans_id, tt)
1750
tt.adjust_path(backup_name, parent_trans_id, e_trans_id)
1751
tt.unversion_file(e_trans_id)
1752
e_trans_id = tt.create_path(entry.name, parent_trans_id)
1753
tt.version_file(file_id, e_trans_id)
1754
trans_id[file_id] = e_trans_id
1755
create_by_entry(tt, entry, target_tree, e_trans_id, mode_id=mode_id)
1756
create_entry_executability(tt, entry, e_trans_id)
1759
tt.set_executability(entry.executable, e_trans_id)
1760
if tt.final_name(e_trans_id) != entry.name:
1763
parent_id = tt.final_parent(e_trans_id)
1764
parent_file_id = tt.final_file_id(parent_id)
1765
if parent_file_id != entry.parent_id:
1770
parent_trans_id = trans_id_file_id(entry.parent_id)
1771
tt.adjust_path(entry.name, parent_trans_id, e_trans_id)
2198
1774
def get_backup_name(entry, by_parent, parent_trans_id, tt):
2199
1775
return _get_backup_name(entry.name, by_parent, parent_trans_id, tt)