/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
"""Git inventory."""
19
20
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
21
from dulwich.objects import (
22
    Blob,
23
    Tree,
24
    )
25
26
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
27
from bzrlib import (
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
28
    errors,
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
29
    inventory,
30
    osutils,
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
31
    ui,
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
32
    )
33
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
34
from bzrlib.plugins.git.mapping import (
35
    mode_kind,
36
    mode_is_executable,
37
    )
38
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
39
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
40
class GitInventoryEntry(inventory.InventoryEntry):
41
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
42
    _git_class = None
43
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
44
    def __init__(self, inv, parent_id, hexsha, path, name, executable):
45
        self.name = name
46
        self.parent_id = parent_id
47
        self._inventory = inv
48
        self._object = None
49
        self.hexsha = hexsha
50
        self.path = path
51
        self.revision = self._inventory.revision_id
52
        self.executable = executable
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
53
        self.file_id = self._inventory.fileid_map.lookup_file_id(
0.200.710 by Jelmer Vernooij
Check types of file ids.
54
            path.encode('utf-8'))
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
55
56
    @property
57
    def object(self):
58
        if self._object is None:
59
            self._object = self._inventory.store[self.hexsha]
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
60
            assert isinstance(self._object, self._git_class), \
61
                    "Expected instance of %r, got %r" % \
62
                    (self._git_class, self._object)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
63
        return self._object
64
65
66
class GitInventoryFile(GitInventoryEntry):
67
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
68
    _git_class = Blob
69
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
70
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
71
        super(GitInventoryFile, self).__init__(inv, parent_id, hexsha, path,
72
            basename, executable)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
73
        self.kind = 'file'
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
74
        self.text_id = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
75
        self.symlink_target = None
76
77
    @property
78
    def text_sha1(self):
0.200.851 by Jelmer Vernooij
Use blob.chunked.
79
        return osutils.sha_strings(self.object.chunked)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
80
81
    @property
82
    def text_size(self):
83
        return len(self.object.data)
84
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
85
    def __repr__(self):
86
        return ("%s(%r, %r, parent_id=%r, sha1=%r, len=%s, revision=%s)"
87
                % (self.__class__.__name__,
88
                   self.file_id,
89
                   self.name,
90
                   self.parent_id,
91
                   self.text_sha1,
92
                   self.text_size,
93
                   self.revision))
94
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
95
    def kind_character(self):
96
        """See InventoryEntry.kind_character."""
97
        return ''
98
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
99
    def copy(self):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
100
        other = inventory.InventoryFile(self.file_id, self.name,
101
            self.parent_id)
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
102
        other.executable = self.executable
103
        other.text_id = self.text_id
104
        other.text_sha1 = self.text_sha1
105
        other.text_size = self.text_size
106
        other.revision = self.revision
107
        return other
108
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
109
110
class GitInventoryLink(GitInventoryEntry):
111
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
112
    _git_class = Blob
113
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
114
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
115
        super(GitInventoryLink, self).__init__(inv, parent_id, hexsha, path, basename, executable)
116
        self.text_sha1 = None
117
        self.text_size = None
118
        self.kind = 'symlink'
119
120
    @property
121
    def symlink_target(self):
122
        return self.object.data
123
124
    def kind_character(self):
125
        """See InventoryEntry.kind_character."""
126
        return ''
127
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
128
    def copy(self):
129
        other = inventory.InventoryLink(self.file_id, self.name, self.parent_id)
0.245.1 by INADA Naoki
Handle executable mode for symlink.
130
        other.executable = self.executable
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
131
        other.symlink_target = self.symlink_target
132
        other.revision = self.revision
133
        return other
134
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
135
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
136
class GitInventoryTreeReference(GitInventoryEntry):
137
138
    _git_class = None
139
140
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
141
        super(GitInventoryTreeReference, self).__init__(inv, parent_id, hexsha, path, basename, executable)
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
142
        self.hexsha = hexsha
143
        self.reference_revision = inv.mapping.revision_id_foreign_to_bzr(hexsha)
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
144
        self.text_sha1 = None
145
        self.text_size = None
146
        self.symlink_target = None
147
        self.kind = 'tree-reference'
148
        self._children = None
149
150
    def kind_character(self):
151
        """See InventoryEntry.kind_character."""
152
        return '/'
153
154
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
155
class GitInventoryDirectory(GitInventoryEntry):
156
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
157
    _git_class = Tree
158
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
159
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
160
        super(GitInventoryDirectory, self).__init__(inv, parent_id, hexsha, path, basename, executable)
161
        self.text_sha1 = None
162
        self.text_size = None
163
        self.symlink_target = None
164
        self.kind = 'directory'
0.200.403 by Jelmer Vernooij
Retrieve children faster.
165
        self._children = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
166
167
    def kind_character(self):
168
        """See InventoryEntry.kind_character."""
169
        return '/'
170
171
    @property
172
    def children(self):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
173
        if self._children is None:
174
            self._retrieve_children()
175
        return self._children
176
177
    def _retrieve_children(self):
178
        self._children = {}
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
179
        for mode, name, hexsha in self.object.entries():
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
180
            basename = name.decode("utf-8")
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
181
            child_path = osutils.pathjoin(self.path, basename)
0.252.35 by Jelmer Vernooij
Ignore control files in inventories.
182
            if self._inventory.mapping.is_control_file(child_path):
183
                continue
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
184
            executable = mode_is_executable(mode)
185
            kind_class = {'directory': GitInventoryDirectory,
186
                          'file': GitInventoryFile,
187
                          'symlink': GitInventoryLink,
188
                          'tree-reference': GitInventoryTreeReference}[mode_kind(mode)]
0.200.710 by Jelmer Vernooij
Check types of file ids.
189
            self._children[basename] = kind_class(self._inventory,
190
                self.file_id, hexsha, child_path, basename, executable)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
191
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
192
    def copy(self):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
193
        other = inventory.InventoryDirectory(self.file_id, self.name,
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
194
                                             self.parent_id)
195
        other.revision = self.revision
196
        # note that children are *not* copied; they're pulled across when
197
        # others are added
198
        return other
