~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-12-02 04:45:19 UTC
  • mfrom: (2012.1.18 tree-compare)
  • Revision ID: pqm@pqm.ubuntu.com-20061202044519-b51893edd371d01d
New low-level interface for determining differences between trees

Show diffs side-by-side

added added

removed removed

Lines of Context:
1156
1156
 
1157
1157
 
1158
1158
def get_backup_name(entry, by_parent, parent_trans_id, tt):
 
1159
    return _get_backup_name(entry.name, by_parent, parent_trans_id, tt)
 
1160
 
 
1161
 
 
1162
def _get_backup_name(name, by_parent, parent_trans_id, tt):
1159
1163
    """Produce a backup-style name that appears to be available"""
1160
1164
    def name_gen():
1161
1165
        counter = 1
1162
1166
        while True:
1163
 
            yield "%s.~%d~" % (entry.name, counter)
 
1167
            yield "%s.~%d~" % (name, counter)
1164
1168
            counter += 1
1165
 
    for name in name_gen():
1166
 
        if not tt.has_named_child(by_parent, parent_trans_id, name):
1167
 
            return name
 
1169
    for new_name in name_gen():
 
1170
        if not tt.has_named_child(by_parent, parent_trans_id, new_name):
 
1171
            return new_name
 
1172
 
1168
1173
 
1169
1174
def _entry_changes(file_id, entry, working_tree):
1170
1175
    """Determine in which ways the inventory entry has changed.
1197
1202
           pb=DummyProgress()):
1198
1203
    """Revert a working tree's contents to those of a target tree."""
1199
1204
    interesting_ids = find_interesting(working_tree, target_tree, filenames)
1200
 
    def interesting(file_id):
1201
 
        return interesting_ids is None or (file_id in interesting_ids)
1202
 
 
1203
1205
    tt = TreeTransform(working_tree, pb)
1204
1206
    try:
1205
 
        merge_modified = working_tree.merge_modified()
1206
 
        trans_id = {}
1207
 
        def trans_id_file_id(file_id):
1208
 
            try:
1209
 
                return trans_id[file_id]
1210
 
            except KeyError:
1211
 
                return tt.trans_id_tree_file_id(file_id)
1212
 
 
1213
 
        pp = ProgressPhase("Revert phase", 4, pb)
1214
 
        pp.next_phase()
1215
 
        sorted_interesting = [i for i in topology_sorted_ids(target_tree) if
1216
 
                              interesting(i)]
1217
 
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1218
 
        try:
1219
 
            by_parent = tt.by_parent()
1220
 
            for id_num, file_id in enumerate(sorted_interesting):
1221
 
                child_pb.update("Reverting file", id_num+1, 
1222
 
                                len(sorted_interesting))
1223
 
                if file_id not in working_tree.inventory:
1224
 
                    entry = target_tree.inventory[file_id]
1225
 
                    parent_id = trans_id_file_id(entry.parent_id)
1226
 
                    e_trans_id = new_by_entry(tt, entry, parent_id, target_tree)
1227
 
                    trans_id[file_id] = e_trans_id
1228
 
                else:
1229
 
                    backup_this = backups
1230
 
                    if file_id in merge_modified:
1231
 
                        backup_this = False
1232
 
                        del merge_modified[file_id]
1233
 
                    change_entry(tt, file_id, working_tree, target_tree, 
1234
 
                                 trans_id_file_id, backup_this, trans_id,
1235
 
                                 by_parent)
1236
 
        finally:
1237
 
            child_pb.finished()
1238
 
        pp.next_phase()
1239
 
        wt_interesting = [i for i in working_tree.inventory if interesting(i)]
1240
 
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1241
 
        basis_tree = None
1242
 
        try:
1243
 
            for id_num, file_id in enumerate(wt_interesting):
1244
 
                if (working_tree.inventory.is_root(file_id) and 
1245
 
                    len(target_tree.inventory) == 0):
1246
 
                    continue
1247
 
                child_pb.update("New file check", id_num+1, 
1248
 
                                len(sorted_interesting))
1249
 
                if file_id not in target_tree:
1250
 
                    trans_id = tt.trans_id_tree_file_id(file_id)
1251
 
                    tt.unversion_file(trans_id)
1252
 
                    try:
1253
 
                        file_kind = working_tree.kind(file_id)
1254
 
                    except NoSuchFile:
1255
 
                        file_kind = None
1256
 
                    delete_merge_modified = (file_id in merge_modified)
1257
 
                    if file_kind != 'file' and file_kind is not None:
1258
 
                        keep_contents = False
1259
 
                    else:
1260
 
                        if basis_tree is None:
1261
 
                            basis_tree = working_tree.basis_tree()
