/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to object_store.py

Fix support for older versions of Dulwich.

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 
19
19
from dulwich.objects import (
20
20
    Blob,
21
 
    Tree,
 
21
    sha_to_hex,
22
22
    )
23
23
from dulwich.object_store import (
24
24
    BaseObjectStore,
25
 
    ObjectStoreIterator,
26
25
    )
27
 
import stat
28
26
 
29
27
from bzrlib import (
30
28
    debug,
36
34
    NULL_REVISION,
37
35
    )
38
36
 
39
 
from bzrlib.plugins.git.errors import (
40
 
    GhostRevision,
41
 
    )
42
 
 
43
37
from bzrlib.plugins.git.mapping import (
44
38
    default_mapping,
45
39
    directory_to_tree,
46
40
    extract_unusual_modes,
47
41
    mapping_registry,
48
 
    revision_to_commit,
49
42
    )
50
43
from bzrlib.plugins.git.shamap import (
51
44
    SqliteGitShaMap,
97
90
        self._update_sha_map()
98
91
        return iter(self._idmap.sha1s())
99
92
 
 
93
    def _revision_to_commit(self, rev, tree_sha):
 
94
        def parent_lookup(revid):
 
95
            try:
 
96
                return self._lookup_revision_sha1(revid)
 
97
            except errors.NoSuchRevision:
 
98
                trace.warning("Ignoring ghost parent %s", revid)
 
99
                return None
 
100
        return self.mapping.export_commit(rev, tree_sha, parent_lookup)
 
101
 
100
102
    def _update_sha_map_revision(self, revid):
101
103
        inv = self.repository.get_inventory(revid)
102
104
        rev = self.repository.get_revision(revid)
103
105
        unusual_modes = extract_unusual_modes(rev)
104
106
        tree_sha = self._get_ie_sha1(inv.root, inv, unusual_modes)
105
 
        commit_obj = revision_to_commit(rev, tree_sha,
106
 
                                        self._idmap.lookup_commit)
 
107
        commit_obj = self._revision_to_commit(rev, tree_sha)
107
108
        try:
108
109
            foreign_revid, mapping = mapping_registry.parse_revision_id(revid)
109
110
        except errors.InvalidRevisionId:
117
118
    def _check_expected_sha(self, expected_sha, object):
118
119
        if expected_sha is None:
119
120
            return
120
 
        if expected_sha != object.id:
121
 
            raise AssertionError("Invalid sha for %r: %s" % (object, expected_sha))
 
121
        if len(expected_sha) == 40:
 
122
            if expected_sha != object.sha().hexdigest():
 
123
                raise AssertionError("Invalid sha for %r: %s" % (object, expected_sha))
 
124
        elif len(expected_sha) == 20:
 
125
            if expected_sha != object.sha().digest():
 
126
                raise AssertionError("Invalid sha for %r: %s" % (object, sha_to_hex(expected_sha)))
 
127
        else:
 
128
            raise AssertionError("Unknown length %d for %r" % (len(expected_sha), expected_sha))
122
129
 
123
 
    def _get_ie_object(self, entry, inv, unusual_modes):  
 
130
    def _get_ie_object(self, entry, inv, unusual_modes):
124
131
        if entry.kind == "directory":
125
132
            return self._get_tree(entry.file_id, inv.revision_id, inv, unusual_modes)
126
 
        else:
 
133
        elif entry.kind in ("file", "symlink"):
127
134
            return self._get_blob(entry.file_id, entry.revision)
 
135
        else:
 
136
            raise AssertionError("unknown entry kind '%s'" % entry.kind)
128
137
 
129
138
    def _get_ie_object_or_sha1(self, entry, inv, unusual_modes):
130
139
        if entry.kind == "directory":
132
141
                return self._idmap.lookup_tree(entry.file_id, inv.revision_id), None
133
142
            except KeyError:
134
143
                ret = self._get_ie_object(entry, inv, unusual_modes)
135
 
                self._idmap.add_entry(ret.id, "tree", (entry.file_id, inv.revision_id))
136
 
                return ret.id, ret
137
 
        else:
 
144
                if ret is None:
 
145
                    hexsha = None
 
146
                else:
 
147
                    hexsha = ret.id
 
148
                self._idmap.add_entry(hexsha, "tree", (entry.file_id, inv.revision_id))
 
149
                return hexsha, ret
 
150
        elif entry.kind in ("file", "symlink"):
138
151
            try:
139
152
                return self._idmap.lookup_blob(entry.file_id, entry.revision), None
140
153
            except KeyError:
141
154
                ret = self._get_ie_object(entry, inv, unusual_modes)
142
155
                self._idmap.add_entry(ret.id, "blob", (entry.file_id, entry.revision))
143
156
                return ret.id, ret
 
157
        else:
 
158
            raise AssertionError("unknown entry kind '%s'" % entry.kind)
144
159
 
145
160
    def _get_ie_sha1(self, entry, inv, unusual_modes):
146
161
        return self._get_ie_object_or_sha1(entry, inv, unusual_modes)[0]
147
162
 
148
163
    def _get_blob(self, fileid, revision, expected_sha=None):
149
164
        """Return a Git Blob object from a fileid and revision stored in bzr.
150
 
        
 
165
 
151
166
        :param fileid: File id of the text
152
167
        :param revision: Revision of the text
153
168
        """
154
 
        text = self.repository.texts.get_record_stream([(fileid, revision)],
155
 
            "unordered", True).next().get_bytes_as("fulltext")
 
169
        chunks = self.repository.iter_files_bytes([(fileid, revision, None)]).next()[1]
156
170
        blob = Blob()
157
 
        blob._text = text
 
171
        blob._text = "".join(chunks)
158
172
        self._check_expected_sha(expected_sha, blob)
159
173
        return blob
160
174
 
164
178
        :param fileid: fileid in the tree.
165
179
        :param revision: Revision of the tree.
166
180
        """
167
 
        tree = directory_to_tree(inv[fileid], 
 
181
        tree = directory_to_tree(inv[fileid],
168
182
            lambda ie: self._get_ie_sha1(ie, inv, unusual_modes),
169
183
            unusual_modes)
170
184
        self._check_expected_sha(expected_sha, tree)
171
185
        return tree
172
186
 
173
187
    def _get_commit(self, rev, tree_sha, expected_sha=None):
174
 
        try:
175
 
            commit = revision_to_commit(rev, tree_sha, self._lookup_revision_sha1)
176
 
        except errors.NoSuchRevision, e:
177
 
            raise GhostRevision(e.branch, e.revision)
 
188
        commit = self._revision_to_commit(rev, tree_sha)
178
189
        self._check_expected_sha(expected_sha, commit)
179
190
        return commit
180
191
 
201
212
 
202
213
        :param sha: SHA1 of the git object
203
214
        """
204
 
        return self[sha].as_raw_string()
 
215
        obj = self[sha]
 
216
        return (obj.type, obj.as_raw_string())
205
217
 
206
218
    def __contains__(self, sha):
207
219
        # See if sha is in map
208
220
        try:
209
 
            self._lookup_git_sha(sha)
 
221
            (type, type_data) = self._lookup_git_sha(sha)
 
222
            if type == "commit":
 
223
                return self.repository.has_revision(type_data[0])
 
224
            elif type == "blob":
 
225
                return self.repository.texts.has_version(type_data)
 
226
            elif type == "tree":
 
227
                return self.repository.has_revision(type_data[1])
 
228
            else:
 
229
                raise AssertionError("Unknown object type '%s'" % type)
210
230
        except KeyError:
211
231
            return False
212
232
        else:
217
237
        try:
218
238
            return self._idmap.lookup_git_sha(sha)
219
239
        except KeyError:
220
 
            # if not, see if there are any unconverted revisions and add them 
 
240
            # if not, see if there are any unconverted revisions and add them
221
241
            # to the map, search for sha in map again
222
242
            self._update_sha_map()
223
243
            return self._idmap.lookup_git_sha(sha)
235
255
        elif type == "blob":
236
256
            return self._get_blob(type_data[0], type_data[1], expected_sha=sha)
237
257
        elif type == "tree":
238
 
            inv = self.repository.get_inventory(type_data[1])
239
 
            rev = self.repository.get_revision(type_data[1])
 
258
            try:
 
259
                inv = self.repository.get_inventory(type_data[1])
 
260
                rev = self.repository.get_revision(type_data[1])
 
261
            except errors.NoSuchRevision:
 
262
                trace.mutter('entry for %s %s in shamap: %r, but not found in repository', type, sha, type_data)
 
263
                raise KeyError(sha)
240
264
            unusual_modes = extract_unusual_modes(rev)
241
265
            try:
242
266
                return self._get_tree(type_data[0], type_data[1], inv, unusual_modes,