199
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
200
201
class GitInventory(inventory.Inventory):
202
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
203
    def __init__(self, tree_id, mapping, fileid_map, store, revision_id):
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
204
        super(GitInventory, self).__init__(revision_id=revision_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
205
        self.store = store
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
206
        self.fileid_map = fileid_map
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
207
        self.mapping = mapping
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
208
        self.root = GitInventoryDirectory(self, None, tree_id, u"", u"", False)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
209
210
    def _get_ie(self, path):
0.200.515 by Jelmer Vernooij
Support Inventory.path2id('').
211
        if path == "":
212
            return self.root
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
213
        parts = path.split("/")
214
        ie = self.root
215
        for name in parts:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
216
            ie = ie.children[name]
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
217
        return ie
218
219
    def has_filename(self, path):
220
        try:
221
            self._get_ie(path)
222
            return True
223
        except KeyError:
224
            return False
225
226
    def has_id(self, file_id):
227
        try:
228
            self.id2path(file_id)
229
            return True
230
        except errors.NoSuchId:
231
            return False
232
233
    def id2path(self, file_id):
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
234
        path = self.fileid_map.lookup_path(file_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
235
        try:
236
            ie = self._get_ie(path)
237
            assert ie.path == path
238
        except KeyError:
239
            raise errors.NoSuchId(None, file_id)
240
241
    def path2id(self, path):
242
        try:
243
            return self._get_ie(path).file_id
244
        except KeyError:
245
            return None
246
247
    def __getitem__(self, file_id):
248
        if file_id == inventory.ROOT_ID:
249
            return self.root
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
250
        path = self.fileid_map.lookup_path(file_id)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
251
        try:
252
            return self._get_ie(path)
253
        except KeyError:
254
            raise errors.NoSuchId(None, file_id)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
255
256
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
257
class GitIndexInventory(inventory.Inventory):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
258
    """Inventory that retrieves its contents from an index file."""
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
259
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
260
    def __init__(self, basis_inventory, fileid_map, index, store):
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
261
        super(GitIndexInventory, self).__init__(revision_id=None, root_id=basis_inventory.root.file_id)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
262
        self.basis_inv = basis_inventory
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
263
        self.fileid_map = fileid_map
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
264
        self.index = index
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
265
        self._contents_read = False
0.200.710 by Jelmer Vernooij
Check types of file ids.
266
        self.store = store
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
267
        self.root = self.add_path("", 'directory',
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
268
            self.fileid_map.lookup_file_id(""), None)
0.200.621 by Jelmer Vernooij
More complete inventory implementation.
269
270
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
271
        self._read_contents()
0.200.710 by Jelmer Vernooij
Check types of file ids.
272
        return super(GitIndexInventory, self).iter_entries_by_dir(
273
            specific_file_ids=specific_file_ids, yield_parents=yield_parents)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
274
275
    def has_id(self, file_id):
0.200.710 by Jelmer Vernooij
Check types of file ids.
276
        if type(file_id) != str:
277
            raise AssertionError
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
278
        try:
279
            self.id2path(file_id)
280
            return True
281
        except errors.NoSuchId:
282
            return False
283
284
    def has_filename(self, path):
285
        if path in self.index:
286
            return True
287
        self._read_contents()
288
        return super(GitIndexInventory, self).has_filename(path)
289
290
    def id2path(self, file_id):
0.200.710 by Jelmer Vernooij
Check types of file ids.
291
        if type(file_id) != str:
292
            raise AssertionError
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
293
        path = self.fileid_map.lookup_path(file_id)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
294
        if path in self.index:
295
            return path
296
        self._read_contents()
297
        return super(GitIndexInventory, self).id2path(file_id)
298
299
    def path2id(self, path):
300
        if path in self.index:
0.200.974 by Jelmer Vernooij
Provide VersionedFiles.get_annotator.
301
            file_id = self.fileid_map.lookup_file_id(path)
302
        else:
303
            self._read_contents()
304
            file_id = super(GitIndexInventory, self).path2id(path)
305
        if type(file_id) is not str:
306
            raise AssertionError
307
        return file_id
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
308
309
    def __getitem__(self, file_id):
310
        self._read_contents()
311
        return super(GitIndexInventory, self).__getitem__(file_id)
312
313
    def _read_contents(self):
314
        if self._contents_read:
315
            return
316
        self._contents_read = True
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
317
        pb = ui.ui_factory.nested_progress_bar()
318
        try:
319
            for i, (path, value) in enumerate(self.index.iteritems()):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
320
                pb.update("creating working inventory from index",
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
321
                        i, len(self.index))
322
                assert isinstance(path, str)
323
                assert isinstance(value, tuple) and len(value) == 10
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
324
                (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
0.200.403 by Jelmer Vernooij
Retrieve children faster.
325
                try:
326
                    old_ie = self.basis_inv._get_ie(path)
327
                except KeyError:
328
                    old_ie = None
329
                if old_ie is None:
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
330
                    file_id = self.fileid_map.lookup_file_id(path)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
331
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
332
                    file_id = old_ie.file_id
0.200.710 by Jelmer Vernooij
Check types of file ids.
333
                if type(file_id) != str:
334
                    raise AssertionError
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
335
                kind = mode_kind(mode)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
336
                if old_ie is not None and old_ie.hexsha == sha:
337
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
338
                    self.add_parents(path)
339
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
340
                else:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
341
                    ie = self.add_path(path, kind, file_id,
342
                        self.add_parents(path))
0.200.710 by Jelmer Vernooij
Check types of file ids.
343
                    data = self.store[sha].data
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
344
                    if kind == "symlink":
345
                        ie.symlink_target = data
346
                    else:
347
                        ie.text_sha1 = osutils.sha_string(data)
348
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
349
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
350
        finally:
351
            pb.finished()
352
353
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
354
        dirname, _ = osutils.split(path)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
355
        file_id = super(GitIndexInventory, self).path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
356
        if file_id is None:
357
            if dirname == "":
358
                parent_fid = None
359
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
360
                parent_fid = self.add_parents(dirname)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
361
            ie = self.add_path(dirname, 'directory',
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
362
                    self.fileid_map.lookup_file_id(dirname), parent_fid)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
363
            if ie.file_id in self.basis_inv:
364
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
365
            file_id = ie.file_id
0.200.710 by Jelmer Vernooij
Check types of file ids.
366
        if type(file_id) != str:
367
            raise AssertionError
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
368
        return file_id
369