/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/transform.py

[merge] bzr.dev 2255, resolve conflicts, update copyrights

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
from bzrlib import bzrdir, errors
22
22
from bzrlib.errors import (DuplicateKey, MalformedTransform, NoSuchFile,
23
23
                           ReusingTransform, NotVersionedError, CantMoveRoot,
24
 
                           ExistingLimbo, ImmortalLimbo)
 
24
                           ExistingLimbo, ImmortalLimbo, NoFinalPath)
25
25
from bzrlib.inventory import InventoryEntry
26
26
from bzrlib.osutils import (file_kind, supports_executable, pathjoin, lexists,
27
27
                            delete_any)
273
273
                os.unlink(name)
274
274
                raise
275
275
 
276
 
            for segment in contents:
277
 
                f.write(segment)
 
276
            f.writelines(contents)
278
277
        finally:
279
278
            f.close()
280
279
        self._set_mode(trans_id, mode_id, S_ISREG)
457
456
        try:
458
457
            return self._new_name[trans_id]
459
458
        except KeyError:
460
 
            return os.path.basename(self._tree_id_paths[trans_id])
 
459
            try:
 
460
                return os.path.basename(self._tree_id_paths[trans_id])
 
461
            except KeyError:
 
462
                raise NoFinalPath(trans_id, self)
461
463
 
462
464
    def by_parent(self):
463
465
        """Return a map of parent: children for known parents.
570
572
            parent_id = trans_id
571
573
            while parent_id is not ROOT_PARENT:
572
574
                seen.add(parent_id)
573
 
                parent_id = self.final_parent(parent_id)
 
575
                try:
 
576
                    parent_id = self.final_parent(parent_id)
 
577
                except KeyError:
 
578
                    break
574
579
                if parent_id == trans_id:
575
580
                    conflicts.append(('parent loop', trans_id))
576
581
                if parent_id in seen:
954
959
      it is silently replaced.
955
960
    - Otherwise, conflict resolution will move the old file to 'oldname.moved'.
956
961
    """
957
 
    assert 2 > len(wt.inventory)
 
962
    if len(wt.inventory) > 1:  # more than just a root
 
963
        raise errors.WorkingTreeAlreadyPopulated(base=wt.basedir)
958
964
    file_trans_id = {}
959
965
    top_pb = bzrlib.ui.ui_factory.nested_progress_bar()
960
966
    pp = ProgressPhase("Build phase", 2, top_pb)
 
967
    if tree.inventory.root is not None:
 
968
        wt.set_root_id(tree.inventory.root.file_id)
961
969
    tt = TreeTransform(wt)
962
970
    divert = set()
963
971
    try:
1147
1155
 
1148
1156
 
1149
1157
def get_backup_name(entry, by_parent, parent_trans_id, tt):
 
1158
    return _get_backup_name(entry.name, by_parent, parent_trans_id, tt)
 
1159
 
 
1160
 
 
1161
def _get_backup_name(name, by_parent, parent_trans_id, tt):
1150
1162
    """Produce a backup-style name that appears to be available"""
1151
1163
    def name_gen():
1152
1164
        counter = 1
1153
1165
        while True:
1154
 
            yield "%s.~%d~" % (entry.name, counter)
 
1166
            yield "%s.~%d~" % (name, counter)
1155
1167
            counter += 1
1156
 
    for name in name_gen():
1157
 
        if not tt.has_named_child(by_parent, parent_trans_id, name):
1158
 
            return name
 
1168
    for new_name in name_gen():
 
1169
        if not tt.has_named_child(by_parent, parent_trans_id, new_name):
 
1170
            return new_name
 
1171
 
1159
1172
 
1160
1173
def _entry_changes(file_id, entry, working_tree):
1161
1174
    """Determine in which ways the inventory entry has changed.
1185
1198
 
1186
1199
 
1187
1200
def revert(working_tree, target_tree, filenames, backups=False, 
1188
 
           pb=DummyProgress()):
 
1201
           pb=DummyProgress(), change_reporter=None):
1189
1202
    """Revert a working tree's contents to those of a target tree."""
1190
1203
    interesting_ids = find_interesting(working_tree, target_tree, filenames)
1191
 
    def interesting(file_id):
1192
 
        return interesting_ids is None or (file_id in interesting_ids)
1193
 
 
1194
1204
    tt = TreeTransform(working_tree, pb)
1195
1205
    try:
1196
 
        merge_modified = working_tree.merge_modified()
