/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.200.982 by Jelmer Vernooij
Add __repr__ implementations for GitInventory and GitIndexInventory.
203
    def __repr__(self):
204
        return "<%s for %r in %r>" % (self.__class__.__name__,
205
                self.root.hexsha, self.store)
206
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
207
    def __init__(self, tree_id, mapping, fileid_map, store, revision_id):
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
208
        super(GitInventory, self).__init__(revision_id=revision_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
209
        self.store = store
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
210
        self.fileid_map = fileid_map
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
211
        self.mapping = mapping
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
212
        self.root = GitInventoryDirectory(self, None, tree_id, u"", u"", False)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
213
214
    def _get_ie(self, path):
0.200.982 by Jelmer Vernooij
Add __repr__ implementations for GitInventory and GitIndexInventory.
215
        if path == "" or path == []:
0.200.515 by Jelmer Vernooij
Support Inventory.path2id('').
216
            return self.root
0.200.982 by Jelmer Vernooij
Add __repr__ implementations for GitInventory and GitIndexInventory.
217
        if isinstance(path, basestring):
218
            parts = path.split("/")
219
        else:
220
            parts = path
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
221
        ie = self.root
222
        for name in parts:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
223
            ie = ie.children[name]
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
224
        return ie
225
226
    def has_filename(self, path):
227
        try:
228
            self._get_ie(path)
229
            return True
230
        except KeyError:
231
            return False
232
233
    def has_id(self, file_id):
234
        try:
235
            self.id2path(file_id)
236
            return True
237
        except errors.NoSuchId:
238
            return False
239
240
    def id2path(self, file_id):
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
241
        path = self.fileid_map.lookup_path(file_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
242
        try:
243
            ie = self._get_ie(path)
244
            assert ie.path == path
245
        except KeyError:
246
            raise errors.NoSuchId(None, file_id)
247
248
    def path2id(self, path):
249
        try:
250
            return self._get_ie(path).file_id
251
        except KeyError:
252
            return None
253
254
    def __getitem__(self, file_id):
255
        if file_id == inventory.ROOT_ID:
256
            return self.root
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
257
        path = self.fileid_map.lookup_path(file_id)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
258
        try:
259
            return self._get_ie(path)
260
        except KeyError:
261
            raise errors.NoSuchId(None, file_id)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
262
263
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
264
class GitIndexInventory(inventory.Inventory):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
265
    """Inventory that retrieves its contents from an index file."""
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
266
0.200.982 by Jelmer Vernooij
Add __repr__ implementations for GitInventory and GitIndexInventory.
267
    def __repr__(self):
268
        return "<%s for %r>" % (self.__class__.__name__, self.index)
269
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
270
    def __init__(self, basis_inventory, fileid_map, index, store):
0.200.983 by Jelmer Vernooij
Use support opening index of first revision.
271
        if basis_inventory is None:
272
            root_id = None
273
        else:
274
            root_id = basis_inventory.root.file_id
275
        super(GitIndexInventory, self).__init__(revision_id=None, root_id=root_id)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
276
        self.basis_inv = basis_inventory
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
277
        self.fileid_map = fileid_map
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
278
        self.index = index
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
279
        self._contents_read = False
0.200.710 by Jelmer Vernooij
Check types of file ids.
280
        self.store = store
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
281
        self.root = self.add_path("", 'directory',
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
282
            self.fileid_map.lookup_file_id(""), None)
0.200.621 by Jelmer Vernooij
More complete inventory implementation.
283
284
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
285
        self._read_contents()
0.200.710 by Jelmer Vernooij
Check types of file ids.
286
        return super(GitIndexInventory, self).iter_entries_by_dir(
287
            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.
288
289
    def has_id(self, file_id):
0.200.710 by Jelmer Vernooij
Check types of file ids.
290
        if type(file_id) != str:
291
            raise AssertionError
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
292
        try:
293
            self.id2path(file_id)
294
            return True
295
        except errors.NoSuchId:
296
            return False
297
298
    def has_filename(self, path):
299
        if path in self.index:
300
            return True
301
        self._read_contents()
302
        return super(GitIndexInventory, self).has_filename(path)
303
304
    def id2path(self, file_id):
0.200.710 by Jelmer Vernooij
Check types of file ids.
305
        if type(file_id) != str:
306
            raise AssertionError
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
307
        path = self.fileid_map.lookup_path(file_id)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
308
        if path in self.index:
309
            return path
310
        self._read_contents()
311
        return super(GitIndexInventory, self).id2path(file_id)
312
313
    def path2id(self, path):
0.200.982 by Jelmer Vernooij
Add __repr__ implementations for GitInventory and GitIndexInventory.
314
        if type(path) in (list, tuple):
315
            path = "/".join(path)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
316
        if path in self.index:
0.200.974 by Jelmer Vernooij
Provide VersionedFiles.get_annotator.
317
            file_id = self.fileid_map.lookup_file_id(path)
318
        else:
319
            self._read_contents()
320
            file_id = super(GitIndexInventory, self).path2id(path)
0.200.990 by Jelmer Vernooij
Support 'add' in empty directory.
321
        if file_id is not None and type(file_id) is not str:
0.200.974 by Jelmer Vernooij
Provide VersionedFiles.get_annotator.
322
            raise AssertionError
323
        return file_id
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
324
325
    def __getitem__(self, file_id):
326
        self._read_contents()
327
        return super(GitIndexInventory, self).__getitem__(file_id)
328
329
    def _read_contents(self):
330
        if self._contents_read:
331
            return
332
        self._contents_read = True
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
333
        pb = ui.ui_factory.nested_progress_bar()
334
        try:
335
            for i, (path, value) in enumerate(self.index.iteritems()):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
336
                pb.update("creating working inventory from index",
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
337
                        i, len(self.index))
338
                assert isinstance(path, str)
339
                assert isinstance(value, tuple) and len(value) == 10
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
340
                (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
0.200.983 by Jelmer Vernooij
Use support opening index of first revision.
341
                if self.basis_inv is not None:
342
                    try:
343
                        old_ie = self.basis_inv._get_ie(path)
344
                    except KeyError:
345
                        old_ie = None
346
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
347
                    old_ie = None
348
                if old_ie is None:
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
349
                    file_id = self.fileid_map.lookup_file_id(path)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
350
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
351
                    file_id = old_ie.file_id
0.200.710 by Jelmer Vernooij
Check types of file ids.
352
                if type(file_id) != str:
353
                    raise AssertionError
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
354
                kind = mode_kind(mode)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
355
                if old_ie is not None and old_ie.hexsha == sha:
356
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
357
                    self.add_parents(path)
358
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
359
                else:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
360
                    ie = self.add_path(path, kind, file_id,
361
                        self.add_parents(path))
0.200.710 by Jelmer Vernooij
Check types of file ids.
362
                    data = self.store[sha].data
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
363
                    if kind == "symlink":
364
                        ie.symlink_target = data
365
                    else:
366
                        ie.text_sha1 = osutils.sha_string(data)
367
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
368
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
369
        finally:
370
            pb.finished()
371
372
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
373
        dirname, _ = osutils.split(path)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
374
        file_id = super(GitIndexInventory, self).path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
375
        if file_id is None:
376
            if dirname == "":
377
                parent_fid = None
378
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
379
                parent_fid = self.add_parents(dirname)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
380
            ie = self.add_path(dirname, 'directory',
0.252.33 by Jelmer Vernooij
Fix file id map lookups.
381
                    self.fileid_map.lookup_file_id(dirname), parent_fid)
0.200.983 by Jelmer Vernooij
Use support opening index of first revision.
382
            if self.basis_inv is not None and ie.file_id in self.basis_inv:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
383
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
384
            file_id = ie.file_id
0.200.710 by Jelmer Vernooij
Check types of file ids.
385
        if type(file_id) != str:
386
            raise AssertionError
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
387
        return file_id
388