354
354
if typefunc(mode):
355
355
os.chmod(self._limbo_name(trans_id), mode)
357
def create_hardlink(self, path, trans_id):
358
"""Schedule creation of a hard link"""
359
name = self._limbo_name(trans_id)
363
if e.errno != errno.EPERM:
365
raise errors.HardLinkNotSupported(path)
367
unique_add(self._new_contents, trans_id, 'file')
369
# Clean up the file, it never got registered so
370
# TreeTransform.finalize() won't clean it up.
357
374
def create_directory(self, trans_id):
358
375
"""Schedule creation of a new directory.
1407
1424
name = self._transform._limbo_name(trans_id)
1408
1425
return open(name, 'rb')
1427
def get_symlink_target(self, file_id):
1428
"""See Tree.get_symlink_target"""
1429
trans_id = self._transform.trans_id_file_id(file_id)
1430
name = self._transform._limbo_name(trans_id)
1431
return os.readlink(name)
1410
1433
def paths2ids(self, specific_files, trees=None, require_versioned=False):
1411
1434
"""See Tree.paths2ids"""
1412
1435
return 'not_empty'
1455
1478
return file_ids
1458
def build_tree(tree, wt, accelerator_tree=None):
1481
def build_tree(tree, wt, accelerator_tree=None, hardlink=False):
1459
1482
"""Create working tree for a branch, using a TreeTransform.
1461
1484
This function should be used on empty trees, having a tree root at most.
1474
1497
:param accelerator_tree: A tree which can be used for retrieving file
1475
1498
contents more quickly than tree itself, i.e. a workingtree. tree
1476
1499
will be used for cases where accelerator_tree's content is different.
1500
:param hardlink: If true, hard-link files to accelerator_tree, where
1501
possible. accelerator_tree must implement abspath, i.e. be a
1478
1504
wt.lock_tree_write()
1482
1508
if accelerator_tree is not None:
1483
1509
accelerator_tree.lock_read()
1485
return _build_tree(tree, wt, accelerator_tree)
1511
return _build_tree(tree, wt, accelerator_tree, hardlink)
1487
1513
if accelerator_tree is not None:
1488
1514
accelerator_tree.unlock()
1495
def _build_tree(tree, wt, accelerator_tree):
1521
def _build_tree(tree, wt, accelerator_tree, hardlink):
1496
1522
"""See build_tree."""
1497
1523
if len(wt.inventory) > 1: # more than just a root
1498
1524
raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
1519
1545
pb = bzrlib.ui.ui_factory.nested_progress_bar()
1521
1547
deferred_contents = []
1522
1549
for num, (tree_path, entry) in \
1523
1550
enumerate(tree.inventory.iter_entries_by_dir()):
1524
1551
pb.update("Building tree", num - len(deferred_contents),
1568
1595
new_trans_id = file_trans_id[file_id]
1569
1596
old_parent = tt.trans_id_tree_path(tree_path)
1570
1597
_reparent_children(tt, old_parent, new_trans_id)
1571
for num, (trans_id, bytes) in enumerate(
1572
_iter_files_bytes_accelerated(tree, accelerator_tree,
1573
deferred_contents)):
1574
tt.create_file(bytes, trans_id)
1575
pb.update('Adding file contents',
1576
(num + len(tree.inventory) - len(deferred_contents)),
1577
len(tree.inventory))
1598
offset = num + 1 - len(deferred_contents)
1599
_create_files(tt, tree, deferred_contents, pb, offset,
1600
accelerator_tree, hardlink)
1580
1603
pp.next_phase()
1598
def _iter_files_bytes_accelerated(tree, accelerator_tree, desired_files):
1621
def _create_files(tt, tree, desired_files, pb, offset, accelerator_tree,
1623
total = len(desired_files) + offset
1599
1624
if accelerator_tree is None:
1600
1625
new_desired_files = desired_files
1602
1627
iter = accelerator_tree._iter_changes(tree, include_unchanged=True)
1603
1628
unchanged = dict((f, p[1]) for (f, p, c, v, d, n, k, e)
1629
in iter if not (c or e[0] != e[1]))
1605
1630
new_desired_files = []
1606
for file_id, identifier in desired_files:
1632
for file_id, trans_id in desired_files:
1607
1633
accelerator_path = unchanged.get(file_id)
1608
1634
if accelerator_path is None:
1609
new_desired_files.append((file_id, identifier))
1635
new_desired_files.append((file_id, trans_id))
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):
1637
pb.update('Adding file contents', count + offset, total)
1639
tt.create_hardlink(accelerator_tree.abspath(accelerator_path),
1642
contents = accelerator_tree.get_file(file_id, accelerator_path)
1644
tt.create_file(contents, trans_id)
1649
for count, (trans_id, contents) in enumerate(tree.iter_files_bytes(
1650
new_desired_files)):
1651
tt.create_file(contents, trans_id)
1652
pb.update('Adding file contents', count + offset, total)
1622
1655
def _reparent_children(tt, old_parent, new_parent):