~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

  • Committer: Vincent Ladeuil
  • Date: 2011-07-06 09:22:00 UTC
  • mfrom: (6008 +trunk)
  • mto: (6012.1.1 trunk)
  • mto: This revision was merged to the branch mainline in revision 6013.
  • Revision ID: v.ladeuil+lp@free.fr-20110706092200-7iai2mwzc0sqdsvf
MergingĀ inĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
lazy_import(globals(), """
32
32
import collections
33
33
import copy
34
 
import os
35
34
import re
36
35
import tarfile
37
36
 
43
42
    )
44
43
""")
45
44
 
46
 
from bzrlib.errors import (
47
 
    BzrCheckError,
48
 
    BzrError,
 
45
from bzrlib import (
 
46
    lazy_regex,
 
47
    trace,
49
48
    )
50
 
from bzrlib.trace import mutter
 
49
 
51
50
from bzrlib.static_tuple import StaticTuple
 
51
from bzrlib.symbol_versioning import (
 
52
    deprecated_in,
 
53
    deprecated_method,
 
54
    )
52
55
 
53
56
 
54
57
class InventoryEntry(object):
101
104
    InventoryDirectory('2325', 'wibble', parent_id='123', revision=None)
102
105
    >>> i.path2id('src/wibble')
103
106
    '2325'
104
 
    >>> '2325' in i
105
 
    True
106
107
    >>> i.add(InventoryFile('2326', 'wibble.c', '2325'))
107
108
    InventoryFile('2326', 'wibble.c', parent_id='2325', sha1=None, len=None, revision=None)
108
109
    >>> i['2326']
171
172
        candidates = {}
172
173
        # identify candidate head revision ids.
173
174
        for inv in previous_inventories:
174
 
            if self.file_id in inv:
 
175
            if inv.has_id(self.file_id):
175
176
                ie = inv[self.file_id]
176
177
                if ie.revision in candidates:
177
178
                    # same revision value in two different inventories:
224
225
 
225
226
    def kind_character(self):
226
227
        """Return a short kind indicator useful for appending to names."""
227
 
        raise BzrError('unknown kind %r' % self.kind)
 
228
        raise errors.BzrError('unknown kind %r' % self.kind)
228
229
 
229
230
    known_kinds = ('file', 'directory', 'symlink')
230
231
 
250
251
        """
251
252
        if self.parent_id is not None:
252
253
            if not inv.has_id(self.parent_id):
253
 
                raise BzrCheckError('missing parent {%s} in inventory for revision {%s}'
254
 
                        % (self.parent_id, rev_id))
 
254
                raise errors.BzrCheckError(
 
255
                    'missing parent {%s} in inventory for revision {%s}' % (
 
256
                        self.parent_id, rev_id))
255
257
        checker._add_entry_to_text_key_references(inv, self)
256
258
        self._check(checker, rev_id)
257
259
 
539
541
        # FIXME: which _modified field should we use ? RBC 20051003
540
542
        text_modified = (self.symlink_target != old_entry.symlink_target)
541
543
        if text_modified:
542
 
            mutter("    symlink target changed")
 
544
            trace.mutter("    symlink target changed")
543
545
        meta_modified = False
544
546
        return text_modified, meta_modified
545
547
 
629
631
    inserted, other than through the Inventory API.
630
632
    """
631
633
 
 
634
    @deprecated_method(deprecated_in((2, 4, 0)))
632
635
    def __contains__(self, file_id):
633
636
        """True if this entry contains a file with given id.
634
637
 
635
638
        >>> inv = Inventory()
636
639
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
637
640
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
638
 
        >>> '123' in inv
 
641
        >>> inv.has_id('123')
639
642
        True
640
 
        >>> '456' in inv
 
643
        >>> inv.has_id('456')
641
644
        False
642
645
 
643
646
        Note that this method along with __iter__ are not encouraged for use as
756
759
            if (not yield_parents and specific_file_ids is not None and
757
760
                len(specific_file_ids) == 1):
758
761
                file_id = list(specific_file_ids)[0]
759
 
                if file_id in self:
 
762
                if self.has_id(file_id):
760
763
                    yield self.id2path(file_id), self[file_id]
761
764
                return
762
765
            from_dir = self.root
772
775
            parents = set()
773
776
            byid = self
774
777
            def add_ancestors(file_id):
775
 
                if file_id not in byid:
 
778
                if not byid.has_id(file_id):
776
779
                    return
777
780
                parent_id = byid[file_id].parent_id
778
781
                if parent_id is None:
822
825
                    file_id, self[file_id]))
823
826
        return delta
824
827
 
825
 
    def _get_mutable_inventory(self):
826
 
        """Returns a mutable copy of the object.
827
 
 
828
 
        Some inventories are immutable, yet working trees, for example, needs
829
 
        to mutate exisiting inventories instead of creating a new one.
830
 
        """
831
 
        raise NotImplementedError(self._get_mutable_inventory)
832
 
 
833
828
    def make_entry(self, kind, name, parent_id, file_id=None):
834
829
        """Simple thunk to bzrlib.inventory.make_entry."""
835
830
        return make_entry(kind, name, parent_id, file_id)
970
965
 
971
966
    >>> inv.path2id('hello.c')
972
967
    '123-123'
973
 
    >>> '123-123' in inv
 
968
    >>> inv.has_id('123-123')
974
969
    True
975
970
 
976
971
    There are iterators over the contents:
1133
1128
            other.add(entry.copy())
1134
1129
        return other
1135
1130
 
1136
 
    def _get_mutable_inventory(self):
1137
 
        """See CommonInventory._get_mutable_inventory."""
1138
 
        return copy.deepcopy(self)
1139
 
 
1140
1131
    def __iter__(self):
1141
1132
        """Iterate over all file-ids."""
1142
1133
        return iter(self._byid)
1182
1173
    def _add_child(self, entry):
1183
1174
        """Add an entry to the inventory, without adding it to its parent"""
1184
1175
        if entry.file_id in self._byid:
1185
 
            raise BzrError("inventory already contains entry with id {%s}" %
1186
 
                           entry.file_id)
 
1176
            raise errors.BzrError(
 
1177
                "inventory already contains entry with id {%s}" %
 
1178
                entry.file_id)
1187
1179
        self._byid[entry.file_id] = entry
1188
1180
        for child in getattr(entry, 'children', {}).itervalues():
1189
1181
            self._add_child(child)
1242
1234
        >>> inv = Inventory()
1243
1235
        >>> inv.add(InventoryFile('123', 'foo.c', ROOT_ID))
1244
1236
        InventoryFile('123', 'foo.c', parent_id='TREE_ROOT', sha1=None, len=None, revision=None)
1245
 
        >>> '123' in inv
 
1237
        >>> inv.has_id('123')
1246
1238
        True
1247
1239
        >>> del inv['123']
1248
 
        >>> '123' in inv
 
1240
        >>> inv.has_id('123')
1249
1241
        False
1250
1242
        """
1251
1243
        ie = self[file_id]
1353
1345
        """
1354
1346
        new_name = ensure_normalized_name(new_name)
1355
1347
        if not is_valid_name(new_name):
1356
 
            raise BzrError("not an acceptable filename: %r" % new_name)
 
1348
            raise errors.BzrError("not an acceptable filename: %r" % new_name)
1357
1349
 
1358
1350
        new_parent = self._byid[new_parent_id]
1359
1351
        if new_name in new_parent.children:
1360
 
            raise BzrError("%r already exists in %r" % (new_name, self.id2path(new_parent_id)))
 
1352
            raise errors.BzrError("%r already exists in %r" %
 
1353
                (new_name, self.id2path(new_parent_id)))
1361
1354
 
1362
1355
        new_parent_idpath = self.get_idpath(new_parent_id)
1363
1356
        if file_id in new_parent_idpath:
1364
 
            raise BzrError("cannot move directory %r into a subdirectory of itself, %r"
 
1357
            raise errors.BzrError(
 
1358
                "cannot move directory %r into a subdirectory of itself, %r"
1365
1359
                    % (self.id2path(file_id), self.id2path(new_parent_id)))
1366
1360
 
1367
1361
        file_ie = self._byid[file_id]
1616
1610
        self._fileid_to_entry_cache[result.file_id] = result
1617
1611
        return result
1618
1612
 
1619
 
    def _get_mutable_inventory(self):
1620
 
        """See CommonInventory._get_mutable_inventory."""
1621
 
        entries = self.iter_entries()
1622
 
        inv = Inventory(None, self.revision_id)
1623
 
        for path, inv_entry in entries:
1624
 
            inv.add(inv_entry.copy())
1625
 
        return inv
1626
 
 
1627
1613
    def create_by_apply_delta(self, inventory_delta, new_revision_id,
1628
1614
        propagate_caches=False):
1629
1615
        """Create a new CHKInventory by applying inventory_delta to this one.
2299
2285
    return name
2300
2286
 
2301
2287
 
2302
 
_NAME_RE = None
 
2288
_NAME_RE = lazy_regex.lazy_compile(r'^[^/\\]+$')
2303
2289
 
2304
2290
def is_valid_name(name):
2305
 
    global _NAME_RE
2306
 
    if _NAME_RE is None:
2307
 
        _NAME_RE = re.compile(r'^[^/\\]+$')
2308
 
 
2309
2291
    return bool(_NAME_RE.match(name))
2310
2292
 
2311
2293
 
2401
2383
            raise errors.InconsistentDelta(new_path, item[1],
2402
2384
                "new_path with no entry")
2403
2385
        yield item
 
2386
 
 
2387
 
 
2388
def mutable_inventory_from_tree(tree):
 
2389
    """Create a new inventory that has the same contents as a specified tree.
 
2390
 
 
2391
    :param tree: Revision tree to create inventory from
 
2392
    """
 
2393
    entries = tree.iter_entries_by_dir()
 
2394
    inv = Inventory(None, tree.get_revision_id())
 
2395
    for path, inv_entry in entries:
 
2396
        inv.add(inv_entry.copy())
 
2397
    return inv