1096
1120
it is silently replaced.
1097
1121
- Otherwise, conflict resolution will move the old file to 'oldname.moved'.
1123
wt.lock_tree_write()
1127
return _build_tree(tree, wt)
1133
def _build_tree(tree, wt):
1134
"""See build_tree."""
1099
1135
if len(wt.inventory) > 1: # more than just a root
1100
1136
raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
1101
1137
file_trans_id = {}
1102
1138
top_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1103
1139
pp = ProgressPhase("Build phase", 2, top_pb)
1104
1140
if tree.inventory.root is not None:
1105
wt.set_root_id(tree.inventory.root.file_id)
1141
# this is kindof a hack: we should be altering the root
1142
# as partof the regular tree shape diff logic.
1143
# the conditional test hereis to avoid doing an
1144
# expensive operation (flush) every time the root id
1145
# is set within the tree, nor setting the root and thus
1146
# marking the tree as dirty, because we use two different
1147
# idioms here: tree interfaces and inventory interfaces.
1148
if wt.path2id('') != tree.inventory.root.file_id:
1149
wt.set_root_id(tree.inventory.root.file_id)
1106
1151
tt = TreeTransform(wt)
1222
1269
executable = tree.is_executable(entry.file_id)
1223
1270
return tt.new_file(name, parent_id, contents, entry.file_id,
1225
elif kind == 'directory':
1226
return tt.new_directory(name, parent_id, entry.file_id)
1272
elif kind in ('directory', 'tree-reference'):
1273
trans_id = tt.new_directory(name, parent_id, entry.file_id)
1274
if kind == 'tree-reference':
1275
tt.set_tree_reference(entry.reference_revision, trans_id)
1227
1277
elif kind == 'symlink':
1228
1278
target = tree.get_symlink_target(entry.file_id)
1229
1279
return tt.new_symlink(name, parent_id, target, entry.file_id)
1281
raise errors.BadFileKindError(name, kind)
1231
1283
def create_by_entry(tt, entry, tree, trans_id, lines=None, mode_id=None):
1232
1284
"""Create new file contents according to an inventory entry."""
1334
1397
return has_contents, contents_mod, meta_mod
1337
def revert(working_tree, target_tree, filenames, backups=False,
1400
def revert(working_tree, target_tree, filenames, backups=False,
1338
1401
pb=DummyProgress(), change_reporter=None):
1339
1402
"""Revert a working tree's contents to those of a target tree."""
1340
interesting_ids = find_interesting(working_tree, target_tree, filenames)
1403
target_tree.lock_read()
1341
1404
tt = TreeTransform(working_tree, pb)
1343
1406
pp = ProgressPhase("Revert phase", 3, pb)
1344
1407
pp.next_phase()
1345
1408
child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1347
_alter_files(working_tree, target_tree, tt, child_pb,
1348
interesting_ids, backups)
1410
_alter_files(working_tree, target_tree, tt, child_pb,
1350
1413
child_pb.finished()
1351
1414
pp.next_phase()
1365
1429
working_tree.set_merge_modified({})
1431
target_tree.unlock()
1369
1434
return conflicts
1372
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids,
1437
def _alter_files(working_tree, target_tree, tt, pb, specific_files,
1374
1439
merge_modified = working_tree.merge_modified()
1375
1440
change_list = target_tree._iter_changes(working_tree,
1376
specific_file_ids=interesting_ids, pb=pb)
1441
specific_files=specific_files, pb=pb)
1377
1442
if target_tree.inventory.root is None:
1378
1443
skip_root = True
1380
1445
skip_root = False
1381
1446
basis_tree = None
1382
for id_num, (file_id, path, changed_content, versioned, parent, name,
1383
kind, executable) in enumerate(change_list):
1384
if skip_root and file_id[0] is not None and parent[0] is None:
1386
trans_id = tt.trans_id_file_id(file_id)
1389
keep_content = False
1390
if kind[0] == 'file' and (backups or kind[1] is None):
1391
wt_sha1 = working_tree.get_file_sha1(file_id)
1392
if merge_modified.get(file_id) != wt_sha1:
1393
if basis_tree is None:
1394
basis_tree = working_tree.basis_tree()
1395
if file_id in basis_tree:
1396
if wt_sha1 != basis_tree.get_file_sha1(file_id):
1448
for id_num, (file_id, path, changed_content, versioned, parent, name,
1449
kind, executable) in enumerate(change_list):
1450
if skip_root and file_id[0] is not None and parent[0] is None:
1452
trans_id = tt.trans_id_file_id(file_id)
1455
keep_content = False
1456
if kind[0] == 'file' and (backups or kind[1] is None):
1457
wt_sha1 = working_tree.get_file_sha1(file_id)
1458
if merge_modified.get(file_id) != wt_sha1:
1459
# acquire the basis tree lazyily to prevent the expense
1460
# of accessing it when its not needed ? (Guessing, RBC,
1462
if basis_tree is None:
1463
basis_tree = working_tree.basis_tree()
1464
basis_tree.lock_read()
1465
if file_id in basis_tree:
1466
if wt_sha1 != basis_tree.get_file_sha1(file_id):
1468
elif kind[1] is None and not versioned[1]:
1397
1469
keep_content = True
1398
elif kind[1] is None and not versioned[1]:
1400
if kind[0] is not None:
1401
if not keep_content:
1402
tt.delete_contents(trans_id)
1403
elif kind[1] is not None:
1404
parent_trans_id = tt.trans_id_file_id(parent[0])
1405
by_parent = tt.by_parent()
1406
backup_name = _get_backup_name(name[0], by_parent,
1407
parent_trans_id, tt)
1408
tt.adjust_path(backup_name, parent_trans_id, trans_id)
1409
new_trans_id = tt.create_path(name[0], parent_trans_id)
1410
if versioned == (True, True):
1411
tt.unversion_file(trans_id)
1412
tt.version_file(file_id, new_trans_id)
1413
# New contents should have the same unix perms as old
1416
trans_id = new_trans_id
1417
if kind[1] == 'directory':
1418
tt.create_directory(trans_id)
1419
elif kind[1] == 'symlink':
1420
tt.create_symlink(target_tree.get_symlink_target(file_id),
1422
elif kind[1] == 'file':
1423
tt.create_file(target_tree.get_file_lines(file_id),
1425
# preserve the execute bit when backing up
1426
if keep_content and executable[0] == executable[1]:
1427
tt.set_executability(executable[1], trans_id)
1429
assert kind[1] is None
1430
if versioned == (False, True):
1431
tt.version_file(file_id, trans_id)
1432
if versioned == (True, False):
1433
tt.unversion_file(trans_id)
1434
if (name[1] is not None and
1435
(name[0] != name[1] or parent[0] != parent[1])):
1436
tt.adjust_path(name[1], tt.trans_id_file_id(parent[1]), trans_id)
1437
if executable[0] != executable[1] and kind[1] == "file":
1438
tt.set_executability(executable[1], trans_id)
1470
if kind[0] is not None:
1471
if not keep_content:
1472
tt.delete_contents(trans_id)
1473
elif kind[1] is not None:
1474
parent_trans_id = tt.trans_id_file_id(parent[0])
1475
by_parent = tt.by_parent()
1476
backup_name = _get_backup_name(name[0], by_parent,
1477
parent_trans_id, tt)
1478
tt.adjust_path(backup_name, parent_trans_id, trans_id)
1479
new_trans_id = tt.create_path(name[0], parent_trans_id)
1480
if versioned == (True, True):
1481
tt.unversion_file(trans_id)
1482
tt.version_file(file_id, new_trans_id)
1483
# New contents should have the same unix perms as old
1486
trans_id = new_trans_id
1487
if kind[1] == 'directory':
1488
tt.create_directory(trans_id)
1489
elif kind[1] == 'symlink':
1490
tt.create_symlink(target_tree.get_symlink_target(file_id),
1492
elif kind[1] == 'file':
1493
tt.create_file(target_tree.get_file_lines(file_id),
1495
# preserve the execute bit when backing up
1496
if keep_content and executable[0] == executable[1]:
1497
tt.set_executability(executable[1], trans_id)
1499
assert kind[1] is None
1500
if versioned == (False, True):
1501
tt.version_file(file_id, trans_id)
1502
if versioned == (True, False):
1503
tt.unversion_file(trans_id)
1504
if (name[1] is not None and
1505
(name[0] != name[1] or parent[0] != parent[1])):
1507
name[1], tt.trans_id_file_id(parent[1]), trans_id)
1508
if executable[0] != executable[1] and kind[1] == "file":
1509
tt.set_executability(executable[1], trans_id)
1511
if basis_tree is not None:
1441
1515
def resolve_conflicts(tt, pb=DummyProgress(), pass_func=None):