/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.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
21
import stat
22
23
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
24
from dulwich.objects import (
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
25
    S_ISGITLINK,
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
26
    Blob,
27
    Tree,
28
    )
29
30
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
31
from bzrlib import (
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
32
    errors,
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
33
    inventory,
34
    osutils,
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
35
    ui,
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
36
    urlutils,
37
    )
38
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
39
from bzrlib.plugins.git.mapping import (
40
    mode_kind,
41
    mode_is_executable,
42
    )
43
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
44
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
45
class GitInventoryEntry(inventory.InventoryEntry):
46
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
47
    _git_class = None
48
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
49
    def __init__(self, inv, parent_id, hexsha, path, name, executable):
50
        self.name = name
51
        self.parent_id = parent_id
52
        self._inventory = inv
53
        self._object = None
54
        self.hexsha = hexsha
55
        self.path = path
56
        self.revision = self._inventory.revision_id
57
        self.executable = executable
58
        self.file_id = self._inventory.mapping.generate_file_id(path.encode('utf-8'))
59
60
    @property
61
    def object(self):
62
        if self._object is None:
63
            self._object = self._inventory.store[self.hexsha]
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
64
            assert isinstance(self._object, self._git_class), \
65
                    "Expected instance of %r, got %r" % \
66
                    (self._git_class, self._object)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
67
        return self._object
68
69
70
class GitInventoryFile(GitInventoryEntry):
71
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
72
    _git_class = Blob
73
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
74
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
75
        super(GitInventoryFile, self).__init__(inv, parent_id, hexsha, path, basename, executable)
76
        self.kind = 'file'
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
77
        self.text_id = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
78
        self.symlink_target = None
79
80
    @property
81
    def text_sha1(self):
82
        return osutils.sha_string(self.object.data)
83
84
    @property
85
    def text_size(self):
86
        return len(self.object.data)
87
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
88
    def __repr__(self):
89
        return ("%s(%r, %r, parent_id=%r, sha1=%r, len=%s, revision=%s)"
90
                % (self.__class__.__name__,
91
                   self.file_id,
92
                   self.name,
93
                   self.parent_id,
94
                   self.text_sha1,
95
                   self.text_size,
96
                   self.revision))
97
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
98
    def kind_character(self):
99
        """See InventoryEntry.kind_character."""
100
        return ''
101
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
102
    def copy(self):
103
        other = inventory.InventoryFile(self.file_id, self.name, self.parent_id)
104
        other.executable = self.executable
105
        other.text_id = self.text_id
106
        other.text_sha1 = self.text_sha1
107
        other.text_size = self.text_size
108
        other.revision = self.revision
109
        return other
110
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
111
112
class GitInventoryLink(GitInventoryEntry):
113
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
114
    _git_class = Blob
115
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
116
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
117
        super(GitInventoryLink, self).__init__(inv, parent_id, hexsha, path, basename, executable)
118
        self.text_sha1 = None
119
        self.text_size = None
120
        self.kind = 'symlink'
121
122
    @property
123
    def symlink_target(self):
124
        return self.object.data
125
126
    def kind_character(self):
127
        """See InventoryEntry.kind_character."""
128
        return ''
129
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
130
    def copy(self):
131
        other = inventory.InventoryLink(self.file_id, self.name, self.parent_id)
132
        other.symlink_target = self.symlink_target
133
        other.revision = self.revision
134
        return other
135
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
136
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
137
class GitInventoryTreeReference(GitInventoryEntry):
138
139
    _git_class = None
140
141
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
142
        super(GitInventoryTreeReference, self).__init__(inv, parent_id, hexsha, path, basename, executable)
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):
189
        other = inventory.InventoryDirectory(self.file_id, self.name, 
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:
211
            ie = ie.children[name] 
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
260
261
        pb = ui.ui_factory.nested_progress_bar()
262
        try:
263
            for i, (path, value) in enumerate(self.index.iteritems()):
264
                pb.update("creating working inventory from index", 
265
                        i, len(self.index))
266
                assert isinstance(path, str)
267
                assert isinstance(value, tuple) and len(value) == 10
268
                (ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags) = value
0.200.403 by Jelmer Vernooij
Retrieve children faster.
269
                try:
270
                    old_ie = self.basis_inv._get_ie(path)
271
                except KeyError:
272
                    old_ie = None
273
                if old_ie is None:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
274
                    file_id = self.mapping.generate_file_id(path)
275
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
276
                    file_id = old_ie.file_id
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
277
                if stat.S_ISLNK(mode):
278
                    kind = 'symlink'
0.200.521 by Jelmer Vernooij
Abstract out kind mapping a bit, initial work on support tree-references.
279
                elif S_ISGITLINK(mode):
280
                    kind = 'tree-reference'
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
281
                else:
282
                    assert stat.S_ISREG(mode)
283
                    kind = 'file'
0.200.403 by Jelmer Vernooij
Retrieve children faster.
284
                if old_ie is not None and old_ie.hexsha == sha:
285
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
286
                    self.add_parents(path)
287
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
288
                else:
289
                    ie = self.add_path(path, kind, file_id, self.add_parents(path))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
290
                    data = store[sha].data
291
                    if kind == "symlink":
292
                        ie.symlink_target = data
293
                    else:
294
                        ie.text_sha1 = osutils.sha_string(data)
295
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
296
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
297
        finally:
298
            pb.finished()
299
300
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
301
        dirname, _ = osutils.split(path)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
302
        file_id = self.path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
303
        if file_id is None:
304
            if dirname == "":
305
                parent_fid = None
306
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
307
                parent_fid = self.add_parents(dirname)
308
            ie = self.add_path(dirname, 'directory', 
309
                    self.mapping.generate_file_id(dirname), parent_fid)
310
            if ie.file_id in self.basis_inv:
311
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
312
            file_id = ie.file_id
313
        return file_id
314