1262
 
                        wt_sha1 = working_tree.get_file_sha1(file_id)
1263
 
                        if (file_id in merge_modified and 
1264
 
                            merge_modified[file_id] == wt_sha1):
1265
 
                            keep_contents = False
1266
 
                        elif (file_id in basis_tree and 
1267
 
                            basis_tree.get_file_sha1(file_id) == wt_sha1):
1268
 
                            keep_contents = False
1269
 
                        else:
1270
 
                            keep_contents = True
1271
 
                    if not keep_contents:
1272
 
                        tt.delete_contents(trans_id)
1273
 
                    if delete_merge_modified:
1274
 
                        del merge_modified[file_id]
 
1207
        pp = ProgressPhase("Revert phase", 3, pb)
 
1208
        pp.next_phase()
 
1209
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
1210
        try:
 
1211
            _alter_files(working_tree, target_tree, tt, child_pb, 
 
1212
                         interesting_ids, backups)
1275
1213
        finally:
1276
1214
            child_pb.finished()
1277
1215
        pp.next_phase()
1292
1230
    return conflicts
1293
1231
 
1294
1232
 
 
1233
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids, backups):
 
1234
    merge_modified = working_tree.merge_modified()
 
1235
    iterator = target_tree._iter_changes(working_tree, 
 
1236
                                         specific_file_ids=interesting_ids,
 
1237
                                         pb=pb)
 
1238
    if target_tree.inventory.root is None:
 
1239
        skip_root = True
 
1240
    else:
 
1241
        skip_root = False
 
1242
    basis_tree = None
 
1243
    for id_num, (file_id, path, changed_content, versioned, parent, name, kind,
 
1244
                 executable) in enumerate(iterator):
 
1245
        if skip_root and file_id[0] is not None and parent[0] is None:
 
1246
            continue
 
1247
        trans_id = tt.trans_id_file_id(file_id)
 
1248
        mode_id = None
 
1249
        if changed_content:
 
1250
            keep_content = False
 
1251
            if kind[0] == 'file' and (backups or kind[1] is None):
 
1252
                wt_sha1 = working_tree.get_file_sha1(file_id)
 
1253
                if merge_modified.get(file_id) != wt_sha1:
 
1254
                    if basis_tree is None:
 
1255
                        basis_tree = working_tree.basis_tree()
 
1256
                    if file_id in basis_tree:
 
1257
                        if wt_sha1 != basis_tree.get_file_sha1(file_id):
 
1258
                            keep_content = True
 
1259
                    elif kind[1] is None and not versioned[1]:
 
1260
                        keep_content = True
 
1261
            if kind[0] is not None:
 
1262
                if not keep_content:
 
1263
                    tt.delete_contents(trans_id)
 
1264
                elif kind[1] is not None:
 
1265
                    parent_trans_id = tt.trans_id_file_id(parent[0])
 
1266
                    by_parent = tt.by_parent()
 
1267
                    backup_name = _get_backup_name(name[0], by_parent,
 
1268
                                                   parent_trans_id, tt)
 
1269
                    tt.adjust_path(backup_name, parent_trans_id, trans_id)
 
1270
                    new_trans_id = tt.create_path(name[0], parent_trans_id)
 
1271
                    if versioned == (True, True):
 
1272
                        tt.unversion_file(trans_id)
 
1273
                        tt.version_file(file_id, new_trans_id)
 
1274
                    mode_id = trans_id
 
1275
                    trans_id = new_trans_id
 
1276
            if kind[1] == 'directory':
 
1277
                tt.create_directory(trans_id)
 
1278
            elif kind[1] == 'symlink':
 
1279
                tt.create_symlink(target_tree.get_symlink_target(file_id),
 
1280
                                  trans_id)
 
1281
            elif kind[1] == 'file':
 
1282
                tt.create_file(target_tree.get_file_lines(file_id),
 
1283
                               trans_id)
 
1284
                if executable[0] != executable[1]:
 
1285
                    tt.set_executability(executable[1], trans_id)
 
1286
            else:
 
1287
                assert kind[1] is None
 
1288
        if versioned == (False, True):
 
1289
            tt.version_file(file_id, trans_id)
 
1290
        if versioned == (True, False):
 
1291
            tt.unversion_file(trans_id)
 
1292
        if (name[1] is not None and 
 
1293
            (name[0] != name[1] or parent[0] != parent[1])):
 
1294
            tt.adjust_path(name[1], tt.trans_id_file_id(parent[1]), trans_id)
 
1295
 
 
1296
 
1295
1297
def resolve_conflicts(tt, pb=DummyProgress(), pass_func=None):
1296
1298
    """Make many conflict-resolution attempts, but die if they fail"""
1297
1299
    if pass_func is None: