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