/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.358.2 by Jelmer Vernooij
Refresh copyright headers, add my email.
1
# Copyright (C) 2009-2018 Jelmer Vernooij <jelmer@jelmer.uk>
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
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
0.358.1 by Jelmer Vernooij
Fix FSF address.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
16
17
"""Map from Git sha's to Bazaar objects."""
18
0.200.1594 by Jelmer Vernooij
Use absolute_import everywhere.
19
from __future__ import absolute_import
20
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
21
from dulwich.objects import (
22
    sha_to_hex,
23
    hex_to_sha,
24
    )
0.200.292 by Jelmer Vernooij
Fix formatting.
25
import os
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
26
import threading
0.200.292 by Jelmer Vernooij
Fix formatting.
27
0.254.44 by Jelmer Vernooij
Add knit-based content cache for trees.
28
from dulwich.objects import (
29
    ShaFile,
30
    )
31
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
32
from .. import (
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
33
    errors as bzr_errors,
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
34
    osutils,
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
35
    registry,
0.200.528 by Jelmer Vernooij
Fix import.
36
    trace,
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
37
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
38
from ..bzr import (
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
39
    btree_index as _mod_btree_index,
40
    index as _mod_index,
0.254.31 by Jelmer Vernooij
Initial work on CHKMap support.
41
    versionedfile,
0.200.528 by Jelmer Vernooij
Fix import.
42
    )
6986.2.3 by Jelmer Vernooij
Merge trunk
43
from ..sixish import (
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
44
    viewitems,
45
    viewkeys,
46
    viewvalues,
47
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
48
from ..transport import (
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
49
    get_transport,
50
    )
0.200.230 by Jelmer Vernooij
Implement sha cache.
51
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
52
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
53
def get_cache_dir():
54
    try:
55
        from xdg.BaseDirectory import xdg_cache_home
56
    except ImportError:
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
57
        from ..config import config_dir
0.200.558 by Jelmer Vernooij
Create cache dir if it doesn't exist yet.
58
        ret = os.path.join(config_dir(), "git")
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
59
    else:
0.417.1 by Jelmer Vernooij
Change cache directory name from bazaar => breezy.
60
        ret = os.path.join(xdg_cache_home, "breezy", "git")
0.200.558 by Jelmer Vernooij
Create cache dir if it doesn't exist yet.
61
    if not os.path.isdir(ret):
62
        os.makedirs(ret)
63
    return ret
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
64
65
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
66
def get_remote_cache_transport(repository):
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
67
    """Retrieve the transport to use when accessing (unwritable) remote
0.200.1027 by Jelmer Vernooij
mark remote git directories as not supporting working trees.
68
    repositories.
69
    """
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
70
    uuid = getattr(repository, "uuid", None)
71
    if uuid is None:
72
        path = get_cache_dir()
73
    else:
74
        path = os.path.join(get_cache_dir(), uuid)
75
        if not os.path.isdir(path):
76
            os.mkdir(path)
77
    return get_transport(path)
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
78
79
0.200.228 by Jelmer Vernooij
Split out map.
80
def check_pysqlite_version(sqlite3):
81
    """Check that sqlite library is compatible.
82
83
    """
7143.15.2 by Jelmer Vernooij
Run autopep8.
84
    if (sqlite3.sqlite_version_info[0] < 3
85
            or (sqlite3.sqlite_version_info[0] == 3 and
86
                sqlite3.sqlite_version_info[1] < 3)):
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
87
        trace.warning('Needs at least sqlite 3.3.x')
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
88
        raise bzr_errors.BzrError("incompatible sqlite library")
0.200.228 by Jelmer Vernooij
Split out map.
89
7143.15.2 by Jelmer Vernooij
Run autopep8.
90
0.200.228 by Jelmer Vernooij
Split out map.
91
try:
92
    try:
93
        import sqlite3
94
        check_pysqlite_version(sqlite3)
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
95
    except (ImportError, bzr_errors.BzrError):
0.200.228 by Jelmer Vernooij
Split out map.
96
        from pysqlite2 import dbapi2 as sqlite3
97
        check_pysqlite_version(sqlite3)
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
98
except BaseException:
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
99
    trace.warning('Needs at least Python2.5 or Python2.4 with the pysqlite2 '
7143.15.2 by Jelmer Vernooij
Run autopep8.
100
                  'module')
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
101
    raise bzr_errors.BzrError("missing sqlite library")
0.200.228 by Jelmer Vernooij
Split out map.
102
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
103
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
104
_mapdbs = threading.local()
7143.15.2 by Jelmer Vernooij
Run autopep8.
105
106
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
107
def mapdbs():
108
    """Get a cache for this thread's db connections."""
109
    try:
110
        return _mapdbs.cache
111
    except AttributeError:
112
        _mapdbs.cache = {}
113
        return _mapdbs.cache
114
115
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
116
class GitShaMap(object):
117
    """Git<->Bzr revision id mapping database."""
118
119
    def lookup_git_sha(self, sha):
120
        """Lookup a Git sha in the database.
121
        :param sha: Git object sha
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
122
        :return: list with (type, type_data) tuples with type_data:
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
123
            commit: revid, tree_sha, verifiers
124
            blob: fileid, revid
125
            tree: fileid, revid
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
126
        """
127
        raise NotImplementedError(self.lookup_git_sha)
128
0.200.835 by Jelmer Vernooij
Rename lookup_{tree,blob} -> lookup_{tree,blob}_id.
129
    def lookup_blob_id(self, file_id, revision):
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
130
        """Retrieve a Git blob SHA by file id.
131
132
        :param file_id: File id of the file/symlink
0.200.806 by Jelmer Vernooij
Make revision_hint mandatory.
133
        :param revision: revision in which the file was last changed.
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
134
        """
0.200.835 by Jelmer Vernooij
Rename lookup_{tree,blob} -> lookup_{tree,blob}_id.
135
        raise NotImplementedError(self.lookup_blob_id)
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
136
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
137
    def lookup_tree_id(self, file_id, revision):
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
138
        """Retrieve a Git tree SHA by file id.
139
        """
0.200.835 by Jelmer Vernooij
Rename lookup_{tree,blob} -> lookup_{tree,blob}_id.
140
        raise NotImplementedError(self.lookup_tree_id)
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
141
0.200.1039 by Jelmer Vernooij
Add stub.
142
    def lookup_commit(self, revid):
143
        """Retrieve a Git commit SHA by Bazaar revision id.
144
        """
145
        raise NotImplementedError(self.lookup_commit)
146
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
147
    def revids(self):
148
        """List the revision ids known."""
149
        raise NotImplementedError(self.revids)
150
0.200.677 by Jelmer Vernooij
Implement TdbCache.missing_revisions().
151
    def missing_revisions(self, revids):
152
        """Return set of all the revisions that are not present."""
153
        present_revids = set(self.revids())
154
        if not isinstance(revids, set):
155
            revids = set(revids)
156
        return revids - present_revids
157
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
158
    def sha1s(self):
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
159
        """List the SHA1s."""
160
        raise NotImplementedError(self.sha1s)
161
0.200.687 by Jelmer Vernooij
Use start_write_group() / commit_write_group() mechanism when creating git SHA maps.
162
    def start_write_group(self):
163
        """Start writing changes."""
164
165
    def commit_write_group(self):
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
166
        """Commit any pending changes."""
167
0.200.687 by Jelmer Vernooij
Use start_write_group() / commit_write_group() mechanism when creating git SHA maps.
168
    def abort_write_group(self):
169
        """Abort any pending changes."""
170
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
171
0.254.44 by Jelmer Vernooij
Add knit-based content cache for trees.
172
class ContentCache(object):
173
    """Object that can cache Git objects."""
174
0.200.952 by Jelmer Vernooij
Write git pack files rather than loose objects.
175
    def add(self, object):
176
        """Add an object."""
177
        raise NotImplementedError(self.add)
178
179
    def add_multi(self, objects):
180
        """Add multiple objects."""
181
        for obj in objects:
182
            self.add(obj)
183
0.254.44 by Jelmer Vernooij
Add knit-based content cache for trees.
184
    def __getitem__(self, sha):
185
        """Retrieve an item, by SHA."""
186
        raise NotImplementedError(self.__getitem__)
187
188
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
189
class BzrGitCacheFormat(object):
0.254.51 by Jelmer Vernooij
Add some docstrings.
190
    """Bazaar-Git Cache Format."""
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
191
192
    def get_format_string(self):
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
193
        """Return a single-line unique format string for this cache format."""
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
194
        raise NotImplementedError(self.get_format_string)
195
196
    def open(self, transport):
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
197
        """Open this format on a transport."""
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
198
        raise NotImplementedError(self.open)
199
200
    def initialize(self, transport):
0.254.51 by Jelmer Vernooij
Add some docstrings.
201
        """Create a new instance of this cache format at transport."""
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
202
        transport.put_bytes('format', self.get_format_string())
203
204
    @classmethod
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
205
    def from_transport(self, transport):
206
        """Open a cache file present on a transport, or initialize one.
207
208
        :param transport: Transport to use
209
        :return: A BzrGitCache instance
210
        """
211
        try:
212
            format_name = transport.get_bytes('format')
213
            format = formats.get(format_name)
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
214
        except bzr_errors.NoSuchFile:
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
215
            format = formats.get('default')
216
            format.initialize(transport)
217
        return format.open(transport)
218
219
    @classmethod
220
    def from_repository(cls, repository):
221
        """Open a cache file for a repository.
222
223
        This will use the repository's transport to store the cache file, or
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
224
        use the users global cache directory if the repository has no
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
225
        transport associated with it.
226
227
        :param repository: Repository to open the cache for
228
        :return: A `BzrGitCache`
229
        """
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
230
        from ..transport.local import LocalTransport
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
231
        repo_transport = getattr(repository, "_transport", None)
7143.15.2 by Jelmer Vernooij
Run autopep8.
232
        if (repo_transport is not None
233
                and isinstance(repo_transport, LocalTransport)):
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
234
            # Even if we don't write to this repo, we should be able
0.200.865 by Jelmer Vernooij
Support serving without --allow-writes.
235
            # to update its cache.
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
236
            try:
7143.15.2 by Jelmer Vernooij
Run autopep8.
237
                repo_transport = remove_readonly_transport_decorator(
238
                    repo_transport)
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
239
            except bzr_errors.ReadOnlyError:
0.200.1438 by Jelmer Vernooij
Cope with remote branches not being readonly at all better.
240
                transport = None
241
            else:
242
                try:
243
                    repo_transport.mkdir('git')
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
244
                except bzr_errors.FileExists:
0.200.1438 by Jelmer Vernooij
Cope with remote branches not being readonly at all better.
245
                    pass
246
                transport = repo_transport.clone('git')
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
247
        else:
0.200.1438 by Jelmer Vernooij
Cope with remote branches not being readonly at all better.
248
            transport = None
249
        if transport is None:
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
250
            transport = get_remote_cache_transport(repository)
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
251
        return cls.from_transport(transport)
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
252
253
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
254
class CacheUpdater(object):
0.254.51 by Jelmer Vernooij
Add some docstrings.
255
    """Base class for objects that can update a bzr-git cache."""
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
256
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
257
    def add_object(self, obj, bzr_key_data, path):
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
258
        """Add an object.
259
260
        :param obj: Object type ("commit", "blob" or "tree")
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
261
        :param bzr_key_data: bzr key store data or testament_sha in case
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
262
            of commit
263
        :param path: Path of the object (optional)
264
        """
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
265
        raise NotImplementedError(self.add_object)
266
267
    def finish(self):
268
        raise NotImplementedError(self.finish)
269
270
271
class BzrGitCache(object):
272
    """Caching backend."""
273
0.422.1 by Jelmer Vernooij
Remove content caching, fix index.
274
    def __init__(self, idmap, cache_updater_klass):
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
275
        self.idmap = idmap
276
        self._cache_updater_klass = cache_updater_klass
277
278
    def get_updater(self, rev):
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
279
        """Update an object that implements the CacheUpdater interface for
0.254.51 by Jelmer Vernooij
Add some docstrings.
280
        updating this cache.
281
        """
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
282
        return self._cache_updater_klass(self, rev)
283
284
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
285
def DictBzrGitCache():
286
    return BzrGitCache(DictGitShaMap(), DictCacheUpdater)
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
287
288
289
class DictCacheUpdater(CacheUpdater):
0.254.51 by Jelmer Vernooij
Add some docstrings.
290
    """Cache updater for dict-based caches."""
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
291
292
    def __init__(self, cache, rev):
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
293
        self.cache = cache
294
        self.revid = rev.revision_id
295
        self.parent_revids = rev.parent_ids
296
        self._commit = None
297
        self._entries = []
298
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
299
    def add_object(self, obj, bzr_key_data, path):
0.423.1 by Jelmer Vernooij
Some performance fixes.
300
        if isinstance(obj, tuple):
301
            (type_name, hexsha) = obj
302
        else:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
303
            type_name = obj.type_name.decode('ascii')
0.423.1 by Jelmer Vernooij
Some performance fixes.
304
            hexsha = obj.id
7018.3.1 by Jelmer Vernooij
Fix git cache handling.
305
        if not isinstance(hexsha, bytes):
306
            raise TypeError(hexsha)
0.423.1 by Jelmer Vernooij
Some performance fixes.
307
        if type_name == "commit":
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
308
            self._commit = obj
0.361.1 by Jelmer Vernooij
Don't use assert.
309
            if type(bzr_key_data) is not dict:
310
                raise TypeError(bzr_key_data)
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
311
            key = self.revid
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
312
            type_data = (self.revid, self._commit.tree, bzr_key_data)
0.423.1 by Jelmer Vernooij
Some performance fixes.
313
            self.cache.idmap._by_revid[self.revid] = hexsha
314
        elif type_name in ("blob", "tree"):
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
315
            if bzr_key_data is not None:
0.421.6 by Jelmer Vernooij
Some more simplifications.
316
                key = type_data = bzr_key_data
7143.15.2 by Jelmer Vernooij
Run autopep8.
317
                self.cache.idmap._by_fileid.setdefault(type_data[1], {})[
318
                    type_data[0]] = hexsha
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
319
        else:
320
            raise AssertionError
0.423.1 by Jelmer Vernooij
Some performance fixes.
321
        entry = (type_name, type_data)
322
        self.cache.idmap._by_sha.setdefault(hexsha, {})[key] = entry
0.200.847 by Jelmer Vernooij
Add BzrGitCache object.
323
324
    def finish(self):
325
        if self._commit is None:
326
            raise AssertionError("No commit object added")
327
        return self._commit
328
329
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
330
class DictGitShaMap(GitShaMap):
0.254.51 by Jelmer Vernooij
Add some docstrings.
331
    """Git SHA map that uses a dictionary."""
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
332
333
    def __init__(self):
0.200.753 by Jelmer Vernooij
Move lookup_tree/lookup_blob to a separate object.
334
        self._by_sha = {}
335
        self._by_fileid = {}
0.200.853 by Jelmer Vernooij
Fix lookup of commits in tdb.
336
        self._by_revid = {}
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
337
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
338
    def lookup_blob_id(self, fileid, revision):
339
        return self._by_fileid[revision][fileid]
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
340
341
    def lookup_git_sha(self, sha):
7018.3.1 by Jelmer Vernooij
Fix git cache handling.
342
        if not isinstance(sha, bytes):
343
            raise TypeError(sha)
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
344
        for entry in viewvalues(self._by_sha[sha]):
0.261.2 by Jelmer Vernooij
Fix cache tests.
345
            yield entry
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
346
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
347
    def lookup_tree_id(self, fileid, revision):
0.200.860 by Jelmer Vernooij
Fix bugs in two lookup_tree_id implementations and add a test for it.
348
        return self._by_fileid[revision][fileid]
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
349
0.200.853 by Jelmer Vernooij
Fix lookup of commits in tdb.
350
    def lookup_commit(self, revid):
351
        return self._by_revid[revid]
352
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
353
    def revids(self):
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
354
        for key, entries in viewitems(self._by_sha):
7018.3.1 by Jelmer Vernooij
Fix git cache handling.
355
            for (type, type_data) in viewvalues(entries):
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
356
                if type == "commit":
357
                    yield type_data[0]
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
358
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
359
    def sha1s(self):
6973.13.6 by Jelmer Vernooij
drop tests affected by new HPSS call.
360
        return viewkeys(self._by_sha)
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
361
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
362
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
363
class SqliteCacheUpdater(CacheUpdater):
364
365
    def __init__(self, cache, rev):
366
        self.cache = cache
0.200.850 by Jelmer Vernooij
Fix tests.
367
        self.db = self.cache.idmap.db
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
368
        self.revid = rev.revision_id
369
        self._commit = None
370
        self._trees = []
371
        self._blobs = []
372
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
373
    def add_object(self, obj, bzr_key_data, path):
0.423.1 by Jelmer Vernooij
Some performance fixes.
374
        if isinstance(obj, tuple):
375
            (type_name, hexsha) = obj
376
        else:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
377
            type_name = obj.type_name.decode('ascii')
0.423.1 by Jelmer Vernooij
Some performance fixes.
378
            hexsha = obj.id
7018.3.1 by Jelmer Vernooij
Fix git cache handling.
379
        if not isinstance(hexsha, bytes):
380
            raise TypeError(hexsha)
0.423.1 by Jelmer Vernooij
Some performance fixes.
381
        if type_name == "commit":
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
382
            self._commit = obj
0.361.1 by Jelmer Vernooij
Don't use assert.
383
            if type(bzr_key_data) is not dict:
384
                raise TypeError(bzr_key_data)
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
385
            self._testament3_sha1 = bzr_key_data.get("testament3-sha1")
0.423.1 by Jelmer Vernooij
Some performance fixes.
386
        elif type_name == "tree":
387
            if bzr_key_data is not None:
388
                self._trees.append((hexsha, bzr_key_data[0], bzr_key_data[1]))
389
        elif type_name == "blob":
390
            if bzr_key_data is not None:
391
                self._blobs.append((hexsha, bzr_key_data[0], bzr_key_data[1]))
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
392
        else:
393
            raise AssertionError
394
395
    def finish(self):
396
        if self._commit is None:
397
            raise AssertionError("No commit object added")
0.200.850 by Jelmer Vernooij
Fix tests.
398
        self.db.executemany(
399
            "replace into trees (sha1, fileid, revid) values (?, ?, ?)",
400
            self._trees)
401
        self.db.executemany(
402
            "replace into blobs (sha1, fileid, revid) values (?, ?, ?)",
403
            self._blobs)
404
        self.db.execute(
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
405
            "replace into commits (sha1, revid, tree_sha, testament3_sha1) "
406
            "values (?, ?, ?, ?)",
407
            (self._commit.id, self.revid, self._commit.tree,
408
                self._testament3_sha1))
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
409
        return self._commit
410
411
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
412
def SqliteBzrGitCache(p):
413
    return BzrGitCache(SqliteGitShaMap(p), SqliteCacheUpdater)
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
414
415
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
416
class SqliteGitCacheFormat(BzrGitCacheFormat):
417
418
    def get_format_string(self):
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
419
        return b'bzr-git sha map version 1 using sqlite\n'
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
420
421
    def open(self, transport):
422
        try:
423
            basepath = transport.local_abspath(".")
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
424
        except bzr_errors.NotLocalUrl:
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
425
            basepath = get_cache_dir()
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
426
        return SqliteBzrGitCache(os.path.join(basepath, "idmap.db"))
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
427
428
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
429
class SqliteGitShaMap(GitShaMap):
0.254.51 by Jelmer Vernooij
Add some docstrings.
430
    """Bazaar GIT Sha map that uses a sqlite database for storage."""
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
431
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
432
    def __init__(self, path=None):
433
        self.path = path
434
        if path is None:
0.200.262 by Jelmer Vernooij
Add tests for GitShaMap.
435
            self.db = sqlite3.connect(":memory:")
436
        else:
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
437
            if path not in mapdbs():
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
438
                mapdbs()[path] = sqlite3.connect(path)
0.200.675 by Jelmer Vernooij
Fix formatting.
439
            self.db = mapdbs()[path]
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
440
        self.db.text_factory = str
0.200.230 by Jelmer Vernooij
Implement sha cache.
441
        self.db.executescript("""
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
442
        create table if not exists commits(
443
            sha1 text not null check(length(sha1) == 40),
444
            revid text not null,
445
            tree_sha text not null check(length(tree_sha) == 40)
446
        );
0.200.230 by Jelmer Vernooij
Implement sha cache.
447
        create index if not exists commit_sha1 on commits(sha1);
0.200.284 by Jelmer Vernooij
Add extra indexes.
448
        create unique index if not exists commit_revid on commits(revid);
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
449
        create table if not exists blobs(
450
            sha1 text not null check(length(sha1) == 40),
451
            fileid text not null,
452
            revid text not null
453
        );
0.200.230 by Jelmer Vernooij
Implement sha cache.
454
        create index if not exists blobs_sha1 on blobs(sha1);
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
455
        create unique index if not exists blobs_fileid_revid on blobs(
456
            fileid, revid);
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
457
        create table if not exists trees(
0.255.1 by Jelmer Vernooij
Remove use of lookup_tree.
458
            sha1 text unique not null check(length(sha1) == 40),
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
459
            fileid text not null,
460
            revid text not null
461
        );
0.255.1 by Jelmer Vernooij
Remove use of lookup_tree.
462
        create unique index if not exists trees_sha1 on trees(sha1);
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
463
        create unique index if not exists trees_fileid_revid on trees(
464
            fileid, revid);
0.200.230 by Jelmer Vernooij
Implement sha cache.
465
""")
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
466
        try:
467
            self.db.executescript(
468
                "ALTER TABLE commits ADD testament3_sha1 TEXT;")
469
        except sqlite3.OperationalError:
7143.15.2 by Jelmer Vernooij
Run autopep8.
470
            pass  # Column already exists.
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
471
0.254.19 by Jelmer Vernooij
Support upgrading sha maps.
472
    def __repr__(self):
473
        return "%s(%r)" % (self.__class__.__name__, self.path)
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
474
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
475
    def lookup_commit(self, revid):
7143.15.2 by Jelmer Vernooij
Run autopep8.
476
        cursor = self.db.execute("select sha1 from commits where revid = ?",
477
                                 (revid,))
0.254.51 by Jelmer Vernooij
Add some docstrings.
478
        row = cursor.fetchone()
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
479
        if row is not None:
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
480
            return row[0]
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
481
        raise KeyError
0.200.231 by Jelmer Vernooij
Partially fix pull.
482
0.200.687 by Jelmer Vernooij
Use start_write_group() / commit_write_group() mechanism when creating git SHA maps.
483
    def commit_write_group(self):
0.200.232 by Jelmer Vernooij
Fix pull from remote branches.
484
        self.db.commit()
485
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
486
    def lookup_blob_id(self, fileid, revision):
7143.15.2 by Jelmer Vernooij
Run autopep8.
487
        row = self.db.execute(
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
488
            "select sha1 from blobs where fileid = ? and revid = ?",
489
            (fileid, revision)).fetchone()
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
490
        if row is not None:
491
            return row[0]
492
        raise KeyError(fileid)
493
494
    def lookup_tree_id(self, fileid, revision):
7143.15.2 by Jelmer Vernooij
Run autopep8.
495
        row = self.db.execute(
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
496
            "select sha1 from trees where fileid = ? and revid = ?",
497
            (fileid, revision)).fetchone()
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
498
        if row is not None:
499
            return row[0]
500
        raise KeyError(fileid)
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
501
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
502
    def lookup_git_sha(self, sha):
503
        """Lookup a Git sha in the database.
504
505
        :param sha: Git object sha
506
        :return: (type, type_data) with type_data:
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
507
            commit: revid, tree sha, verifiers
508
            tree: fileid, revid
509
            blob: fileid, revid
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
510
        """
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
511
        found = False
7143.15.2 by Jelmer Vernooij
Run autopep8.
512
        cursor = self.db.execute(
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
513
            "select revid, tree_sha, testament3_sha1 from commits where "
514
            "sha1 = ?", (sha,))
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
515
        for row in cursor.fetchall():
516
            found = True
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
517
            if row[2] is not None:
518
                verifiers = {"testament3-sha1": row[2]}
519
            else:
520
                verifiers = {}
521
            yield ("commit", (row[0], row[1], verifiers))
7143.15.2 by Jelmer Vernooij
Run autopep8.
522
        cursor = self.db.execute(
523
            "select fileid, revid from blobs where sha1 = ?", (sha,))
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
524
        for row in cursor.fetchall():
525
            found = True
526
            yield ("blob", row)
7143.15.2 by Jelmer Vernooij
Run autopep8.
527
        cursor = self.db.execute(
528
            "select fileid, revid from trees where sha1 = ?", (sha,))
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
529
        for row in cursor.fetchall():
530
            found = True
531
            yield ("tree", row)
532
        if not found:
533
            raise KeyError(sha)
0.200.230 by Jelmer Vernooij
Implement sha cache.
534
535
    def revids(self):
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
536
        """List the revision ids known."""
0.248.7 by Jelmer Vernooij
Avoid fetching all sha1s at once.
537
        return (row for (row,) in self.db.execute("select revid from commits"))
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
538
539
    def sha1s(self):
540
        """List the SHA1s."""
541
        for table in ("blobs", "commits", "trees"):
0.254.26 by Jelmer Vernooij
Fix typo, cope with invalid shamaps a bit better.
542
            for (sha,) in self.db.execute("select sha1 from %s" % table):
7018.3.1 by Jelmer Vernooij
Fix git cache handling.
543
                yield sha.encode('ascii')
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
544
545
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
546
class TdbCacheUpdater(CacheUpdater):
0.254.51 by Jelmer Vernooij
Add some docstrings.
547
    """Cache updater for tdb-based caches."""
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
548
549
    def __init__(self, cache, rev):
550
        self.cache = cache
551
        self.db = cache.idmap.db
552
        self.revid = rev.revision_id
553
        self.parent_revids = rev.parent_ids
554
        self._commit = None
555
        self._entries = []
556
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
557
    def add_object(self, obj, bzr_key_data, path):
0.423.1 by Jelmer Vernooij
Some performance fixes.
558
        if isinstance(obj, tuple):
559
            (type_name, hexsha) = obj
560
            sha = hex_to_sha(hexsha)
561
        else:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
562
            type_name = obj.type_name.decode('ascii')
0.423.1 by Jelmer Vernooij
Some performance fixes.
563
            sha = obj.sha().digest()
564
        if type_name == "commit":
6973.14.6 by Jelmer Vernooij
Fix some more tests.
565
            self.db[b"commit\0" + self.revid] = b"\0".join((sha, obj.tree))
0.361.1 by Jelmer Vernooij
Don't use assert.
566
            if type(bzr_key_data) is not dict:
567
                raise TypeError(bzr_key_data)
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
568
            type_data = (self.revid, obj.tree)
569
            try:
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
570
                type_data += (bzr_key_data["testament3-sha1"],)
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
571
            except KeyError:
572
                pass
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
573
            self._commit = obj
0.423.1 by Jelmer Vernooij
Some performance fixes.
574
        elif type_name == "blob":
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
575
            if bzr_key_data is None:
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
576
                return
7143.15.2 by Jelmer Vernooij
Run autopep8.
577
            self.db[b"\0".join(
578
                (b"blob", bzr_key_data[0], bzr_key_data[1]))] = sha
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
579
            type_data = bzr_key_data
0.423.1 by Jelmer Vernooij
Some performance fixes.
580
        elif type_name == "tree":
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
581
            if bzr_key_data is None:
0.252.23 by Jelmer Vernooij
More work on roundtripping support.
582
                return
0.421.6 by Jelmer Vernooij
Some more simplifications.
583
            type_data = bzr_key_data
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
584
        else:
585
            raise AssertionError
6973.14.6 by Jelmer Vernooij
Fix some more tests.
586
        entry = b"\0".join((type_name.encode('ascii'), ) + type_data) + b"\n"
587
        key = b"git\0" + sha
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
588
        try:
589
            oldval = self.db[key]
590
        except KeyError:
591
            self.db[key] = entry
592
        else:
6973.11.12 by Jelmer Vernooij
Fix tdb cache tests when tdb is installed.
593
            if not oldval.endswith(b'\n'):
6973.14.6 by Jelmer Vernooij
Fix some more tests.
594
                self.db[key] = b"".join([oldval, b"\n", entry])
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
595
            else:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
596
                self.db[key] = b"".join([oldval, entry])
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
597
598
    def finish(self):
599
        if self._commit is None:
600
            raise AssertionError("No commit object added")
601
        return self._commit
602
603
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
604
def TdbBzrGitCache(p):
605
    return BzrGitCache(TdbGitShaMap(p), TdbCacheUpdater)
0.200.479 by Jelmer Vernooij
Version tdb sha map.
606
0.200.1140 by Jelmer Vernooij
Update now that the control dir formats are no longer in __init__.
607
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
608
class TdbGitCacheFormat(BzrGitCacheFormat):
0.254.51 by Jelmer Vernooij
Add some docstrings.
609
    """Cache format for tdb-based caches."""
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
610
611
    def get_format_string(self):
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
612
        return b'bzr-git sha map version 3 using tdb\n'
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
613
614
    def open(self, transport):
615
        try:
0.200.1075 by Jelmer Vernooij
Fix compatibility with older versions of python-tdb.
616
            basepath = transport.local_abspath(".").encode(osutils._fs_enc)
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
617
        except bzr_errors.NotLocalUrl:
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
618
            basepath = get_cache_dir()
6973.14.6 by Jelmer Vernooij
Fix some more tests.
619
        if not isinstance(basepath, str):
0.361.1 by Jelmer Vernooij
Don't use assert.
620
            raise TypeError(basepath)
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
621
        try:
0.200.850 by Jelmer Vernooij
Fix tests.
622
            return TdbBzrGitCache(os.path.join(basepath, "idmap.tdb"))
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
623
        except ImportError:
624
            raise ImportError(
625
                "Unable to open existing bzr-git cache because 'tdb' is not "
626
                "installed.")
627
628
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
629
class TdbGitShaMap(GitShaMap):
630
    """SHA Map that uses a TDB database.
631
632
    Entries:
633
0.200.476 by Jelmer Vernooij
Fix Tdb backend, use tdb if possible by default.
634
    "git <sha1>" -> "<type> <type-data1> <type-data2>"
635
    "commit revid" -> "<sha1> <tree-id>"
0.200.477 by Jelmer Vernooij
More tests for sha maps, fix cache misses in tdb.
636
    "tree fileid revid" -> "<sha1>"
637
    "blob fileid revid" -> "<sha1>"
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
638
    """
639
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
640
    TDB_MAP_VERSION = 3
641
    TDB_HASH_SIZE = 50000
642
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
643
    def __init__(self, path=None):
644
        import tdb
645
        self.path = path
646
        if path is None:
647
            self.db = {}
648
        else:
6973.5.10 by Jelmer Vernooij
Random bunch of python3 bee-improvements.
649
            if path not in mapdbs():
0.200.849 by Jelmer Vernooij
Allow cache backends to decide when to add entries rather than adding once per commit.
650
                mapdbs()[path] = tdb.Tdb(path, self.TDB_HASH_SIZE, tdb.DEFAULT,
7143.15.2 by Jelmer Vernooij
Run autopep8.
651
                                         os.O_RDWR | os.O_CREAT)
0.200.676 by Jelmer Vernooij
Avoid iterating over all keys in the tdb database.
652
            self.db = mapdbs()[path]
653
        try:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
654
            if int(self.db[b"version"]) not in (2, 3):
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
655
                trace.warning(
656
                    "SHA Map is incompatible (%s -> %d), rebuilding database.",
657
                    self.db[b"version"], self.TDB_MAP_VERSION)
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
658
                self.db.clear()
0.200.676 by Jelmer Vernooij
Avoid iterating over all keys in the tdb database.
659
        except KeyError:
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
660
            pass
6973.14.6 by Jelmer Vernooij
Fix some more tests.
661
        self.db[b"version"] = b'%d' % self.TDB_MAP_VERSION
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
662
0.200.809 by Jelmer Vernooij
Use tdb transactions for write groups.
663
    def start_write_group(self):
664
        """Start writing changes."""
0.200.778 by Jelmer Vernooij
Use transactions in tdb.
665
        self.db.transaction_start()
0.200.809 by Jelmer Vernooij
Use tdb transactions for write groups.
666
667
    def commit_write_group(self):
668
        """Commit any pending changes."""
669
        self.db.transaction_commit()
670
671
    def abort_write_group(self):
672
        """Abort any pending changes."""
673
        self.db.transaction_cancel()
0.200.778 by Jelmer Vernooij
Use transactions in tdb.
674
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
675
    def __repr__(self):
676
        return "%s(%r)" % (self.__class__.__name__, self.path)
677
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
678
    def lookup_commit(self, revid):
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
679
        try:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
680
            return sha_to_hex(self.db[b"commit\0" + revid][:20])
0.200.1264 by Jelmer Vernooij
Fix updating cache for single revision - don't consider it an update of the full cache.
681
        except KeyError:
682
            raise KeyError("No cache entry for %r" % revid)
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
683
0.200.841 by Jelmer Vernooij
Eliminate InventorySHAMap.
684
    def lookup_blob_id(self, fileid, revision):
6973.14.6 by Jelmer Vernooij
Fix some more tests.
685
        return sha_to_hex(self.db[b"\0".join((b"blob", fileid, revision))])
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
686
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
687
    def lookup_git_sha(self, sha):
688
        """Lookup a Git sha in the database.
689
690
        :param sha: Git object sha
691
        :return: (type, type_data) with type_data:
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
692
            commit: revid, tree sha
693
            blob: fileid, revid
694
            tree: fileid, revid
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
695
        """
0.200.564 by Jelmer Vernooij
Accept 'binary' shas.
696
        if len(sha) == 40:
697
            sha = hex_to_sha(sha)
6973.14.6 by Jelmer Vernooij
Fix some more tests.
698
        value = self.db[b"git\0" + sha]
0.261.2 by Jelmer Vernooij
Fix cache tests.
699
        for data in value.splitlines():
6973.14.6 by Jelmer Vernooij
Fix some more tests.
700
            data = data.split(b"\0")
701
            type_name = data[0].decode('ascii')
702
            if type_name == "commit":
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
703
                if len(data) == 3:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
704
                    yield (type_name, (data[1], data[2], {}))
0.261.1 by Jelmer Vernooij
Initial work on supporting multiple results for git shas.
705
                else:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
706
                    yield (type_name, (data[1], data[2],
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
707
                                       {"testament3-sha1": data[3]}))
6973.14.8 by Jelmer Vernooij
Fix tests.
708
            elif type_name in ("tree", "blob"):
709
                yield (type_name, tuple(data[1:]))
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
710
            else:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
711
                raise AssertionError("unknown type %r" % type_name)
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
712
0.200.677 by Jelmer Vernooij
Implement TdbCache.missing_revisions().
713
    def missing_revisions(self, revids):
714
        ret = set()
715
        for revid in revids:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
716
            if self.db.get(b"commit\0" + revid) is None:
0.200.677 by Jelmer Vernooij
Implement TdbCache.missing_revisions().
717
                ret.add(revid)
718
        return ret
719
6973.14.10 by Jelmer Vernooij
Merge python3-l.
720
    def _keys(self):
721
        try:
7018.3.2 by Jelmer Vernooij
Fix some git tests.
722
            return self.db.keys()
723
        except AttributeError:  # python < 3
6973.14.10 by Jelmer Vernooij
Merge python3-l.
724
            return self.db.iterkeys()
725
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
726
    def revids(self):
727
        """List the revision ids known."""
6973.14.10 by Jelmer Vernooij
Merge python3-l.
728
        for key in self._keys():
6973.14.6 by Jelmer Vernooij
Fix some more tests.
729
            if key.startswith(b"commit\0"):
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
730
                yield key[7:]
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
731
732
    def sha1s(self):
733
        """List the SHA1s."""
6973.14.10 by Jelmer Vernooij
Merge python3-l.
734
        for key in self._keys():
6973.14.6 by Jelmer Vernooij
Fix some more tests.
735
            if key.startswith(b"git\0"):
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
736
                yield sha_to_hex(key[4:])
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
737
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
738
0.254.44 by Jelmer Vernooij
Add knit-based content cache for trees.
739
class VersionedFilesContentCache(ContentCache):
740
741
    def __init__(self, vf):
742
        self._vf = vf
743
744
    def add(self, obj):
745
        self._vf.insert_record_stream(
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
746
            [versionedfile.ChunkedContentFactory(
747
                (obj.id,), [], None, obj.as_legacy_object_chunks())])
0.254.44 by Jelmer Vernooij
Add knit-based content cache for trees.
748
749
    def __getitem__(self, sha):
750
        stream = self._vf.get_record_stream([(sha,)], 'unordered', True)
6973.10.5 by Jelmer Vernooij
Fix use of .next.
751
        entry = next(stream)
0.254.44 by Jelmer Vernooij
Add knit-based content cache for trees.
752
        if entry.storage_kind == 'absent':
753
            raise KeyError(sha)
754
        return ShaFile._parse_legacy_object(entry.get_bytes_as('fulltext'))
755
756
0.254.46 by Jelmer Vernooij
Merge trunk.
757
class IndexCacheUpdater(CacheUpdater):
758
759
    def __init__(self, cache, rev):
760
        self.cache = cache
761
        self.revid = rev.revision_id
762
        self.parent_revids = rev.parent_ids
763
        self._commit = None
764
        self._entries = []
765
0.275.2 by Jelmer Vernooij
Pass tuples around for cache entries, rather than inventory entries.
766
    def add_object(self, obj, bzr_key_data, path):
0.423.1 by Jelmer Vernooij
Some performance fixes.
767
        if isinstance(obj, tuple):
768
            (type_name, hexsha) = obj
769
        else:
6973.14.6 by Jelmer Vernooij
Fix some more tests.
770
            type_name = obj.type_name.decode('ascii')
0.423.1 by Jelmer Vernooij
Some performance fixes.
771
            hexsha = obj.id
772
        if type_name == "commit":
0.254.46 by Jelmer Vernooij
Merge trunk.
773
            self._commit = obj
0.361.1 by Jelmer Vernooij
Don't use assert.
774
            if type(bzr_key_data) is not dict:
775
                raise TypeError(bzr_key_data)
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
776
            self.cache.idmap._add_git_sha(hexsha, b"commit",
7143.15.2 by Jelmer Vernooij
Run autopep8.
777
                                          (self.revid, obj.tree, bzr_key_data))
6973.14.6 by Jelmer Vernooij
Fix some more tests.
778
            self.cache.idmap._add_node((b"commit", self.revid, b"X"),
7143.15.2 by Jelmer Vernooij
Run autopep8.
779
                                       b" ".join((hexsha, obj.tree)))
0.423.1 by Jelmer Vernooij
Some performance fixes.
780
        elif type_name == "blob":
6973.14.6 by Jelmer Vernooij
Fix some more tests.
781
            self.cache.idmap._add_git_sha(hexsha, b"blob", bzr_key_data)
782
            self.cache.idmap._add_node((b"blob", bzr_key_data[0],
7143.15.2 by Jelmer Vernooij
Run autopep8.
783
                                        bzr_key_data[1]), hexsha)
0.423.1 by Jelmer Vernooij
Some performance fixes.
784
        elif type_name == "tree":
6973.14.6 by Jelmer Vernooij
Fix some more tests.
785
            self.cache.idmap._add_git_sha(hexsha, b"tree", bzr_key_data)
0.254.46 by Jelmer Vernooij
Merge trunk.
786
        else:
787
            raise AssertionError
788
789
    def finish(self):
790
        return self._commit
791
792
793
class IndexBzrGitCache(BzrGitCache):
794
795
    def __init__(self, transport=None):
0.254.52 by Jelmer Vernooij
Merge trunk, use git objects to cache tree objects.
796
        shamap = IndexGitShaMap(transport.clone('index'))
0.422.1 by Jelmer Vernooij
Remove content caching, fix index.
797
        super(IndexBzrGitCache, self).__init__(shamap, IndexCacheUpdater)
0.254.46 by Jelmer Vernooij
Merge trunk.
798
799
0.254.43 by Jelmer Vernooij
Merge trunk.
800
class IndexGitCacheFormat(BzrGitCacheFormat):
801
802
    def get_format_string(self):
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
803
        return b'bzr-git sha map with git object cache version 1\n'
0.254.43 by Jelmer Vernooij
Merge trunk.
804
805
    def initialize(self, transport):
806
        super(IndexGitCacheFormat, self).initialize(transport)
807
        transport.mkdir('index')
0.254.52 by Jelmer Vernooij
Merge trunk, use git objects to cache tree objects.
808
        transport.mkdir('objects')
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
809
        from .transportgit import TransportObjectStore
0.254.52 by Jelmer Vernooij
Merge trunk, use git objects to cache tree objects.
810
        TransportObjectStore.init(transport.clone('objects'))
0.254.43 by Jelmer Vernooij
Merge trunk.
811
812
    def open(self, transport):
0.254.46 by Jelmer Vernooij
Merge trunk.
813
        return IndexBzrGitCache(transport)
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
814
815
816
class IndexGitShaMap(GitShaMap):
0.254.31 by Jelmer Vernooij
Initial work on CHKMap support.
817
    """SHA Map that uses the Bazaar APIs to store a cache.
818
819
    BTree Index file with the following contents:
820
0.422.1 by Jelmer Vernooij
Remove content caching, fix index.
821
    ("git", <sha1>, "X") -> "<type> <type-data1> <type-data2>"
822
    ("commit", <revid>, "X") -> "<sha1> <tree-id>"
0.254.36 by Jelmer Vernooij
Merge trunk.
823
    ("blob", <fileid>, <revid>) -> <sha1>
824
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
825
    """
826
827
    def __init__(self, transport=None):
6962.1.1 by Jelmer Vernooij
Fix handling cache updates in bzr-based index formats.
828
        self._name = None
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
829
        if transport is None:
0.254.43 by Jelmer Vernooij
Merge trunk.
830
            self._transport = None
0.254.36 by Jelmer Vernooij
Merge trunk.
831
            self._index = _mod_index.InMemoryGraphIndex(0, key_elements=3)
0.254.2 by jelmer
use btree indexes
832
            self._builder = self._index
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
833
        else:
0.254.30 by Jelmer Vernooij
Move index to separate dir.
834
            self._builder = None
0.254.43 by Jelmer Vernooij
Merge trunk.
835
            self._transport = transport
0.254.2 by jelmer
use btree indexes
836
            self._index = _mod_index.CombinedGraphIndex([])
0.254.43 by Jelmer Vernooij
Merge trunk.
837
            for name in self._transport.list_dir("."):
0.254.2 by jelmer
use btree indexes
838
                if not name.endswith(".rix"):
839
                    continue
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
840
                x = _mod_btree_index.BTreeGraphIndex(
841
                    self._transport, name, self._transport.stat(name).st_size)
0.254.2 by jelmer
use btree indexes
842
                self._index.insert_index(0, x)
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
843
844
    @classmethod
845
    def from_repository(cls, repository):
846
        transport = getattr(repository, "_transport", None)
847
        if transport is not None:
0.254.2 by jelmer
use btree indexes
848
            try:
849
                transport.mkdir('git')
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
850
            except bzr_errors.FileExists:
0.254.2 by jelmer
use btree indexes
851
                pass
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
852
            return cls(transport.clone('git'))
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
853
        from ..transport import get_transport
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
854
        return cls(get_transport(get_cache_dir()))
855
0.254.19 by Jelmer Vernooij
Support upgrading sha maps.
856
    def __repr__(self):
857
        if self._transport is not None:
858
            return "%s(%r)" % (self.__class__.__name__, self._transport.base)
859
        else:
860
            return "%s()" % (self.__class__.__name__)
861
0.254.3 by John Arbash Meinel
Add repack function.
862
    def repack(self):
0.361.1 by Jelmer Vernooij
Don't use assert.
863
        if self._builder is not None:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
864
            raise bzr_errors.BzrError('builder already open')
0.254.3 by John Arbash Meinel
Add repack function.
865
        self.start_write_group()
0.422.1 by Jelmer Vernooij
Remove content caching, fix index.
866
        self._builder.add_nodes(
867
            ((key, value) for (_, key, value) in
868
                self._index.iter_all_entries()))
0.254.3 by John Arbash Meinel
Add repack function.
869
        to_remove = []
0.254.43 by Jelmer Vernooij
Merge trunk.
870
        for name in self._transport.list_dir('.'):
0.254.3 by John Arbash Meinel
Add repack function.
871
            if name.endswith('.rix'):
872
                to_remove.append(name)
873
        self.commit_write_group()
874
        del self._index.indices[1:]
875
        for name in to_remove:
0.254.43 by Jelmer Vernooij
Merge trunk.
876
            self._transport.rename(name, name + '.old')
0.254.3 by John Arbash Meinel
Add repack function.
877
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
878
    def start_write_group(self):
0.361.1 by Jelmer Vernooij
Don't use assert.
879
        if self._builder is not None:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
880
            raise bzr_errors.BzrError('builder already open')
0.254.36 by Jelmer Vernooij
Merge trunk.
881
        self._builder = _mod_btree_index.BTreeBuilder(0, key_elements=3)
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
882
        self._name = osutils.sha()
883
884
    def commit_write_group(self):
0.361.1 by Jelmer Vernooij
Don't use assert.
885
        if self._builder is None:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
886
            raise bzr_errors.BzrError('builder not open')
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
887
        stream = self._builder.finish()
0.254.2 by jelmer
use btree indexes
888
        name = self._name.hexdigest() + ".rix"
0.254.43 by Jelmer Vernooij
Merge trunk.
889
        size = self._transport.put_file(name, stream)
890
        index = _mod_btree_index.BTreeGraphIndex(self._transport, name, size)
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
891
        self._index.insert_index(0, index)
892
        self._builder = None
893
        self._name = None
894
895
    def abort_write_group(self):
0.361.1 by Jelmer Vernooij
Don't use assert.
896
        if self._builder is None:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
897
            raise bzr_errors.BzrError('builder not open')
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
898
        self._builder = None
899
        self._name = None
900
0.254.15 by Jelmer Vernooij
Convenience function for adding index nodes.
901
    def _add_node(self, key, value):
902
        try:
0.425.1 by Jelmer Vernooij
Add really basic check implementation.
903
            self._get_entry(key)
904
        except KeyError:
0.254.15 by Jelmer Vernooij
Convenience function for adding index nodes.
905
            self._builder.add_node(key, value)
0.425.1 by Jelmer Vernooij
Add really basic check implementation.
906
            return False
907
        else:
0.254.26 by Jelmer Vernooij
Fix typo, cope with invalid shamaps a bit better.
908
            return True
0.254.15 by Jelmer Vernooij
Convenience function for adding index nodes.
909
0.254.2 by jelmer
use btree indexes
910
    def _get_entry(self, key):
911
        entries = self._index.iter_entries([key])
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
912
        try:
6973.10.5 by Jelmer Vernooij
Fix use of .next.
913
            return next(entries)[2]
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
914
        except StopIteration:
0.254.2 by jelmer
use btree indexes
915
            if self._builder is None:
916
                raise KeyError
917
            entries = self._builder.iter_entries([key])
918
            try:
6973.10.5 by Jelmer Vernooij
Fix use of .next.
919
                return next(entries)[2]
0.254.2 by jelmer
use btree indexes
920
            except StopIteration:
921
                raise KeyError
922
0.261.2 by Jelmer Vernooij
Fix cache tests.
923
    def _iter_entries_prefix(self, prefix):
0.254.2 by jelmer
use btree indexes
924
        for entry in self._index.iter_entries_prefix([prefix]):
0.261.2 by Jelmer Vernooij
Fix cache tests.
925
            yield (entry[1], entry[2])
0.254.2 by jelmer
use btree indexes
926
        if self._builder is not None:
927
            for entry in self._builder.iter_entries_prefix([prefix]):
0.261.2 by Jelmer Vernooij
Fix cache tests.
928
                yield (entry[1], entry[2])
0.254.2 by jelmer
use btree indexes
929
930
    def lookup_commit(self, revid):
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
931
        return self._get_entry((b"commit", revid, b"X"))[:40]
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
932
0.254.33 by Jelmer Vernooij
Merge trunk.
933
    def _add_git_sha(self, hexsha, type, type_data):
0.254.2 by jelmer
use btree indexes
934
        if hexsha is not None:
935
            self._name.update(hexsha)
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
936
            if type == b"commit":
0.200.1179 by Jelmer Vernooij
Avoid using verifiers for natively imported revisions, save a lot of time.
937
                td = (type_data[0], type_data[1])
938
                try:
939
                    td += (type_data[2]["testament3-sha1"],)
940
                except KeyError:
941
                    pass
0.200.1029 by Jelmer Vernooij
Use dictionary with verifiers rather than requiring testament3-sha1 everywhere.
942
            else:
943
                td = type_data
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
944
            self._add_node((b"git", hexsha, b"X"), b" ".join((type,) + td))
0.254.2 by jelmer
use btree indexes
945
        else:
946
            # This object is not represented in Git - perhaps an empty
947
            # directory?
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
948
            self._name.update(type + b" ".join(type_data))
0.254.33 by Jelmer Vernooij
Merge trunk.
949
0.254.42 by Jelmer Vernooij
Merge trunk.
950
    def lookup_blob_id(self, fileid, revision):
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
951
        return self._get_entry((b"blob", fileid, revision))
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
952
953
    def lookup_git_sha(self, sha):
954
        if len(sha) == 20:
955
            sha = sha_to_hex(sha)
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
956
        value = self._get_entry((b"git", sha, b"X"))
957
        data = value.split(b" ", 3)
958
        if data[0] == b"commit":
0.425.1 by Jelmer Vernooij
Add really basic check implementation.
959
            try:
960
                if data[3]:
961
                    verifiers = {"testament3-sha1": data[3]}
962
                else:
963
                    verifiers = {}
964
            except IndexError:
0.422.1 by Jelmer Vernooij
Remove content caching, fix index.
965
                verifiers = {}
966
            yield ("commit", (data[1], data[2], verifiers))
967
        else:
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
968
            yield (data[0].decode('ascii'), tuple(data[1:]))
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
969
970
    def revids(self):
971
        """List the revision ids known."""
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
972
        for key, value in self._iter_entries_prefix((b"commit", None, None)):
0.254.2 by jelmer
use btree indexes
973
            yield key[1]
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
974
0.254.21 by Jelmer Vernooij
Implement faster missing_revisions.
975
    def missing_revisions(self, revids):
976
        """Return set of all the revisions that are not present."""
977
        missing_revids = set(revids)
978
        for _, key, value in self._index.iter_entries((
7143.15.2 by Jelmer Vernooij
Run autopep8.
979
                (b"commit", revid, b"X") for revid in revids)):
0.254.21 by Jelmer Vernooij
Implement faster missing_revisions.
980
            missing_revids.remove(key[1])
981
        return missing_revids
982
0.254.1 by Jelmer Vernooij
Add trivial index-based sha map.
983
    def sha1s(self):
984
        """List the SHA1s."""
6973.13.7 by Jelmer Vernooij
Fix remaining git cache tests.
985
        for key, value in self._iter_entries_prefix((b"git", None, None)):
0.254.2 by jelmer
use btree indexes
986
            yield key[1]
0.254.19 by Jelmer Vernooij
Support upgrading sha maps.
987
988
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
989
formats = registry.Registry()
990
formats.register(TdbGitCacheFormat().get_format_string(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
991
                 TdbGitCacheFormat())
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
992
formats.register(SqliteGitCacheFormat().get_format_string(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
993
                 SqliteGitCacheFormat())
0.254.43 by Jelmer Vernooij
Merge trunk.
994
formats.register(IndexGitCacheFormat().get_format_string(),
7143.15.2 by Jelmer Vernooij
Run autopep8.
995
                 IndexGitCacheFormat())
0.200.951 by Jelmer Vernooij
merge support for git object store-based caching mechanism.
996
# In the future, this will become the default:
0.425.1 by Jelmer Vernooij
Add really basic check implementation.
997
formats.register('default', IndexGitCacheFormat())
0.200.951 by Jelmer Vernooij
merge support for git object store-based caching mechanism.
998
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
999
1000
def migrate_ancient_formats(repo_transport):
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
1001
    # Migrate older cache formats
1002
    repo_transport = remove_readonly_transport_decorator(repo_transport)
1003
    has_sqlite = repo_transport.has("git.db")
1004
    has_tdb = repo_transport.has("git.tdb")
1005
    if not has_sqlite or has_tdb:
1006
        return
1007
    try:
1008
        repo_transport.mkdir("git")
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
1009
    except bzr_errors.FileExists:
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
1010
        return
7143.15.2 by Jelmer Vernooij
Run autopep8.
1011
    # Prefer migrating git.db over git.tdb, since the latter may not
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
1012
    # be openable on some platforms.
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
1013
    if has_sqlite:
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
1014
        SqliteGitCacheFormat().initialize(repo_transport.clone("git"))
1015
        repo_transport.rename("git.db", "git/idmap.db")
0.200.1221 by Jelmer Vernooij
Support cache for non-local transport properly.
1016
    elif has_tdb:
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
1017
        TdbGitCacheFormat().initialize(repo_transport.clone("git"))
1018
        repo_transport.rename("git.tdb", "git/idmap.tdb")
1019
1020
0.200.865 by Jelmer Vernooij
Support serving without --allow-writes.
1021
def remove_readonly_transport_decorator(transport):
1022
    if transport.is_readonly():
0.200.1438 by Jelmer Vernooij
Cope with remote branches not being readonly at all better.
1023
        try:
1024
            return transport._decorated
1025
        except AttributeError:
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
1026
            raise bzr_errors.ReadOnlyError(transport)
0.200.865 by Jelmer Vernooij
Support serving without --allow-writes.
1027
    return transport
1028
1029
0.254.19 by Jelmer Vernooij
Support upgrading sha maps.
1030
def from_repository(repository):
0.200.866 by Jelmer Vernooij
More docstrings, prefer migrating git.db to migrating git.tdb.
1031
    """Open a cache file for a repository.
1032
1033
    If the repository is remote and there is no transport available from it
1034
    this will use a local file in the users cache directory
1035
    (typically ~/.cache/bazaar/git/)
1036
1037
    :param repository: A repository object
1038
    """
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
1039
    repo_transport = getattr(repository, "_transport", None)
1040
    if repo_transport is not None:
0.200.1438 by Jelmer Vernooij
Cope with remote branches not being readonly at all better.
1041
        try:
1042
            migrate_ancient_formats(repo_transport)
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
1043
        except bzr_errors.ReadOnlyError:
7143.15.2 by Jelmer Vernooij
Run autopep8.
1044
            pass  # Not much we can do
0.200.844 by Jelmer Vernooij
Add infrastructure for multiple cache formats.
1045
    return BzrGitCacheFormat.from_repository(repository)