/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/workingtree_4.py

  • Committer: Daniel Watkins
  • Date: 2007-11-06 09:33:05 UTC
  • mfrom: (2967 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2993.
  • Revision ID: d.m.watkins@warwick.ac.uk-20071106093305-zfef3c0jbcvunnuz
Merged bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
49
49
    errors,
50
50
    generate_ids,
51
51
    globbing,
52
 
    hashcache,
53
52
    ignores,
54
53
    merge,
55
54
    osutils,
159
158
        state = self.current_dirstate()
160
159
        for f, file_id, kind in zip(files, ids, kinds):
161
160
            f = f.strip('/')
162
 
            assert '//' not in f
163
 
            assert '..' not in f
164
161
            if self.path2id(f):
165
162
                # special case tree root handling.
166
163
                if f == '' and self.path2id(f) == ROOT_ID:
271
268
        self._dirstate = dirstate.DirState.on_file(local_path)
272
269
        return self._dirstate
273
270
 
274
 
    def _directory_is_tree_reference(self, relpath):
275
 
        # as a special case, if a directory contains control files then 
276
 
        # it's a tree reference, except that the root of the tree is not
277
 
        return relpath and osutils.isdir(self.abspath(relpath) + u"/.bzr")
278
 
        # TODO: We could ask all the control formats whether they
279
 
        # recognize this directory, but at the moment there's no cheap api
280
 
        # to do that.  Since we probably can only nest bzr checkouts and
281
 
        # they always use this name it's ok for now.  -- mbp 20060306
282
 
        #
283
 
        # FIXME: There is an unhandled case here of a subdirectory
284
 
        # containing .bzr but not a branch; that will probably blow up
285
 
        # when you try to commit it.  It might happen if there is a
286
 
        # checkout in a subdirectory.  This can be avoided by not adding
287
 
        # it.  mbp 20070306
288
 
 
289
271
    def filter_unversioned_files(self, paths):
290
272
        """Filter out paths that are versioned.
291
273
 
469
451
 
470
452
    def has_id(self, file_id):
471
453
        state = self.current_dirstate()
472
 
        file_id = osutils.safe_file_id(file_id)
473
454
        row, parents = self._get_entry(file_id=file_id)
474
455
        if row is None:
475
456
            return False
479
460
    @needs_read_lock
480
461
    def id2path(self, file_id):
481
462
        "Convert a file-id to a path."
482
 
        file_id = osutils.safe_file_id(file_id)
483
463
        state = self.current_dirstate()
484
464
        entry = self._get_entry(file_id=file_id)
485
465
        if entry == (None, None):
487
467
        path_utf8 = osutils.pathjoin(entry[0][0], entry[0][1])
488
468
        return path_utf8.decode('utf8')
489
469
 
 
470
    def _is_executable_from_path_and_stat_from_basis(self, path, stat_result):
 
471
        entry = self._get_entry(path=path)
 
472
        if entry == (None, None):
 
473
            return False # Missing entries are not executable
 
474
        return entry[1][0][3] # Executable?
 
475
 
490
476
    if not osutils.supports_executable():
491
477
        def is_executable(self, file_id, path=None):
492
478
            """Test if a file is executable or not.
493
479
 
494
480
            Note: The caller is expected to take a read-lock before calling this.
495
481
            """
496
 
            file_id = osutils.safe_file_id(file_id)
497
482
            entry = self._get_entry(file_id=file_id, path=path)
498
483
            if entry == (None, None):
499
484
                return False
500
485
            return entry[1][0][3]
 
486
 
 
487
        _is_executable_from_path_and_stat = \
 
488
            _is_executable_from_path_and_stat_from_basis
501
489
    else:
502
490
        def is_executable(self, file_id, path=None):
503
491
            """Test if a file is executable or not.
505
493
            Note: The caller is expected to take a read-lock before calling this.
506
494
            """
507
495
            if not path:
508
 
                file_id = osutils.safe_file_id(file_id)
509
496
                path = self.id2path(file_id)
510
497
            mode = os.lstat(self.abspath(path)).st_mode
511
498
            return bool(stat.S_ISREG(mode) and stat.S_IEXEC & mode)
946
933
            if not all_versioned:
947
934
                raise errors.PathsNotVersionedError(paths)
948
935
        # -- remove redundancy in supplied paths to prevent over-scanning --
949
 
        search_paths = set()
950
 
        for path in paths:
951
 
            other_paths = paths.difference(set([path]))
952
 
            if not osutils.is_inside_any(other_paths, path):
953
 
                # this is a top level path, we must check it.
954
 
                search_paths.add(path)
 
936
        search_paths = osutils.minimum_path_selection(paths)
955
937
        # sketch: 
956
938
        # for all search_indexs in each path at or under each element of
957
939
        # search_paths, if the detail is relocated: add the id, and add the
1025
1007
 
1026
1008
        WorkingTree4 supplies revision_trees for any basis tree.
1027
1009
        """
1028
 
        revision_id = osutils.safe_revision_id(revision_id)
1029
1010
        dirstate = self.current_dirstate()
1030
1011
        parent_ids = dirstate.get_parent_ids()
1031
1012
        if revision_id not in parent_ids:
1038
1019
    @needs_tree_write_lock
1039
1020
    def set_last_revision(self, new_revision):
1040
1021
        """Change the last revision in the working tree."""
1041
 
        new_revision = osutils.safe_revision_id(new_revision)
1042
1022
        parents = self.get_parent_ids()
1043
1023
        if new_revision in (NULL_REVISION, None):
1044
1024
            assert len(parents) < 2, (
1062
1042
        :param revision_ids: The revision_ids to set as the parent ids of this
1063
1043
            working tree. Any of these may be ghosts.
1064
1044
        """
1065
 
        revision_ids = [osutils.safe_revision_id(r) for r in revision_ids]
1066
1045
        trees = []
1067
1046
        for revision_id in revision_ids:
1068
1047
            try:
1094
1073
        # convert absent trees to the null tree, which we convert back to
1095
1074
        # missing on access.
1096
1075
        for rev_id, tree in parents_list:
1097
 
            rev_id = osutils.safe_revision_id(rev_id)
1098
1076
            _mod_revision.check_not_reserved_id(rev_id)
1099
1077
            if tree is not None:
1100
1078
                real_trees.append((rev_id, tree))
1112
1090
        if state._dirblock_state == dirstate.DirState.IN_MEMORY_MODIFIED:
1113
1091
            self._make_dirty(reset_inventory=True)
1114
1092
 
 
1093
    def _sha_from_stat(self, path, stat_result):
 
1094
        """Get a sha digest from the tree's stat cache.
 
1095
 
 
1096
        The default implementation assumes no stat cache is present.
 
1097
 
 
1098
        :param path: The path.
 
1099
        :param stat_result: The stat result being looked up.
 
1100
        """
 
1101
        return self.current_dirstate().sha1_from_stat(path, stat_result)
 
1102
 
1115
1103
    @needs_read_lock
1116
1104
    def supports_tree_reference(self):
1117
1105
        return self._repo_supports_tree_reference
1157
1145
            return
1158
1146
        state = self.current_dirstate()
1159
1147
        state._read_dirblocks_if_needed()
1160
 
        ids_to_unversion = set()
1161
 
        for file_id in file_ids:
1162
 
            ids_to_unversion.add(osutils.safe_file_id(file_id))
 
1148
        ids_to_unversion = set(file_ids)
1163
1149
        paths_to_unversion = set()
1164
1150
        # sketch:
1165
1151
        # check if the root is to be unversioned, if so, assert for now.
1195
1181
                    # Mark this file id as having been removed
1196
1182
                    entry = block[1][entry_index]
1197
1183
                    ids_to_unversion.discard(entry[0][2])
1198
 
                    if (entry[1][0][0] == 'a'
 
1184
                    if (entry[1][0][0] in 'ar' # don't remove absent or renamed
 
1185
                                               # entries
1199
1186
                        or not state._make_absent(entry)):
1200
1187
                        entry_index += 1
1201
1188
                # go to the next block. (At the moment we dont delete empty
1226
1213
            for file_id in file_ids:
1227
1214
                self._inventory.remove_recursive_id(file_id)
1228
1215
 
 
1216
    def update_basis_by_delta(self, new_revid, delta):
 
1217
        """See MutableTree.update_basis_by_delta."""
 
1218
        assert self.last_revision() != new_revid
 
1219
        self.current_dirstate().update_basis_by_delta(delta, new_revid)
 
1220
 
1229
1221
    @needs_read_lock
1230
1222
    def _validate(self):
1231
1223
        self._dirstate._validate()
1233
1225
    @needs_tree_write_lock
1234
1226
    def _write_inventory(self, inv):
1235
1227
        """Write inventory as the current inventory."""
1236
 
        assert not self._dirty, "attempting to write an inventory when the dirstate is dirty will cause data loss"
 
1228
        assert not self._dirty, ("attempting to write an inventory when the "
 
1229
            "dirstate is dirty will cause data loss")
1237
1230
        self.current_dirstate().set_state_from_inventory(inv)
1238
1231
        self._make_dirty(reset_inventory=False)
1239
1232
        if self._inventory is not None:
1272
1265
        These trees get an initial random root id, if their repository supports
1273
1266
        rich root data, TREE_ROOT otherwise.
1274
1267
        """
1275
 
        revision_id = osutils.safe_revision_id(revision_id)
1276
1268
        if not isinstance(a_bzrdir.transport, LocalTransport):
1277
1269
            raise errors.NotLocalUrl(a_bzrdir.transport.base)
1278
1270
        transport = a_bzrdir.get_workingtree_transport(self)
1344
1336
 
1345
1337
    def __init__(self, dirstate, revision_id, repository):
1346
1338
        self._dirstate = dirstate
1347
 
        self._revision_id = osutils.safe_revision_id(revision_id)
 
1339
        self._revision_id = revision_id
1348
1340
        self._repository = repository
1349
1341
        self._inventory = None
1350
1342
        self._locked = 0
1402
1394
        """
1403
1395
        if file_id is None and path is None:
1404
1396
            raise errors.BzrError('must supply file_id or path')
1405
 
        file_id = osutils.safe_file_id(file_id)
1406
1397
        if path is not None:
1407
1398
            path = path.encode('utf8')
1408
1399
        parent_index = self._get_parent_index()
1574
1565
    def kind(self, file_id):
1575
1566
        return self.inventory[file_id].kind
1576
1567
 
 
1568
    def path_content_summary(self, path):
 
1569
        """See Tree.path_content_summary."""
 
1570
        id = self.inventory.path2id(path)
 
1571
        if id is None:
 
1572
            return ('missing', None, None, None)
 
1573
        entry = self._inventory[id]
 
1574
        kind = entry.kind
 
1575
        if kind == 'file':
 
1576
            return (kind, entry.text_size, entry.executable, entry.text_sha1)
 
1577
        elif kind == 'symlink':
 
1578
            return (kind, None, None, entry.symlink_target)
 
1579
        else:
 
1580
            return (kind, None, None, None)
 
1581
 
1577
1582
    def is_executable(self, file_id, path=None):
1578
1583
        ie = self.inventory[file_id]
1579
1584
        if ie.kind != "file":