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