/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.200.710 by Jelmer Vernooij
Check types of file ids.
53
        self.file_id = self._inventory.mapping.generate_file_id(
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):
79
        return osutils.sha_string(self.object.data)
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.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
182
            executable = mode_is_executable(mode)
183
            kind_class = {'directory': GitInventoryDirectory,
184
                          'file': GitInventoryFile,
185
                          'symlink': GitInventoryLink,
186
                          'tree-reference': GitInventoryTreeReference}[mode_kind(mode)]
0.200.710 by Jelmer Vernooij
Check types of file ids.
187
            self._children[basename] = kind_class(self._inventory,
188
                self.file_id, hexsha, child_path, basename, executable)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
189
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
190
    def copy(self):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
191
        other = inventory.InventoryDirectory(self.file_id, self.name,
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
192
                                             self.parent_id)
193
        other.revision = self.revision
194
        # note that children are *not* copied; they're pulled across when
195
        # others are added
196
        return other
197
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
198
199
class GitInventory(inventory.Inventory):
200
201
    def __init__(self, tree_id, mapping, store, revision_id):
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
202
        super(GitInventory, self).__init__(revision_id=revision_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
203
        self.store = store
204
        self.mapping = mapping
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
205
        self.root = GitInventoryDirectory(self, None, tree_id, u"", u"", False)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
206
207
    def _get_ie(self, path):
0.200.515 by Jelmer Vernooij
Support Inventory.path2id('').
208
        if path == "":
209
            return self.root
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
210
        parts = path.split("/")
211
        ie = self.root
212
        for name in parts:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
213
            ie = ie.children[name]
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
214
        return ie
215
216
    def has_filename(self, path):
217
        try:
218
            self._get_ie(path)
219
            return True
220
        except KeyError:
221
            return False
222
223
    def has_id(self, file_id):
224
        try:
225
            self.id2path(file_id)
226
            return True
227
        except errors.NoSuchId:
228
            return False
229
230
    def id2path(self, file_id):
231
        path = self.mapping.parse_file_id(file_id)
232
        try:
233
            ie = self._get_ie(path)
234
            assert ie.path == path
235
        except KeyError:
236
            raise errors.NoSuchId(None, file_id)
237
238
    def path2id(self, path):
239
        try:
240
            return self._get_ie(path).file_id
241
        except KeyError:
242
            return None
243
244
    def __getitem__(self, file_id):
245
        if file_id == inventory.ROOT_ID:
246
            return self.root
247
        path = self.mapping.parse_file_id(file_id)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
248
        try:
249
            return self._get_ie(path)
250
        except KeyError:
251
            raise errors.NoSuchId(None, file_id)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
252
253
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
254
class GitIndexInventory(inventory.Inventory):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
255
    """Inventory that retrieves its contents from an index file."""
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
256
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
257
    def __init__(self, basis_inventory, mapping, index, store):
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
258
        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.
259
        self.basis_inv = basis_inventory
260
        self.mapping = mapping
261
        self.index = index
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
262
        self._contents_read = False
0.200.710 by Jelmer Vernooij
Check types of file ids.
263
        self.store = store
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
264
        self.root = self.add_path("", 'directory',
0.200.621 by Jelmer Vernooij
More complete inventory implementation.
265
            self.mapping.generate_file_id(""), None)
266
267
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
268
        self._read_contents()
0.200.710 by Jelmer Vernooij
Check types of file ids.
269
        return super(GitIndexInventory, self).iter_entries_by_dir(
270
            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.
271
272
    def has_id(self, file_id):
0.200.710 by Jelmer Vernooij
Check types of file ids.
273
        if type(file_id) != str:
274
            raise AssertionError
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
275
        try:
276
            self.id2path(file_id)
277
            return True
278
        except errors.NoSuchId:
279
            return False
280
281
    def has_filename(self, path):
282
        if path in self.index:
283
            return True
284
        self._read_contents()
285
        return super(GitIndexInventory, self).has_filename(path)
286
287
    def id2path(self, file_id):
0.200.710 by Jelmer Vernooij
Check types of file ids.
288
        if type(file_id) != str:
289
            raise AssertionError
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
290
        path = self.mapping.parse_file_id(file_id)
291
        if path in self.index:
292
            return path
293
        self._read_contents()
294
        return super(GitIndexInventory, self).id2path(file_id)
295
296
    def path2id(self, path):
297
        if path in self.index:
298
            return self.mapping.generate_file_id(path)
299
        self._read_contents()
300
        return super(GitIndexInventory, self).path2id(path)
301
302
    def __getitem__(self, file_id):
303
        self._read_contents()
304
        return super(GitIndexInventory, self).__getitem__(file_id)
305
306
    def _read_contents(self):
307
        if self._contents_read:
308
            return
309
        self._contents_read = True
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
310
        pb = ui.ui_factory.nested_progress_bar()
311
        try:
312
            for i, (path, value) in enumerate(self.index.iteritems()):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
313
                pb.update("creating working inventory from index",
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
314
                        i, len(self.index))
315
                assert isinstance(path, str)
316
                assert isinstance(value, tuple) and len(value) == 10
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
317
                (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
0.200.403 by Jelmer Vernooij
Retrieve children faster.
318
                try:
319
                    old_ie = self.basis_inv._get_ie(path)
320
                except KeyError:
321
                    old_ie = None
322
                if old_ie is None:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
323
                    file_id = self.mapping.generate_file_id(path)
324
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
325
                    file_id = old_ie.file_id
0.200.710 by Jelmer Vernooij
Check types of file ids.
326
                if type(file_id) != str:
327
                    raise AssertionError
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
328
                kind = mode_kind(mode)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
329
                if old_ie is not None and old_ie.hexsha == sha:
330
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
331
                    self.add_parents(path)
332
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
333
                else:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
334
                    ie = self.add_path(path, kind, file_id,
335
                        self.add_parents(path))
0.200.710 by Jelmer Vernooij
Check types of file ids.
336
                    data = self.store[sha].data
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
337
                    if kind == "symlink":
338
                        ie.symlink_target = data
339
                    else:
340
                        ie.text_sha1 = osutils.sha_string(data)
341
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
342
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
343
        finally:
344
            pb.finished()
345
346
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
347
        dirname, _ = osutils.split(path)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
348
        file_id = super(GitIndexInventory, self).path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
349
        if file_id is None:
350
            if dirname == "":
351
                parent_fid = None
352
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
353
                parent_fid = self.add_parents(dirname)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
354
            ie = self.add_path(dirname, 'directory',
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
355
                    self.mapping.generate_file_id(dirname), parent_fid)
356
            if ie.file_id in self.basis_inv:
357
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
358
            file_id = ie.file_id
0.200.710 by Jelmer Vernooij
Check types of file ids.
359
        if type(file_id) != str:
360
            raise AssertionError
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
361
        return file_id
362