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