~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-09-17 21:19:56 UTC
  • mfrom: (1997.1.6 bind-does-not-push-or-pull)
  • Revision ID: pqm@pqm.ubuntu.com-20060917211956-6e30d07da410fd1a
(Robert Collins) Change the Branch bind method to just bind rather than binding and pushing (fixes #43744 and #39542)

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
import sys
35
35
import tarfile
36
36
import types
 
37
from warnings import warn
37
38
 
38
39
import bzrlib
 
40
from bzrlib import errors, osutils
39
41
from bzrlib.osutils import (pumpfile, quotefn, splitpath, joinpath,
40
42
                            pathjoin, sha_strings)
41
43
from bzrlib.errors import (NotVersionedError, InvalidEntryName,
80
82
    InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None)
81
83
    >>> i.add(InventoryFile('2323', 'hello.c', parent_id='123'))
82
84
    InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None)
83
 
    >>> shouldbe = {0: 'src', 1: pathjoin('src','hello.c')}
 
85
    >>> shouldbe = {0: '', 1: 'src', 2: pathjoin('src','hello.c')}
84
86
    >>> for ix, j in enumerate(i.iter_entries()):
85
87
    ...   print (j[0] == shouldbe[ix], j[1])
86
88
    ... 
 
89
    (True, InventoryDirectory('TREE_ROOT', '', parent_id=None, revision=None))
87
90
    (True, InventoryDirectory('123', 'src', parent_id='TREE_ROOT', revision=None))
88
91
    (True, InventoryFile('2323', 'hello.c', parent_id='123', sha1=None, len=None))
89
92
    >>> i.add(InventoryFile('2323', 'bye.c', '123'))
106
109
    ...     print path
107
110
    ...     assert i.path2id(path)
108
111
    ... 
 
112
    <BLANKLINE>
109
113
    src
110
114
    src/bye.c
111
115
    src/hello.c
292
296
        """Return a short kind indicator useful for appending to names."""
293
297
        raise BzrError('unknown kind %r' % self.kind)
294
298
 
295
 
    known_kinds = ('file', 'directory', 'symlink', 'root_directory')
 
299
    known_kinds = ('file', 'directory', 'symlink')
296
300
 
297
301
    def _put_in_tar(self, item, tree):
298
302
        """populate item for stashing in a tar, and return the content stream.
309
313
        """
310
314
        fullpath = pathjoin(dest, dp)
311
315
        self._put_on_disk(fullpath, tree)
312
 
        mutter("  export {%s} kind %s to %s", self.file_id,
313
 
                self.kind, fullpath)
 
316
        # mutter("  export {%s} kind %s to %s", self.file_id,
 
317
        #         self.kind, fullpath)
314
318
 
315
319
    def _put_on_disk(self, fullpath, tree):
316
320
        """Put this entry onto disk at fullpath, from tree tree."""
321
325
 
322
326
    @staticmethod
323
327
    def versionable_kind(kind):
324
 
        return kind in ('file', 'directory', 'symlink')
 
328
        return (kind in ('file', 'directory', 'symlink'))
325
329
 
326
330
    def check(self, checker, rev_id, inv, tree):
327
331
        """Check this inventory entry is intact.
407
411
        This means that all its fields are populated, that it has its
408
412
        text stored in the text store or weave.
409
413
        """
410
 
        mutter('new parents of %s are %r', path, previous_entries)
 
414
        # mutter('new parents of %s are %r', path, previous_entries)
411
415
        self._read_tree_state(path, work_tree)
412
416
        # TODO: Where should we determine whether to reuse a
413
417
        # previous revision id or create a new revision? 20060606
415
419
            # cannot be unchanged unless there is only one parent file rev.
416
420
            parent_ie = previous_entries.values()[0]
417
421
            if self._unchanged(parent_ie):
418
 
                mutter("found unchanged entry")
 
422
                # mutter("found unchanged entry")
419
423
                self.revision = parent_ie.revision
420
424
                return "unchanged"
