~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

Teach TreeTransform to lock basis_trees if it acquires them, fixing revert on a dirstate working tree.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1197
1197
    return has_contents, contents_mod, meta_mod
1198
1198
 
1199
1199
 
1200
 
def revert(working_tree, target_tree, filenames, backups=False, 
 
1200
def revert(working_tree, target_tree, filenames, backups=False,
1201
1201
           pb=DummyProgress(), change_reporter=None):
1202
1202
    """Revert a working tree's contents to those of a target tree."""
1203
 
    interesting_ids = find_interesting(working_tree, target_tree, filenames)
 
1203
    target_tree.lock_read()
1204
1204
    tt = TreeTransform(working_tree, pb)
1205
1205
    try:
 
1206
        interesting_ids = find_interesting(working_tree, target_tree, filenames)
1206
1207
        pp = ProgressPhase("Revert phase", 3, pb)
1207
1208
        pp.next_phase()
1208
1209
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1209
1210
        try:
1210
 
            _alter_files(working_tree, target_tree, tt, child_pb, 
 
1211
            _alter_files(working_tree, target_tree, tt, child_pb,
1211
1212
                         interesting_ids, backups, change_reporter)
1212
1213
        finally:
1213
1214
            child_pb.finished()
1224
1225
        tt.apply()
1225
1226
        working_tree.set_merge_modified({})
1226
1227
    finally:
 
1228
        target_tree.unlock()
1227
1229
        tt.finalize()
1228
1230
        pb.clear()
1229
1231
    return conflicts
1240
1242
    else:
1241
1243
        skip_root = False
1242
1244
    basis_tree = None
1243
 
    if report_changes:
1244
 
        change_reporter = delta.ChangeReporter(working_tree.inventory)
1245
 
        delta.report_changes(change_list, change_reporter)
1246
 
    for id_num, (file_id, path, changed_content, versioned, parent, name, kind,
1247
 
                 executable) in enumerate(change_list):
1248
 
        if skip_root and file_id[0] is not None and parent[0] is None:
1249
 
            continue
1250
 
        trans_id = tt.trans_id_file_id(file_id)
1251
 
        mode_id = None
1252
 
        if changed_content:
1253
 
            keep_content = False
1254
 
            if kind[0] == 'file' and (backups or kind[1] is None):
1255
 
                wt_sha1 = working_tree.get_file_sha1(file_id)
1256
 
                if merge_modified.get(file_id) != wt_sha1:
1257
 
                    if basis_tree is None:
1258
 
                        basis_tree = working_tree.basis_tree()
1259
 
                    if file_id in basis_tree:
1260
 
                        if wt_sha1 != basis_tree.get_file_sha1(file_id):
 
1245
    try:
 
1246
        if report_changes:
 
1247
            change_reporter = delta.ChangeReporter(working_tree.inventory)
 
1248
            delta.report_changes(change_list, change_reporter)
 
1249
        for id_num, (file_id, path, changed_content, versioned, parent, name,
 
1250
                kind, executable) in enumerate(change_list):
 
1251
            if skip_root and file_id[0] is not None and parent[0] is None:
 
1252
                continue
 
1253
            trans_id = tt.trans_id_file_id(file_id)
 
1254
            mode_id = None
 
1255
            if changed_content:
 
1256
                keep_content = False
 
1257
                if kind[0] == 'file' and (backups or kind[1] is None):
 
1258
                    wt_sha1 = working_tree.get_file_sha1(file_id)
 
1259
                    if merge_modified.get(file_id) != wt_sha1:
 
1260
                        # acquire the basis tree lazyily to prevent the expense
 
1261
                        # of accessing it when its not needed ? (Guessing, RBC,
 
1262
                        # 200702)
 
1263
                        if basis_tree is None:
 
1264
                            basis_tree = working_tree.basis_tree()
 
1265
                            basis_tree.lock_read()
 
1266
                        if file_id in basis_tree:
 
1267
                            if wt_sha1 != basis_tree.get_file_sha1(file_id):
 
1268
                                keep_content = True
 
1269
                        elif kind[1] is None and not versioned[1]:
1261
1270
                            keep_content = True
1262
 
                    elif kind[1] is None and not versioned[1]:
1263
 
                        keep_content = True
1264
 
            if kind[0] is not None:
1265
 
                if not keep_content:
1266
 
                    tt.delete_contents(trans_id)
1267
 
                elif kind[1] is not None:
1268
 
                    parent_trans_id = tt.trans_id_file_id(parent[0])
1269
 
                    by_parent = tt.by_parent()
1270
 
                    backup_name = _get_backup_name(name[0], by_parent,
1271
 
                                                   parent_trans_id, tt)
1272
 
                    tt.adjust_path(backup_name, parent_trans_id, trans_id)
1273
 
                    new_trans_id = tt.create_path(name[0], parent_trans_id)
1274
 
                    if versioned == (True, True):
1275
 
                        tt.unversion_file(trans_id)
1276
 
                        tt.version_file(file_id, new_trans_id)
1277
 
                    # New contents should have the same unix perms as old
1278
 
                    # contents
1279
 
                    mode_id = trans_id
1280
 
                    trans_id = new_trans_id
1281
 
            if kind[1] == 'directory':
1282
 
                tt.create_directory(trans_id)
1283
 
            elif kind[1] == 'symlink':
1284
 
                tt.create_symlink(target_tree.get_symlink_target(file_id),
1285
 
                                  trans_id)
1286
 
            elif kind[1] == 'file':
1287
 
                tt.create_file(target_tree.get_file_lines(file_id),
1288
 
                               trans_id, mode_id)
1289
 
                # preserve the execute bit when backing up
1290
 
                if keep_content and executable[0] == executable[1]:
1291
 
                    tt.set_executability(executable[1], trans_id)
1292
 
            else:
1293
 
                assert kind[1] is None
1294
 
        if versioned == (False, True):
1295
 
            tt.version_file(file_id, trans_id)
1296
 
        if versioned == (True, False):
1297
 
            tt.unversion_file(trans_id)
1298
 
        if (name[1] is not None and 
1299
 
            (name[0] != name[1] or parent[0] != parent[1])):
1300
 
            tt.adjust_path(name[1], tt.trans_id_file_id(parent[1]), trans_id)
1301
 
        if executable[0] != executable[1] and kind[1] == "file":
1302
 
            tt.set_executability(executable[1], trans_id)
 
1271
                if kind[0] is not None:
 
1272
                    if not keep_content:
 
1273
                        tt.delete_contents(trans_id)
 
1274
                    elif kind[1] is not None:
 
1275
                        parent_trans_id = tt.trans_id_file_id(parent[0])
 
1276
                        by_parent = tt.by_parent()
 
1277
                        backup_name = _get_backup_name(name[0], by_parent,
 
1278
                                                       parent_trans_id, tt)
 
1279
                        tt.adjust_path(backup_name, parent_trans_id, trans_id)
 
1280
                        new_trans_id = tt.create_path(name[0], parent_trans_id)
 
1281
                        if versioned == (True, True):
 
1282
                            tt.unversion_file(trans_id)
 
1283
                            tt.version_file(file_id, new_trans_id)
 
1284
                        # New contents should have the same unix perms as old
 
1285
                        # contents
 
1286
                        mode_id = trans_id
 
1287
                        trans_id = new_trans_id
 
1288
                if kind[1] == 'directory':
 
1289
                    tt.create_directory(trans_id)
 
1290
                elif kind[1] == 'symlink':
 
1291
                    tt.create_symlink(target_tree.get_symlink_target(file_id),
 
1292
                                      trans_id)
 
1293
                elif kind[1] == 'file':
 
1294
                    tt.create_file(target_tree.get_file_lines(file_id),
 
1295
                                   trans_id, mode_id)
 
1296
                    # preserve the execute bit when backing up
 
1297
                    if keep_content and executable[0] == executable[1]:
 
1298
                        tt.set_executability(executable[1], trans_id)
 
1299
                else:
 
1300
                    assert kind[1] is None
 
1301
            if versioned == (False, True):
 
1302
                tt.version_file(file_id, trans_id)
 
1303
            if versioned == (True, False):
 
1304
                tt.unversion_file(trans_id)
 
1305
            if (name[1] is not None and 
 
1306
                (name[0] != name[1] or parent[0] != parent[1])):
 
1307
                tt.adjust_path(
 
1308
                    name[1], tt.trans_id_file_id(parent[1]), trans_id)
 
1309
            if executable[0] != executable[1] and kind[1] == "file":
 
1310
                tt.set_executability(executable[1], trans_id)
 
1311
    finally:
 
1312
        if basis_tree is not None:
 
1313
            basis_tree.unlock()
1303
1314
 
1304
1315
 
1305
1316
def resolve_conflicts(tt, pb=DummyProgress(), pass_func=None):