1197
 
        trans_id = {}
1198
 
        def trans_id_file_id(file_id):
1199
 
            try:
1200
 
                return trans_id[file_id]
1201
 
            except KeyError:
1202
 
                return tt.trans_id_tree_file_id(file_id)
1203
 
 
1204
 
        pp = ProgressPhase("Revert phase", 4, pb)
1205
 
        pp.next_phase()
1206
 
        sorted_interesting = [i for i in topology_sorted_ids(target_tree) if
1207
 
                              interesting(i)]
1208
 
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1209
 
        try:
1210
 
            by_parent = tt.by_parent()
1211
 
            for id_num, file_id in enumerate(sorted_interesting):
1212
 
                child_pb.update("Reverting file", id_num+1, 
1213
 
                                len(sorted_interesting))
1214
 
                if file_id not in working_tree.inventory:
1215
 
                    entry = target_tree.inventory[file_id]
1216
 
                    parent_id = trans_id_file_id(entry.parent_id)
1217
 
                    e_trans_id = new_by_entry(tt, entry, parent_id, target_tree)
1218
 
                    trans_id[file_id] = e_trans_id
1219
 
                else:
1220
 
                    backup_this = backups
1221
 
                    if file_id in merge_modified:
1222
 
                        backup_this = False
1223
 
                        del merge_modified[file_id]
1224
 
                    change_entry(tt, file_id, working_tree, target_tree, 
1225
 
                                 trans_id_file_id, backup_this, trans_id,
1226
 
                                 by_parent)
1227
 
        finally:
1228
 
            child_pb.finished()
1229
 
        pp.next_phase()
1230
 
        wt_interesting = [i for i in working_tree.inventory if interesting(i)]
1231
 
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1232
 
        basis_tree = None
1233
 
        try:
1234
 
            for id_num, file_id in enumerate(wt_interesting):
1235
 
                child_pb.update("New file check", id_num+1, 
1236
 
                                len(sorted_interesting))
1237
 
                if file_id not in target_tree:
1238
 
                    trans_id = tt.trans_id_tree_file_id(file_id)
1239
 
                    tt.unversion_file(trans_id)
1240
 
                    try:
1241
 
                        file_kind = working_tree.kind(file_id)
1242
 
                    except NoSuchFile:
1243
 
                        file_kind = None
1244
 
                    delete_merge_modified = (file_id in merge_modified)
1245
 
                    if file_kind != 'file' and file_kind is not None:
1246
 
                        keep_contents = False
1247
 
                    else:
1248
 
                        if basis_tree is None:
1249
 
                            basis_tree = working_tree.basis_tree()
1250
 
                        wt_sha1 = working_tree.get_file_sha1(file_id)
1251
 
                        if (file_id in merge_modified and 
1252
 
                            merge_modified[file_id] == wt_sha1):
1253
 
                            keep_contents = False
1254
 
                        elif (file_id in basis_tree and 
1255
 
                            basis_tree.get_file_sha1(file_id) == wt_sha1):
1256
 
                            keep_contents = False
1257
 
                        else:
1258
 
                            keep_contents = True
1259
 
                    if not keep_contents:
1260
 
                        tt.delete_contents(trans_id)
1261
 
                    if delete_merge_modified:
1262
 
                        del merge_modified[file_id]
 
1206
        pp = ProgressPhase("Revert phase", 3, pb)
 
1207
        pp.next_phase()
 
1208
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
1209
        try:
 
1210
            _alter_files(working_tree, target_tree, tt, child_pb, 
 
1211
                         interesting_ids, backups, change_reporter)
1263
1212
        finally:
1264
1213
            child_pb.finished()
1265
1214
        pp.next_phase()
1280
1229
    return conflicts
1281
1230
 
1282
1231
 
 
1232
def _alter_files(working_tree, target_tree, tt, pb, interesting_ids, backups,
 
1233
                 report_changes):
 
1234
    from bzrlib import delta
 
1235
    merge_modified = working_tree.merge_modified()
 
1236
    change_list = list(target_tree._iter_changes(working_tree,
 
1237
        specific_file_ids=interesting_ids, 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
    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):
 
1261
                            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)
 
1303
 
 
1304
 
1283
1305
def resolve_conflicts(tt, pb=DummyProgress(), pass_func=None):
1284
1306
    """Make many conflict-resolution attempts, but die if they fail"""
1285
1307
    if pass_func is None: