/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 with walkdirs

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
    delta,
28
28
    errors,
29
29
    inventory,
 
30
    osutils,
30
31
    revision as _mod_revision,
31
32
    )
32
33
""")
470
471
        """
471
472
        new_ids = set()
472
473
        if filesystem_only:
473
 
            id_sets = (self._needs_rename, self._new_executability)
 
474
            stale_ids = self._needs_rename.difference(self._new_name)
 
475
            stale_ids.difference_update(self._new_parent)
 
476
            stale_ids.difference_update(self._new_contents)
 
477
            stale_ids.difference_update(self._new_id)
 
478
            needs_rename = self._needs_rename.difference(stale_ids)
 
479
            id_sets = (needs_rename, self._new_executability)
474
480
        else:
475
481
            id_sets = (self._new_name, self._new_parent, self._new_contents,
476
482
                       self._new_id, self._new_executability)
478
484
            new_ids.update(id_set)
479
485
        return sorted(FinalPaths(self).get_paths(new_ids))
480
486
 
 
487
    def _inventory_altered(self):
 
488
        """Get the trans_ids and paths of files needing new inv entries."""
 
489
        new_ids = set()
 
490
        for id_set in [self._new_name, self._new_parent, self._new_id,
 
491
                       self._new_executability]:
 
492
            new_ids.update(id_set)
 
493
        changed_kind = set(self._removed_contents)
 
494
        changed_kind.intersection_update(self._new_contents)
 
495
        changed_kind.difference_update(new_ids)
 
496
        changed_kind = (t for t in changed_kind if self.tree_kind(t) !=
 
497
                        self.final_kind(t))
 
498
        new_ids.update(changed_kind)
 
499
        return sorted(FinalPaths(self).get_paths(new_ids))
 
500
 
481
501
    def tree_kind(self, trans_id):
482
502
        """Determine the file kind in the working tree.
483
503
 
636
656
        try:
637
657
            children = os.listdir(self._tree.abspath(path))
638
658
        except OSError, e:
639
 
            if e.errno not in (errno.ENOENT, errno.ESRCH, errno.ENOTDIR):
 
659
            if not (osutils._is_error_enotdir(e)
 
660
                    or e.errno in (errno.ENOENT, errno.ESRCH)):
640
661
                raise
641
662
            return
642
 
            
 
663
 
643
664
        for child in children:
644
665
            childpath = joinpath(path, child)
645
666
            if self._tree.is_control_filename(childpath):
870
891
        self._limbo_files[trans_id] = limbo_name
871
892
        return limbo_name
872
893
 
873
 
    def _set_executability(self, path, entry, trans_id):
 
894
    def _set_executability(self, path, trans_id):
874
895
        """Set the executability of versioned files """
875
 
        new_executability = self._new_executability[trans_id]
876
 
        if entry is not None:
877
 
            entry.executable = new_executability
878
896
        if supports_executable():
 
897
            new_executability = self._new_executability[trans_id]
879
898
            abspath = self._tree.abspath(path)
880
899
            current_mode = os.stat(abspath).st_mode
881
900
            if new_executability:
1203
1222
            conflicts = self.find_conflicts()
1204
1223
            if len(conflicts) != 0:
1205
1224
                raise MalformedTransform(conflicts=conflicts)
1206
 
        if precomputed_delta is None:
1207
 
            new_inventory_delta = []
1208
 
            inventory_delta = new_inventory_delta
1209
 
        else:
1210
 
            new_inventory_delta = None
1211
 
            inventory_delta = precomputed_delta
1212
1225
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1213
1226
        try:
 
1227
            if precomputed_delta is None:
 
1228
                child_pb.update('Apply phase', 0, 2)
 
1229
                inventory_delta = self._generate_inventory_delta()
 
1230
                offset = 1
 
1231
            else:
 
1232
                inventory_delta = precomputed_delta
 
1233
                offset = 0
1214
1234
            if _mover is None:
1215
1235
                mover = _FileMover()
1216
1236
            else:
1217
1237
                mover = _mover
1218
1238
            try:
1219
 
                child_pb.update('Apply phase', 0, 2)
1220
 
                self._apply_removals(new_inventory_delta, mover)
1221
 
                child_pb.update('Apply phase', 1, 2)
1222
 
                modified_paths = self._apply_insertions(new_inventory_delta,
1223
 
                                                        mover)
 
1239
                child_pb.update('Apply phase', 0 + offset, 2 + offset)
 
1240
                self._apply_removals(mover)
 
1241
                child_pb.update('Apply phase', 1 + offset, 2 + offset)
 
1242
                modified_paths = self._apply_insertions(mover)
1224
1243
            except:
1225
1244
                mover.rollback()
1226
1245
                raise
1233
1252
        self.finalize()
1234
1253
        return _TransformResults(modified_paths, self.rename_count)
1235
1254
 
1236
 
    def _apply_removals(self, inventory_delta, mover):
 
1255
    def _generate_inventory_delta(self):
 
1256
        """Generate an inventory delta for the current transform."""
 
1257
        inventory_delta = []
 
1258
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
 
1259
        new_paths = self._inventory_altered()
 
1260
        total_entries = len(new_paths) + len(self._removed_id)
 
1261
        try:
 
1262
            for num, trans_id in enumerate(self._removed_id):
 
1263
                if (num % 10) == 0:
 
1264
                    child_pb.update('removing file', num, total_entries)
 
1265
                if trans_id == self._new_root:
 
1266
                    file_id = self._tree.get_root_id()
 
1267
                else:
 
1268
                    file_id = self.tree_file_id(trans_id)
 
1269
                # File-id isn't really being deleted, just moved
 
1270
                if file_id in self._r_new_id:
 
1271
                    continue
 
1272
                path = self._tree_id_paths[trans_id]
 
1273
                inventory_delta.append((path, None, file_id, None))
 
1274
            new_path_file_ids = dict((t, self.final_file_id(t)) for p, t in
 
1275
                                     new_paths)
 
1276
            entries = self._tree.iter_entries_by_dir(
 
1277
                new_path_file_ids.values())
 
1278
            old_paths = dict((e.file_id, p) for p, e in entries)
 
1279
            final_kinds = {}
 
1280
            for num, (path, trans_id) in enumerate(new_paths):
 
1281
                if (num % 10) == 0:
 
1282
                    child_pb.update('adding file',
 
1283
                                    num + len(self._removed_id), total_entries)
 
1284
                file_id = new_path_file_ids[trans_id]
 
1285
                if file_id is None:
 
1286
                    continue
 
1287
                needs_entry = False
 
1288
                try:
 
1289
                    kind = self.final_kind(trans_id)
 
1290
                except NoSuchFile:
 
1291
                    kind = self._tree.stored_kind(file_id)
 
1292
                parent_trans_id = self.final_parent(trans_id)
 
1293
                parent_file_id = new_path_file_ids.get(parent_trans_id)
 
1294
                if parent_file_id is None:
 
1295
                    parent_file_id = self.final_file_id(parent_trans_id)
 
1296
                if trans_id in self._new_reference_revision:
 
1297
                    new_entry = inventory.TreeReference(
 
1298
                        file_id,
 
1299
                        self._new_name[trans_id],
 
1300
                        self.final_file_id(self._new_parent[trans_id]),
 
1301
                        None, self._new_reference_revision[trans_id])
 
1302
                else:
 
1303
                    new_entry = inventory.make_entry(kind,
 
1304
                        self.final_name(trans_id),
 
1305
                        parent_file_id, file_id)
 
1306
                old_path = old_paths.get(new_entry.file_id)
 
1307
                new_executability = self._new_executability.get(trans_id)
 
1308
                if new_executability is not None:
 
1309
                    new_entry.executable = new_executability
 
1310
                inventory_delta.append(
 
1311
                    (old_path, path, new_entry.file_id, new_entry))
 
1312
        finally:
 
1313
            child_pb.finished()
 
1314
        return inventory_delta
 
1315
 
 
1316
    def _apply_removals(self, mover):
1237
1317
        """Perform tree operations that remove directory/inventory names.
1238
1318
 
1239
1319
        That is, delete files that are to be deleted, and put any files that
1244
1324
        """
1245
1325
        tree_paths = list(self._tree_path_ids.iteritems())
1246
1326
        tree_paths.sort(reverse=True)
 
1327
        kind_changes = set()
1247
1328
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1248
1329
        try:
1249
1330
            for num, data in enumerate(tree_paths):
1262
1343
                            raise
1263
1344
                    else:
1264
1345
                        self.rename_count += 1
1265
 
                if (trans_id in self._removed_id
1266
 
                    and inventory_delta is not None):
1267
 
                    if trans_id == self._new_root:
1268
 
                        file_id = self._tree.get_root_id()
1269
 
                    else:
1270
 
                        file_id = self.tree_file_id(trans_id)
1271
 
                    # File-id isn't really being deleted, just moved
1272
 
                    if file_id in self._r_new_id:
1273
 
                        continue
1274
 
                    inventory_delta.append((path, None, file_id, None))
1275
1346
        finally:
1276
1347
            child_pb.finished()
 
1348
        return kind_changes
1277
1349
 
1278
 
    def _apply_insertions(self, inventory_delta, mover):
 
1350
    def _apply_insertions(self, mover):
1279
1351
        """Perform tree operations that insert directory/inventory names.
1280
1352
 
1281
1353
        That is, create any files that need to be created, and restore from
1284
1356
 
1285
1357
        If inventory_delta is None, no inventory delta is calculated, and
1286
1358
        no list of modified paths is returned.
 
1359
 
 
1360
        kind_changes is a set of trans ids where the entry has changed
 
1361
        kind, and so an inventory delta entry should be created for them.
1287
1362
        """
1288
 
        new_paths = self.new_paths(filesystem_only=(inventory_delta is None))
 
1363
        new_paths = self.new_paths(filesystem_only=True)
1289
1364
        modified_paths = []
1290
 
        completed_new = []
1291
1365
        new_path_file_ids = dict((t, self.final_file_id(t)) for p, t in
1292
1366
                                 new_paths)
1293
 
        if inventory_delta is not None:
1294
 
            entries = self._tree.iter_entries_by_dir(
1295
 
                new_path_file_ids.values())
1296
 
            old_paths = dict((e.file_id, p) for p, e in entries)
1297
1367
        child_pb = bzrlib.ui.ui_factory.nested_progress_bar()
1298
1368
        try:
1299
1369
            for num, (path, trans_id) in enumerate(new_paths):
1300
 
                new_entry = None
1301
1370
                if (num % 10) == 0:
1302
1371
                    child_pb.update('adding file', num, len(new_paths))
1303
1372
                full_path = self._tree.abspath(path)
1310
1379
                            raise
1311
1380
                    else:
1312
1381
                        self.rename_count += 1
1313
 
                if inventory_delta is not None:
1314
 
                    if (trans_id in self._new_contents or
1315
 
                        self.path_changed(trans_id)):
1316
 
                        if trans_id in self._new_contents:
1317
 
                            modified_paths.append(full_path)
1318
 
                            completed_new.append(trans_id)
1319
 
                    file_id = new_path_file_ids[trans_id]
1320
 
                    if file_id is not None and (trans_id in self._new_id or
1321
 
                        trans_id in self._new_name or
1322
 
                        trans_id in self._new_parent
1323
 
                        or trans_id in self._new_executability):
1324
 
                        try:
1325
 
                            kind = self.final_kind(trans_id)
1326
 
                        except NoSuchFile:
1327
 
                            kind = self._tree.stored_kind(file_id)
1328
 
                        parent_trans_id = self.final_parent(trans_id)
1329
 
                        parent_file_id = new_path_file_ids.get(parent_trans_id)
1330
 
                        if parent_file_id is None:
1331
 
                            parent_file_id = self.final_file_id(
1332
 
                                parent_trans_id)
1333
 
                        if trans_id in self._new_reference_revision:
1334
 
                            new_entry = inventory.TreeReference(
1335
 
                                file_id,
1336
 
                                self._new_name[trans_id],
1337
 
                                self.final_file_id(self._new_parent[trans_id]),
1338
 
                                None, self._new_reference_revision[trans_id])
1339
 
                        else:
1340
 
                            new_entry = inventory.make_entry(kind,
1341
 
                                self.final_name(trans_id),
1342
 
                                parent_file_id, file_id)
1343
 
                        old_path = old_paths.get(new_entry.file_id)
1344
 
                        inventory_delta.append(
1345
 
                            (old_path, path, new_entry.file_id, new_entry))
1346
 
 
 
1382
                if (trans_id in self._new_contents or
 
1383
                    self.path_changed(trans_id)):
 
1384
                    if trans_id in self._new_contents:
 
1385
                        modified_paths.append(full_path)
1347
1386
                if trans_id in self._new_executability:
1348
 
                    self._set_executability(path, new_entry, trans_id)
 
1387
                    self._set_executability(path, trans_id)
1349
1388
        finally:
1350
1389
            child_pb.finished()
1351
 
        if inventory_delta is None:
1352
 
            self._new_contents.clear()
1353
 
        else:
1354
 
            for trans_id in completed_new:
1355
 
                del self._new_contents[trans_id]
 
1390
        self._new_contents.clear()
1356
1391
        return modified_paths
1357
1392
 
1358
1393