~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/inventory.py

  • Committer: Martin Pool
  • Date: 2005-09-05 09:11:03 UTC
  • Revision ID: mbp@sourcefrog.net-20050905091103-1e51e146be0f08b4
- add test for deserialization from a canned XML inventory

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
 
18
 
# TODO: Maybe also keep the full path of the entry, and the children?
19
 
# But those depend on its position within a particular inventory, and
20
 
# it would be nice not to need to hold the backpointer here.
21
 
 
22
 
# TODO: Perhaps split InventoryEntry into subclasses for files,
23
 
# directories, etc etc.
24
 
 
25
 
 
26
18
# This should really be an id randomly assigned when the tree is
27
19
# created, but it's not for now.
28
20
ROOT_ID = "TREE_ROOT"
44
36
    An InventoryEntry has the following fields, which are also
45
37
    present in the XML inventory-entry element:
46
38
 
47
 
    file_id
48
 
 
49
 
    name
50
 
        (within the parent directory)
51
 
 
52
 
    kind
53
 
        'directory' or 'file'
54
 
 
55
 
    parent_id
56
 
        file_id of the parent directory, or ROOT_ID
57
 
 
58
 
    entry_version
59
 
        the revision_id in which the name or parent of this file was
60
 
        last changed
61
 
 
62
 
    text_sha1
63
 
        sha-1 of the text of the file
64
 
        
65
 
    text_size
66
 
        size in bytes of the text of the file
67
 
        
68
 
    text_version
69
 
        the revision_id in which the text of this file was introduced
70
 
 
71
 
    (reading a version 4 tree created a text_id field.)
 
39
    * *file_id*
 
40
    * *name*: (only the basename within the directory, must not
 
41
      contain slashes)
 
42
    * *kind*: "directory" or "file"
 
43
    * *directory_id*: (if absent/null means the branch root directory)
 
44
    * *text_sha1*: only for files
 
45
    * *text_size*: in bytes, only for files 
 
46
    * *text_id*: identifier for the text version, only for files
 
47
 
 
48
    InventoryEntries can also exist inside a WorkingTree
 
49
    inventory, in which case they are not yet bound to a
 
50
    particular revision of the file.  In that case the text_sha1,
 
51
    text_size and text_id are absent.
 
52
 
72
53
 
73
54
    >>> i = Inventory()
74
55
    >>> i.path2id('')
109
90
    src/wibble/wibble.c
110
91
    >>> i.id2path('2326')
111
92
    'src/wibble/wibble.c'
 
93
 
 
94
    TODO: Maybe also keep the full path of the entry, and the children?
 
95
           But those depend on its position within a particular inventory, and
 
96
           it would be nice not to need to hold the backpointer here.
112
97
    """
113
 
    
 
98
 
 
99
    # TODO: split InventoryEntry into subclasses for files,
 
100
    # directories, etc etc.
 
101
 
114
102
    __slots__ = ['text_sha1', 'text_size', 'file_id', 'name', 'kind',
115
 
                 'text_id', 'parent_id', 'children',
116
 
                 'text_version', 'entry_version', ]
117
 
 
 
103
                 'text_id', 'parent_id', 'children', ]
118
104
 
119
105
    def __init__(self, file_id, name, kind, parent_id, text_id=None):
120
106
        """Create an InventoryEntry
131
117
        Traceback (most recent call last):
132
118
        BzrCheckError: InventoryEntry name 'src/hello.c' is invalid
133
119
        """
134
 
        assert isinstance(name, basestring), name
135
120
        if '/' in name or '\\' in name:
136
121
            raise BzrCheckError('InventoryEntry name %r is invalid' % name)
137
122
        
138
 
        self.text_version = None
139
 
        self.entry_version = None
140
123
        self.text_sha1 = None
141
124
        self.text_size = None
 
125
    
142
126
        self.file_id = file_id
143
127
        self.name = name
144
128
        self.kind = kind
161
145
 
162
146
    def copy(self):
163
147
        other = InventoryEntry(self.file_id, self.name, self.kind,
164
 
                               self.parent_id)
165
 
        other.text_id = self.text_id
 
148
                               self.parent_id, text_id=self.text_id)
166
149
        other.text_sha1 = self.text_sha1
167
150
        other.text_size = self.text_size
168
 
        other.text_version = self.text_version
169
 
        other.entry_version = self.entry_version
170
151
        # note that children are *not* copied; they're pulled across when
171
152
        # others are added
172
153
        return other
191
172
               and (self.text_size == other.text_size) \
192
173
               and (self.text_id == other.text_id) \
193
174
               and (self.parent_id == other.parent_id) \
194
 
               and (self.kind == other.kind) \
195
 
               and (self.text_version == other.text_version) \
196
 
               and (self.entry_version == other.entry_version)
 
175
               and (self.kind == other.kind)
197
176
 
198
177
 
199
178
    def __ne__(self, other):
277
256
        self._byid = {self.root.file_id: self.root}
278
257
 
279
258
 
280
 
    def copy(self):
281
 
        other = Inventory(self.root.file_id)
282
 
        # copy recursively so we know directories will be added before
283
 
        # their children.  There are more efficient ways than this...
284
 
        for path, entry in self.iter_entries():
285
 
            if entry == self.root:
286
 
                continue
287
 
            other.add(entry.copy())
288
 
        return other
289
 
 
290
 
 
291
259
    def __iter__(self):
292
260
        return iter(self._byid)
293
261
 
497
465
 
498
466
 
499
467
    def __ne__(self, other):
500
 
        return not self.__eq__(other)
 
468
        return not (self == other)
501
469
 
502
470
 
503
471
    def __hash__(self):