/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 (
25
    Blob,
26
    Tree,
27
    )
28
29
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
30
from bzrlib import (
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
31
    errors,
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
32
    inventory,
33
    osutils,
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
34
    ui,
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
35
    urlutils,
36
    )
37
38
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
39
class GitInventoryEntry(inventory.InventoryEntry):
40
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
41
    _git_class = None
42
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
43
    def __init__(self, inv, parent_id, hexsha, path, name, executable):
44
        self.name = name
45
        self.parent_id = parent_id
46
        self._inventory = inv
47
        self._object = None
48
        self.hexsha = hexsha
49
        self.path = path
50
        self.revision = self._inventory.revision_id
51
        self.executable = executable
52
        self.file_id = self._inventory.mapping.generate_file_id(path.encode('utf-8'))
53
54
    @property
55
    def object(self):
56
        if self._object is None:
57
            self._object = self._inventory.store[self.hexsha]
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
58
            assert isinstance(self._object, self._git_class), \
59
                    "Expected instance of %r, got %r" % \
60
                    (self._git_class, self._object)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
61
        return self._object
62
63
64
class GitInventoryFile(GitInventoryEntry):
65
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
66
    _git_class = Blob
67
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
68
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
69
        super(GitInventoryFile, self).__init__(inv, parent_id, hexsha, path, basename, executable)
70
        self.kind = 'file'
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
71
        self.text_id = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
72
        self.symlink_target = None
73
74
    @property
75
    def text_sha1(self):
76
        return osutils.sha_string(self.object.data)
77
78
    @property
79
    def text_size(self):
80
        return len(self.object.data)
81
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
82
    def __repr__(self):
83
        return ("%s(%r, %r, parent_id=%r, sha1=%r, len=%s, revision=%s)"
84
                % (self.__class__.__name__,
85
                   self.file_id,
86
                   self.name,
87
                   self.parent_id,
88
                   self.text_sha1,
89
                   self.text_size,
90
                   self.revision))
91
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
92
    def kind_character(self):
93
        """See InventoryEntry.kind_character."""
94
        return ''
95
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
96
    def copy(self):
97
        other = inventory.InventoryFile(self.file_id, self.name, self.parent_id)
98
        other.executable = self.executable
99
        other.text_id = self.text_id
100
        other.text_sha1 = self.text_sha1
101
        other.text_size = self.text_size
102
        other.revision = self.revision
103
        return other
104
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
105
106
class GitInventoryLink(GitInventoryEntry):
107
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
108
    _git_class = Blob
109
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
110
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
111
        super(GitInventoryLink, self).__init__(inv, parent_id, hexsha, path, basename, executable)
112
        self.text_sha1 = None
113
        self.text_size = None
114
        self.kind = 'symlink'
115
116
    @property
117
    def symlink_target(self):
118
        return self.object.data
119
120
    def kind_character(self):
121
        """See InventoryEntry.kind_character."""
122
        return ''
123
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
124
    def copy(self):
125
        other = inventory.InventoryLink(self.file_id, self.name, self.parent_id)
126
        other.symlink_target = self.symlink_target
127
        other.revision = self.revision
128
        return other
129
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
130
131
class GitInventoryDirectory(GitInventoryEntry):
132
0.200.455 by Jelmer Vernooij
Add extra paranoia check.
133
    _git_class = Tree
134
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
135
    def __init__(self, inv, parent_id, hexsha, path, basename, executable):
136
        super(GitInventoryDirectory, self).__init__(inv, parent_id, hexsha, path, basename, executable)
137
        self.text_sha1 = None
138
        self.text_size = None
139
        self.symlink_target = None
140
        self.kind = 'directory'
0.200.403 by Jelmer Vernooij
Retrieve children faster.
141
        self._children = None
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
142
143
    def kind_character(self):
144
        """See InventoryEntry.kind_character."""
145
        return '/'
146
147
    @property
148
    def children(self):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
149
        if self._children is None:
150
            self._retrieve_children()
151
        return self._children
152
153
    def _retrieve_children(self):
154
        self._children = {}
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
155
        for mode, name, hexsha in self.object.entries():
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
156
            basename = name.decode("utf-8")
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
157
            child_path = osutils.pathjoin(self.path, basename)
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
158
            entry_kind = (mode & 0700000) / 0100000
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
159
            fs_mode = mode & 0777
160
            executable = bool(fs_mode & 0111)
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
161
            if entry_kind == 0:
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
162
                kind_class = GitInventoryDirectory
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
163
            elif entry_kind == 1:
164
                file_kind = (mode & 070000) / 010000
165
                if file_kind == 0:
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
166
                    kind_class = GitInventoryFile
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
167
                elif file_kind == 2:
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
168
                    kind_class = GitInventoryLink
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
169
                else:
170
                    raise AssertionError(
171
                        "Unknown file kind, perms=%o." % (mode,))
