/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
53
        self.file_id = self._inventory.mapping.generate_file_id(path.encode('utf-8'))
54
55
    @property
56
    def object(self):
57
        if self._object is None:
58
            self._object = self._inventory.store[self.hexsha]
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
59
            assert isinstance(self._object, self._git_class), \
60
                    "Expected instance of %r, got %r" % \
61
                    (self._git_class, self._object)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
62
        return self._object
63
64
65
class GitInventoryFile(GitInventoryEntry):
66
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
67
    _git_class = Blob
68
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
69
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
70
        super(GitInventoryFile, self).__init__(inv, parent_id, hexsha, path,
71
            basename, executable)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
72
        self.kind = 'file'
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
73
        self.text_id = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
74
        self.symlink_target = None
75
76
    @property
77
    def text_sha1(self):
78
        return osutils.sha_string(self.object.data)
79
80
    @property
81
    def text_size(self):
82
        return len(self.object.data)
83
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
84
    def __repr__(self):
85
        return ("%s(%r, %r, parent_id=%r, sha1=%r, len=%s, revision=%s)"
86
                % (self.__class__.__name__,
87
                   self.file_id,
88
                   self.name,
89
                   self.parent_id,
90
                   self.text_sha1,
91
                   self.text_size,
92
                   self.revision))
93
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
94
    def kind_character(self):
95
        """See InventoryEntry.kind_character."""
96
        return ''
97
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
98
    def copy(self):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
99
        other = inventory.InventoryFile(self.file_id, self.name,
100
            self.parent_id)
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
101
        other.executable = self.executable
102
        other.text_id = self.text_id
103
        other.text_sha1 = self.text_sha1
104
        other.text_size = self.text_size
105
        other.revision = self.revision
106
        return other
107
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
108
109
class GitInventoryLink(GitInventoryEntry):
110
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
111
    _git_class = Blob
112
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
113
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
114
        super(GitInventoryLink, self).__init__(inv, parent_id, hexsha, path, basename, executable)
115
        self.text_sha1 = None
116
        self.text_size = None
117
        self.kind = 'symlink'
118
119
    @property
120
    def symlink_target(self):
121
        return self.object.data
122
123
    def kind_character(self):
124
        """See InventoryEntry.kind_character."""
125
        return ''
126
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
127
    def copy(self):
128
        other = inventory.InventoryLink(self.file_id, self.name, self.parent_id)
0.245.1 by INADA Naoki
Handle executable mode for symlink.
129
        other.executable = self.executable
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
130
        other.symlink_target = self.symlink_target
131
        other.revision = self.revision
132
        return other
133
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
134
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
135
class GitInventoryTreeReference(GitInventoryEntry):
136
137
    _git_class = None
138
139
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
140
        super(GitInventoryTreeReference, self).__init__(inv, parent_id, hexsha, path, basename, executable)
0.200.664 by Jelmer Vernooij
Support submodules during fetch.
141
        self.hexsha = hexsha
142
        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.
143
        self.text_sha1 = None
144
        self.text_size = None
145
        self.symlink_target = None
146
        self.kind = 'tree-reference'
147
        self._children = None
148
149
    def kind_character(self):
150
        """See InventoryEntry.kind_character."""
151
        return '/'
152
153
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
154
class GitInventoryDirectory(GitInventoryEntry):
155
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
156
    _git_class = Tree
157
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
158
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
159
        super(GitInventoryDirectory, self).__init__(inv, parent_id, hexsha, path, basename, executable)
160
        self.text_sha1 = None
161
        self.text_size = None
162
        self.symlink_target = None
163
        self.kind = 'directory'
0.200.403 by Jelmer Vernooij
Retrieve children faster.
164
        self._children = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
165
166
    def kind_character(self):
167
        """See InventoryEntry.kind_character."""
168
        return '/'
169
170
    @property
171
    def children(self):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
172
        if self._children is None:
173
            self._retrieve_children()
174
        return self._children
175
176
    def _retrieve_children(self):
177
        self._children = {}
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
178
        for mode, name, hexsha in self.object.entries():
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
179
            basename = name.decode("utf-8")
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
180
            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.
181
            executable = mode_is_executable(mode)
182
            kind_class = {'directory': GitInventoryDirectory,
183
                          'file': GitInventoryFile,
184
                          'symlink': GitInventoryLink,
185
                          'tree-reference': GitInventoryTreeReference}[mode_kind(mode)]
0.200.403 by Jelmer Vernooij
Retrieve children faster.
186
            self._children[basename] = kind_class(self._inventory, self.file_id, hexsha, child_path, basename, executable)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
187
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
188
    def copy(self):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
189
        other = inventory.InventoryDirectory(self.file_id, self.name,
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
190
                                             self.parent_id)
191
        other.revision = self.revision
192
        # note that children are *not* copied; they're pulled across when
193
        # others are added
194
        return other
