/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
0.200.522 by Jelmer Vernooij
Simplify index handling a bit more.
268
                (ctime, mtime, dev, ino, 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.522 by Jelmer Vernooij
Simplify index handling a bit more.
277
                kind = mode_kind(mode)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
278
                if old_ie is not None and old_ie.hexsha == sha:
279
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
280
                    self.add_parents(path)
281
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
282
                else:
283
                    ie = self.add_path(path, kind, file_id, self.add_parents(path))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
284
                    data = store[sha].data
285
                    if kind == "symlink":
286
                        ie.symlink_target = data
287
                    else:
288
                        ie.text_sha1 = osutils.sha_string(data)
289
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
290
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
291
        finally:
292
            pb.finished()
293
294
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
295
        dirname, _ = osutils.split(path)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
296
        file_id = self.path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
297
        if file_id is None:
298
            if dirname == "":
299
                parent_fid = None
300
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
301
                parent_fid = self.add_parents(dirname)
302
            ie = self.add_path(dirname, 'directory', 
303
                    self.mapping.generate_file_id(dirname), parent_fid)
304
            if ie.file_id in self.basis_inv:
305
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
306
            file_id = ie.file_id
307
        return file_id
308