0.200.335 by Jelmer Vernooij
Move inventory code to separate module.
172
            else:
173
                raise AssertionError(
0.200.336 by Jelmer Vernooij
Use custom GitInventory class.
174
                    "Unknown blob kind, perms=%r." % (mode,))
0.200.403 by Jelmer Vernooij
Retrieve children faster.
175
            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.
176
0.200.380 by Jelmer Vernooij
Support copy on inventory entries.
177
    def copy(self):
178
        other = inventory.InventoryDirectory(self.file_id, self.name, 
179
                                             self.parent_id)
180
        other.revision = self.revision
181
        # note that children are *not* copied; they're pulled across when
182
        # others are added
183
        return other
184
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
185
186
class GitInventory(inventory.Inventory):
187
188
    def __init__(self, tree_id, mapping, store, revision_id):
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
189
        super(GitInventory, self).__init__(revision_id=revision_id)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
190
        self.store = store
191
        self.mapping = mapping
0.200.397 by Jelmer Vernooij
Fix GitInventory.__repr__ to include more information.
192
        self.root = GitInventoryDirectory(self, None, tree_id, u"", u"", False)
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
193
194
    def _get_ie(self, path):
0.200.515 by Jelmer Vernooij
Support Inventory.path2id('').
195
        if path == "":
196
            return self.root
0.200.337 by Jelmer Vernooij
Use CommonInventory to lazily evaluate trees.
197
        parts = path.split("/")
198
        ie = self.root
199
        for name in parts:
200
            ie = ie.children[name] 
201
        return ie
202
203
    def has_filename(self, path):
204
        try:
205
            self._get_ie(path)
206
            return True
207
        except KeyError:
208
            return False
209
210
    def has_id(self, file_id):
211
        try:
212
            self.id2path(file_id)
213
            return True
214
        except errors.NoSuchId:
215
            return False
216
217
    def id2path(self, file_id):
218
        path = self.mapping.parse_file_id(file_id)
219
        try:
220
            ie = self._get_ie(path)
221
            assert ie.path == path
222
        except KeyError:
223
            raise errors.NoSuchId(None, file_id)
224
225
    def path2id(self, path):
226
        try:
227
            return self._get_ie(path).file_id
228
        except KeyError:
229
            return None
230
231
    def __getitem__(self, file_id):
232
        if file_id == inventory.ROOT_ID:
233
            return self.root
234
        path = self.mapping.parse_file_id(file_id)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
235
        try:
236
            return self._get_ie(path)
237
        except KeyError:
238
            raise errors.NoSuchId(None, file_id)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
239
240
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
241
class GitIndexInventory(inventory.Inventory):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
242
    """Inventory that retrieves its contents from an index file."""
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
243
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
244
    def __init__(self, basis_inventory, mapping, index, store):
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
245
        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.
246
        self.basis_inv = basis_inventory
247
        self.mapping = mapping
248
        self.index = index
249
250
        pb = ui.ui_factory.nested_progress_bar()
251
        try:
252
            for i, (path, value) in enumerate(self.index.iteritems()):
253
                pb.update("creating working inventory from index", 
254
                        i, len(self.index))
255
                assert isinstance(path, str)
256
                assert isinstance(value, tuple) and len(value) == 10
257
                (ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags) = value
0.200.403 by Jelmer Vernooij
Retrieve children faster.
258
                try:
259
                    old_ie = self.basis_inv._get_ie(path)
260
                except KeyError:
261
                    old_ie = None
262
                if old_ie is None:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
263
                    file_id = self.mapping.generate_file_id(path)
264
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
265
                    file_id = old_ie.file_id
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
266
                if stat.S_ISLNK(mode):
267
                    kind = 'symlink'
268
                else:
269
                    assert stat.S_ISREG(mode)
270
                    kind = 'file'
0.200.403 by Jelmer Vernooij
Retrieve children faster.
271
                if old_ie is not None and old_ie.hexsha == sha:
272
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
273
                    self.add_parents(path)
274
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
275
                else:
276
                    ie = self.add_path(path, kind, file_id, self.add_parents(path))
0.200.502 by Jelmer Vernooij
Fill in sha1s in inventory.
277
                    data = store[sha].data
278
                    if kind == "symlink":
279
                        ie.symlink_target = data
280
                    else:
281
                        ie.text_sha1 = osutils.sha_string(data)
282
                        ie.text_size = len(data)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
283
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
284
        finally:
285
            pb.finished()
286
287
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
288
        dirname, _ = osutils.split(path)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
289
        file_id = self.path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
290
        if file_id is None:
291
            if dirname == "":
292
                parent_fid = None
293
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
294
                parent_fid = self.add_parents(dirname)
295
            ie = self.add_path(dirname, 'directory', 
296
                    self.mapping.generate_file_id(dirname), parent_fid)
297
            if ie.file_id in self.basis_inv:
298
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
299
            file_id = ie.file_id
300
        return file_id
301