421
425
        return self._snapshot_into_revision(revision, previous_entries, 
432
436
 
433
437
        :returns: String description of the commit (e.g. "merged", "modified"), etc.
434
438
        """
435
 
        mutter('new revision {%s} for {%s}', revision, self.file_id)
 
439
        # mutter('new revision {%s} for {%s}', revision, self.file_id)
436
440
        self.revision = revision
437
441
        self._snapshot_text(previous_entries, work_tree, commit_builder)
438
442
 
506
510
    def __init__(self, file_id):
507
511
        self.file_id = file_id
508
512
        self.children = {}
509
 
        self.kind = 'root_directory'
 
513
        self.kind = 'directory'
510
514
        self.parent_id = None
511
515
        self.name = u''
512
516
        self.revision = None
 
517
        warn('RootEntry is deprecated as of bzr 0.10.  Please use '
 
518
             'InventoryDirectory instead.',
 
519
            DeprecationWarning, stacklevel=2)
513
520
 
514
521
    def __eq__(self, other):
515
522
        if not isinstance(other, RootEntry):
692
699
 
693
700
    def _forget_tree_state(self):
694
701
        self.text_sha1 = None
695
 
        self.executable = None
696
702
 
697
703
    def _snapshot_text(self, file_parents, work_tree, commit_builder):
698
704
        """See InventoryEntry._snapshot_text."""
840
846
    May also look up by name:
841
847
 
842
848
    >>> [x[0] for x in inv.iter_entries()]
843
 
    [u'hello.c']
 
849
    ['', u'hello.c']
844
850
    >>> inv = Inventory('TREE_ROOT-12345678-12345678')
845
851
    >>> inv.add(InventoryFile('123-123', 'hello.c', ROOT_ID))
846
852
    InventoryFile('123-123', 'hello.c', parent_id='TREE_ROOT-12345678-12345678', sha1=None, len=None)
859
865
        # root id. Rather than generating a random one here.
860
866
        #if root_id is None:
861
867
        #    root_id = bzrlib.branch.gen_file_id('TREE_ROOT')
862
 
        self.root = RootEntry(root_id)
 
868
        if root_id is not None:
 
869
            self._set_root(InventoryDirectory(root_id, '', None))
 
870
        else:
 
871
            self.root = None
 
872
            self._byid = {}
863
873
        # FIXME: this isn't ever used, changing it to self.revision may break
864
874
        # things. TODO make everything use self.revision_id
865
875
        self.revision_id = revision_id
 
876
 
 
877
    def _set_root(self, ie):
 
878
        self.root = ie
866
879
        self._byid = {self.root.file_id: self.root}
867
880
 
868
881
    def copy(self):
869
882
        # TODO: jam 20051218 Should copy also copy the revision_id?
870
 
        other = Inventory(self.root.file_id)
 
883
        entries = self.iter_entries()
 
884
        other = Inventory(entries.next()[1].file_id)
871
885
        # copy recursively so we know directories will be added before
872
886
        # their children.  There are more efficient ways than this...
873
 
        for path, entry in self.iter_entries():
874
 
            if entry == self.root:
875
 
                continue
 
887
        for path, entry in entries():
876
888
            other.add(entry.copy())
877
889
        return other
878
890
 
888
900
        if from_dir is None:
889
901
            assert self.root
890
902
            from_dir = self.root
 
903
            yield '', self.root
891
904
        elif isinstance(from_dir, basestring):
892
905
            from_dir = self._byid[from_dir]
893
906
            
940
953
        if from_dir is None:
941
954
            assert self.root
942
955
            from_dir = self.root
 
956
            yield '', self.root
943
957
        elif isinstance(from_dir, basestring):
944
958
            from_dir = self._byid[from_dir]
945
959
            
1003
1017
        >>> '456' in inv
1004
1018
        False
1005
1019
        """
1006
 
        return file_id in self._byid
 
1020
        return (file_id in self._byid)
1007
1021
 
1008
1022
    def __getitem__(self, file_id):
1009
1023
        """Return the entry for given file_id.
1039
1053
        if entry.file_id in self._byid:
1040
1054
            raise BzrError("inventory already contains entry with id {%s}" % entry.file_id)
1041
1055
 
1042
 
        if entry.parent_id == ROOT_ID or entry.parent_id is None:
 
1056
        if entry.parent_id is None:
 
1057
            assert self.root is None and len(self._byid) == 0
 
1058
            self._set_root(entry)
 
1059
            return entry
 
1060
        if entry.parent_id == ROOT_ID:
 
1061
            assert self.root is not None, self
1043
1062
            entry.parent_id = self.root.file_id
1044
1063
 
1045
1064
        try:
1062
1081
 
1063
1082
        Returns the new entry object."""
1064
1083
        
1065
 
        parts = bzrlib.osutils.splitpath(relpath)
 
1084
        parts = osutils.splitpath(relpath)
1066
1085
 
1067
1086
        if len(parts) == 0:
1068
1087
            if file_id is None:
1069
1088
                file_id = bzrlib.workingtree.gen_root_id()
1070
 
            self.root = RootEntry(file_id)
 
1089
            self.root = InventoryDirectory(file_id, '', None)
1071
1090
            self._byid = {self.root.file_id: self.root}
1072
1091
            return
1073
1092
        else:
1196
1215
        return bool(self.path2id(names))
1197
1216
 
1198
1217
    def has_id(self, file_id):
1199
 
        return self._byid.has_key(file_id)
 
1218
        return (file_id in self._byid)
 
1219
 
 
1220
    def remove_recursive_id(self, file_id):
 
1221
        """Remove file_id, and children, from the inventory.
 
1222
        
 
1223
        :param file_id: A file_id to remove.
 
1224
        """
 
1225
        to_find_delete = [self._byid[file_id]]
 
1226
        to_delete = []
 
1227
        while to_find_delete:
 
1228
            ie = to_find_delete.pop()
 
1229
            to_delete.append(ie.file_id)
 
1230
            if ie.kind == 'directory':
 
1231
                to_find_delete.extend(ie.children.values())
 
1232
        for file_id in reversed(to_delete):
 
1233
            ie = self[file_id]
 
1234
            del self._byid[file_id]
 
1235
            if ie.parent_id is not None:
 
1236
                del self[ie.parent_id].children[ie.name]
1200
1237
 
1201
1238
    def rename(self, file_id, new_parent_id, new_name):
1202
1239
        """Move a file within the inventory.
1238
1275
    """
1239
1276
    if file_id is None:
1240
1277
        file_id = bzrlib.workingtree.gen_file_id(name)
 
1278
 
 
1279
    norm_name, can_access = osutils.normalized_filename(name)
 
1280
    if norm_name != name:
 
1281
        if can_access:
 
1282
            name = norm_name
 
1283
        else:
 
1284
            # TODO: jam 20060701 This would probably be more useful
 
1285
            #       if the error was raised with the full path
 
1286
            raise errors.InvalidNormalization(name)
 
1287
 
1241
1288
    if kind == 'directory':
1242
1289
        return InventoryDirectory(file_id, name, parent_id)
1243
1290
    elif kind == 'file':
1248
1295
        raise BzrError("unknown kind %r" % kind)
1249
1296
 
1250
1297
 
1251
 
 
1252
1298
_NAME_RE = None
1253
1299
 
1254
1300
def is_valid_name(name):