/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):
195
        parts = path.split("/")
196
        ie = self.root
197
        for name in parts:
198
            ie = ie.children[name] 
199
        return ie
200
201
    def has_filename(self, path):
202
        try:
203
            self._get_ie(path)
204
            return True
205
        except KeyError:
206
            return False
207
208
    def has_id(self, file_id):
209
        try:
210
            self.id2path(file_id)
211
            return True
212
        except errors.NoSuchId:
213
            return False
214
215
    def id2path(self, file_id):
216
        path = self.mapping.parse_file_id(file_id)
217
        try:
218
            ie = self._get_ie(path)
219
            assert ie.path == path
220
        except KeyError:
221
            raise errors.NoSuchId(None, file_id)
222
223
    def path2id(self, path):
224
        try:
225
            return self._get_ie(path).file_id
226
        except KeyError:
227
            return None
228
229
    def __getitem__(self, file_id):
230
        if file_id == inventory.ROOT_ID:
231
            return self.root
232
        path = self.mapping.parse_file_id(file_id)
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
233
        try:
234
            return self._get_ie(path)
235
        except KeyError:
236
            raise errors.NoSuchId(None, file_id)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
237
238
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
239
class GitIndexInventory(inventory.Inventory):
0.200.403 by Jelmer Vernooij
Retrieve children faster.
240
    """Inventory that retrieves its contents from an index file."""
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
241
242
    def __init__(self, basis_inventory, mapping, index):
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
243
        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.
244
        self.basis_inv = basis_inventory
245
        self.mapping = mapping
246
        self.index = index
247
248
        pb = ui.ui_factory.nested_progress_bar()
249
        try:
250
            for i, (path, value) in enumerate(self.index.iteritems()):
251
                pb.update("creating working inventory from index", 
252
                        i, len(self.index))
253
                assert isinstance(path, str)
254
                assert isinstance(value, tuple) and len(value) == 10
255
                (ctime, mtime, ino, dev, mode, uid, gid, size, sha, flags) = value
0.200.403 by Jelmer Vernooij
Retrieve children faster.
256
                try:
257
                    old_ie = self.basis_inv._get_ie(path)
258
                except KeyError:
259
                    old_ie = None
260
                if old_ie is None:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
261
                    file_id = self.mapping.generate_file_id(path)
262
                else:
0.200.403 by Jelmer Vernooij
Retrieve children faster.
263
                    file_id = old_ie.file_id
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
264
                if stat.S_ISLNK(mode):
265
                    kind = 'symlink'
266
                else:
267
                    assert stat.S_ISREG(mode)
268
                    kind = 'file'
0.200.403 by Jelmer Vernooij
Retrieve children faster.
269
                if old_ie is not None and old_ie.hexsha == sha:
270
                    # Hasn't changed since basis inv
0.200.404 by Jelmer Vernooij
Actually put contents in the working tree inventory.
271
                    self.add_parents(path)
272
                    self.add(old_ie)
0.200.403 by Jelmer Vernooij
Retrieve children faster.
273
                else:
274
                    ie = self.add_path(path, kind, file_id, self.add_parents(path))
275
                    ie.revision = None
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
276
        finally:
277
            pb.finished()
278
279
    def add_parents(self, path):
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
280
        dirname, _ = osutils.split(path)
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
281
        file_id = self.path2id(dirname)
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
282
        if file_id is None:
283
            if dirname == "":
284
                parent_fid = None
285
            else:
0.200.402 by Jelmer Vernooij
Turn GitIndexInventory into an object, use progress bars.
286
                parent_fid = self.add_parents(dirname)
287
            ie = self.add_path(dirname, 'directory', 
288
                    self.mapping.generate_file_id(dirname), parent_fid)
289
            if ie.file_id in self.basis_inv:
290
                ie.revision = self.basis_inv[ie.file_id].revision
0.200.401 by Jelmer Vernooij
Move working tree inventory code to inventory.
291
            file_id = ie.file_id
292
        return file_id
293