195
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
196
197
class GitInventory(inventory.Inventory):
198
199
    def __init__(self, tree_id, mapping, store, revision_id):
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
200
        super(GitInventory, self).__init__(revision_id=revision_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
201
        self.store = store
202
        self.mapping = mapping
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
203
        self.root = GitInventoryDirectory(self, None, tree_id, u"", u"", False)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
204
205
    def _get_ie(self, path):
0.200.515 by Jelmer Vernooij
Support Inventory.path2id('').
206
        if path == "":
207
            return self.root
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
208
        parts = path.split("/")
209
        ie = self.root
210
        for name in parts:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
211
            ie = ie.children[name]
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
212
        return ie
213
214
    def has_filename(self, path):
215
        try:
216
            self._get_ie(path)
217
            return True
218
        except KeyError:
219
            return False
220
221
    def has_id(self, file_id):
222
        try:
223
            self.id2path(file_id)
224
            return True
225
        except errors.NoSuchId:
226
            return False
227
228
    def id2path(self, file_id):
229
        path = self.mapping.parse_file_id(file_id)
230
        try:
231
            ie = self._get_ie(path)
232
            assert ie.path == path
233
        except KeyError:
234
            raise errors.NoSuchId(None, file_id)
235
236
    def path2id(self, path):
237
        try:
238
            return self._get_ie(path).file_id
239
        except KeyError:
240
            return None
241
242
    def __getitem__(self, file_id):
243
        if file_id == inventory.ROOT_ID:
244
            return self.root
245
        path = self.mapping.parse_file_id(file_id)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
246
        try:
247
            return self._get_ie(path)
248
        except KeyError:
249
            raise errors.NoSuchId(None, file_id)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
250
251
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
252
class GitIndexInventory(inventory.Inventory):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
253
    """Inventory that retrieves its contents from an index file."""
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
254
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
255
    def __init__(self, basis_inventory, mapping, index, store):
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
256
        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.
257
        self.basis_inv = basis_inventory
258
        self.mapping = mapping
259
        self.index = index
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
260
        self._contents_read = False
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
261
        self.root = self.add_path("", 'directory',
0.200.621 by Jelmer Vernooij
More complete inventory implementation.
262
            self.mapping.generate_file_id(""), None)
263
264
    def iter_entries_by_dir(self, specific_file_ids=None, yield_parents=False):
265
        self._read_contents()
266
        return super(GitIndexInventory, self).iter_entries_by_dir(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.
267
268
    def has_id(self, file_id):
269
        try:
270
            self.id2path(file_id)
271
            return True
272
        except errors.NoSuchId:
273
            return False
274
275
    def has_filename(self, path):
276
        if path in self.index:
277
            return True
278
        self._read_contents()
279
        return super(GitIndexInventory, self).has_filename(path)
280
281
    def id2path(self, file_id):
282
        path = self.mapping.parse_file_id(file_id)
283
        if path in self.index:
284
            return path
285
        self._read_contents()
286
        return super(GitIndexInventory, self).id2path(file_id)
287
288
    def path2id(self, path):
289
        if path in self.index:
290
            return self.mapping.generate_file_id(path)
291
        self._read_contents()
292
        return super(GitIndexInventory, self).path2id(path)
293
294
    def __getitem__(self, file_id):
295
        self._read_contents()
296
        return super(GitIndexInventory, self).__getitem__(file_id)
297
298
    def _read_contents(self):
299
        if self._contents_read:
300
            return
301
        self._contents_read = True
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
302
        pb = ui.ui_factory.nested_progress_bar()
303
        try:
304
            for i, (path, value) in enumerate(self.index.iteritems()):
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
305
                pb.update("creating working inventory from index",
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
306
                        i, len(self.index))
307
                assert isinstance(path, str)
308
                assert isinstance(value, tuple) and len(value) == 10
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
309
                (ctime, mtime, dev, ino, mode, uid, gid, size, sha, flags) = value
0.200.403 by Jelmer Vernooij
Retrieve children faster.
310
                try:
311
                    old_ie = self.basis_inv._get_ie(path)
312
                except KeyError:
313
                    old_ie = None
314
                if old_ie is None:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
315
                    file_id = self.mapping.generate_file_id(path)
316
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
317
                    file_id = old_ie.file_id
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
318
                kind = mode_kind(mode)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
319
                if old_ie is not None and old_ie.hexsha == sha:
320
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
321
                    self.add_parents(path)
322
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
323
                else:
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
324
                    ie = self.add_path(path, kind, file_id,
325
                        self.add_parents(path))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
326
                    data = store[sha].data
327
                    if kind == "symlink":
328
                        ie.symlink_target = data
329
                    else:
330
                        ie.text_sha1 = osutils.sha_string(data)
331
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
332
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
333
        finally:
334
            pb.finished()
335
336
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
337
        dirname, _ = osutils.split(path)
0.200.620 by Jelmer Vernooij
Don't convert index to inventory unless we have to.
338
        file_id = super(GitIndexInventory, self).path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
339
        if file_id is None:
340
            if dirname == "":
341
                parent_fid = None
342
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
343
                parent_fid = self.add_parents(dirname)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
344
            ie = self.add_path(dirname, 'directory',
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
345
                    self.mapping.generate_file_id(dirname), parent_fid)
346
            if ie.file_id in self.basis_inv:
347
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
348
            file_id = ie.file_id
349
        return file_id
350