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