1334
1334
return file_ids
1337
def build_tree(tree, wt, accelerator_tree=None):
1337
def build_tree(tree, wt, accelerator_tree=None, hardlink=False):
1338
1338
"""Create working tree for a branch, using a TreeTransform.
1340
1340
This function should be used on empty trees, having a tree root at most.
1353
1353
:param accelerator_tree: A tree which can be used for retrieving file
1354
1354
contents more quickly than tree itself, i.e. a workingtree. tree
1355
1355
will be used for cases where accelerator_tree's content is different.
1356
:param hardlink: If true, hard-link files to accelerator_tree, where
1357
possible. accelerator_tree must implement id2abspath, i.e. be a
1357
1360
wt.lock_tree_write()
1361
1364
if accelerator_tree is not None:
1362
1365
accelerator_tree.lock_read()
1364
return _build_tree(tree, wt, accelerator_tree)
1367
return _build_tree(tree, wt, accelerator_tree, hardlink)
1366
1369
if accelerator_tree is not None:
1367
1370
accelerator_tree.unlock()
1374
def _build_tree(tree, wt, accelerator_tree):
1377
def _build_tree(tree, wt, accelerator_tree, hardlink):
1375
1378
"""See build_tree."""
1376
1379
if len(wt.inventory) > 1: # more than just a root
1377
1380
raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
1398
1401
pb = bzrlib.ui.ui_factory.nested_progress_bar()
1400
1403
deferred_contents = []
1401
1405
for num, (tree_path, entry) in \
1402
1406
enumerate(tree.inventory.iter_entries_by_dir()):
1403
1407
pb.update("Building tree", num - len(deferred_contents),
1447
1451
new_trans_id = file_trans_id[file_id]
1448
1452
old_parent = tt.trans_id_tree_path(tree_path)
1449
1453
_reparent_children(tt, old_parent, new_trans_id)
1450
for num, (trans_id, bytes) in enumerate(
1451
_iter_files_bytes_accelerated(tree, accelerator_tree,
1452
deferred_contents)):
1453
tt.create_file(bytes, trans_id)
1454
pb.update('Adding file contents',
1455
(num + len(tree.inventory) - len(deferred_contents)),
1456
len(tree.inventory))
1454
offset = num +1 - len(deferred_contents)
1455
_create_files(tt, tree, deferred_contents, pb, offset,
1456
accelerator_tree, hardlink)
1459
1459
pp.next_phase()
1477
def _iter_files_bytes_accelerated(tree, accelerator_tree, desired_files):
1477
def _create_files(tt, tree, desired_files, pb, offset, accelerator_tree,
1479
total = len(desired_files) + offset
1478
1480
if accelerator_tree is None:
1479
1481
new_desired_files = desired_files
1481
1483
iter = accelerator_tree._iter_changes(tree, include_unchanged=True)
1482
1484
unchanged = dict((f, p[0]) for (f, p, c, v, d, n, k, e)
1485
in iter if not (c or e[0] != e[1]))
1484
1486
new_desired_files = []
1485
for file_id, identifier in desired_files:
1488
for file_id, trans_id in desired_files:
1486
1489
accelerator_path = unchanged.get(file_id)
1487
1490
if accelerator_path is None:
1488
new_desired_files.append((file_id, identifier))
1491
new_desired_files.append((file_id, trans_id))
1490
contents = accelerator_tree.get_file(file_id, accelerator_path)
1493
contents_bytes = (contents.read(),)
1496
yield identifier, contents_bytes
1497
for result in tree.iter_files_bytes(new_desired_files):
1493
pb.update('Adding file contents', count+offset, total)
1495
tt.create_hardlink(accelerator_tree.id2abspath(file_id),
1498
contents = accelerator_tree.get_file(file_id, accelerator_path)
1500
tt.create_file(contents, trans_id)
1506
for count, (trans_id, contents) in enumerate(tree.iter_files_bytes(
1507
new_desired_files)):
1508
tt.create_file(contents, trans_id)
1509
pb.update('Adding file contents', count+offset, total)
1501
1512
def _reparent_children(tt, old_parent, new_parent):