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