/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.200.252 by Jelmer Vernooij
Clarify history, copyright.
1
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
"""Map from Git sha's to Bazaar objects."""
18
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
19
from dulwich.objects import (
20
    sha_to_hex,
21
    hex_to_sha,
22
    )
0.200.292 by Jelmer Vernooij
Fix formatting.
23
import os
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
24
import threading
0.200.292 by Jelmer Vernooij
Fix formatting.
25
0.200.228 by Jelmer Vernooij
Split out map.
26
import bzrlib
0.200.528 by Jelmer Vernooij
Fix import.
27
from bzrlib import (
28
    trace,
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
29
    ui,
0.200.528 by Jelmer Vernooij
Fix import.
30
    )
0.200.230 by Jelmer Vernooij
Implement sha cache.
31
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
32
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
33
def get_cache_dir():
34
    try:
35
        from xdg.BaseDirectory import xdg_cache_home
36
    except ImportError:
0.200.558 by Jelmer Vernooij
Create cache dir if it doesn't exist yet.
37
        from bzrlib.config import config_dir
38
        ret = os.path.join(config_dir(), "git")
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
39
    else:
0.200.558 by Jelmer Vernooij
Create cache dir if it doesn't exist yet.
40
        ret = os.path.join(xdg_cache_home, "bazaar", "git")
41
    if not os.path.isdir(ret):
42
        os.makedirs(ret)
43
    return ret
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
44
45
0.200.228 by Jelmer Vernooij
Split out map.
46
def check_pysqlite_version(sqlite3):
47
    """Check that sqlite library is compatible.
48
49
    """
0.200.675 by Jelmer Vernooij
Fix formatting.
50
    if (sqlite3.sqlite_version_info[0] < 3 or
51
            (sqlite3.sqlite_version_info[0] == 3 and
0.200.228 by Jelmer Vernooij
Split out map.
52
             sqlite3.sqlite_version_info[1] < 3)):
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
53
        trace.warning('Needs at least sqlite 3.3.x')
0.200.228 by Jelmer Vernooij
Split out map.
54
        raise bzrlib.errors.BzrError("incompatible sqlite library")
55
56
try:
57
    try:
58
        import sqlite3
59
        check_pysqlite_version(sqlite3)
0.200.675 by Jelmer Vernooij
Fix formatting.
60
    except (ImportError, bzrlib.errors.BzrError), e:
0.200.228 by Jelmer Vernooij
Split out map.
61
        from pysqlite2 import dbapi2 as sqlite3
62
        check_pysqlite_version(sqlite3)
63
except:
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
64
    trace.warning('Needs at least Python2.5 or Python2.4 with the pysqlite2 '
0.200.228 by Jelmer Vernooij
Split out map.
65
            'module')
66
    raise bzrlib.errors.BzrError("missing sqlite library")
67
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
68
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
69
_mapdbs = threading.local()
70
def mapdbs():
71
    """Get a cache for this thread's db connections."""
72
    try:
73
        return _mapdbs.cache
74
    except AttributeError:
75
        _mapdbs.cache = {}
76
        return _mapdbs.cache
77
78
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
79
class GitShaMap(object):
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
80
    """Git<->Bzr revision id mapping database."""
81
82
    def add_entry(self, sha, type, type_data):
83
        """Add a new entry to the database.
84
        """
85
        raise NotImplementedError(self.add_entry)
86
0.200.361 by Jelmer Vernooij
Fix existing object lookup issues when pulling from remote branches.
87
    def add_entries(self, entries):
88
        """Add multiple new entries to the database.
89
        """
90
        for e in entries:
91
            self.add_entry(*e)
92
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
93
    def lookup_blob(self, fileid, revid):
0.200.752 by Jelmer Vernooij
Actually use shagitmap again to look up trees.
94
        """Lookup a blob by the fileid it has in a bzr revision.
95
        
96
        :param fileid: File id of the file
97
        :param revid: Revision in which the file was changed
98
        :return: SHA1
99
        """
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
100
        raise NotImplementedError(self.lookup_blob)
101
0.200.752 by Jelmer Vernooij
Actually use shagitmap again to look up trees.
102
    def lookup_tree(self, fileid, revid):
103
        """Lookup a blob by the fileid it has in a bzr revision.
104
        
105
        :param fileid: File id of the file
106
        :param revid: Revision for which to find the tree
107
        :return: SHA1
108
        """
109
        raise NotImplementedError(self.lookup_tree)
110
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
111
    def lookup_git_sha(self, sha):
112
        """Lookup a Git sha in the database.
113
114
        :param sha: Git object sha
115
        :return: (type, type_data) with type_data:
116
            revision: revid, tree sha
117
        """
118
        raise NotImplementedError(self.lookup_git_sha)
119
120
    def revids(self):
121
        """List the revision ids known."""
122
        raise NotImplementedError(self.revids)
123
0.200.677 by Jelmer Vernooij
Implement TdbCache.missing_revisions().
124
    def missing_revisions(self, revids):
125
        """Return set of all the revisions that are not present."""
126
        present_revids = set(self.revids())
127
        if not isinstance(revids, set):
128
            revids = set(revids)
129
        return revids - present_revids
130
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
131
    def sha1s(self):
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
132
        """List the SHA1s."""
133
        raise NotImplementedError(self.sha1s)
134
0.200.687 by Jelmer Vernooij
Use start_write_group() / commit_write_group() mechanism when creating git SHA maps.
135
    def start_write_group(self):
136
        """Start writing changes."""
137
138
    def commit_write_group(self):
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
139
        """Commit any pending changes."""
140
0.200.687 by Jelmer Vernooij
Use start_write_group() / commit_write_group() mechanism when creating git SHA maps.
141
    def abort_write_group(self):
142
        """Abort any pending changes."""
143
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
144
145
class DictGitShaMap(GitShaMap):
146
147
    def __init__(self):
148
        self.dict = {}
149
150
    def add_entry(self, sha, type, type_data):
151
        self.dict[sha] = (type, type_data)
152
153
    def lookup_git_sha(self, sha):
154
        return self.dict[sha]
155
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
156
    def lookup_blob(self, fileid, revid):
157
        for k, v in self.dict.iteritems():
158
            if v == ("blob", (fileid, revid)):
159
                return k
160
        raise KeyError((fileid, revid))
161
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
162
    def revids(self):
163
        for key, (type, type_data) in self.dict.iteritems():
164
            if type == "commit":
0.200.262 by Jelmer Vernooij
Add tests for GitShaMap.
165
                yield type_data[0]
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
166
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
167
    def sha1s(self):
168
        return self.dict.iterkeys()
169
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
170
171
class SqliteGitShaMap(GitShaMap):
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
172
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
173
    def __init__(self, path=None):
174
        self.path = path
175
        if path is None:
0.200.262 by Jelmer Vernooij
Add tests for GitShaMap.
176
            self.db = sqlite3.connect(":memory:")
177
        else:
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
178
            if not mapdbs().has_key(path):
179
                mapdbs()[path] = sqlite3.connect(path)
0.200.675 by Jelmer Vernooij
Fix formatting.
180
            self.db = mapdbs()[path]
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
181
        self.db.text_factory = str
0.200.230 by Jelmer Vernooij
Implement sha cache.
182
        self.db.executescript("""
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
183
        create table if not exists commits(
184
            sha1 text not null check(length(sha1) == 40),
185
            revid text not null,
186
            tree_sha text not null check(length(tree_sha) == 40)
187
        );
0.200.230 by Jelmer Vernooij
Implement sha cache.
188
        create index if not exists commit_sha1 on commits(sha1);
0.200.284 by Jelmer Vernooij
Add extra indexes.
189
        create unique index if not exists commit_revid on commits(revid);
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
190
        create table if not exists blobs(
191
            sha1 text not null check(length(sha1) == 40),
192
            fileid text not null,
193
            revid text not null
194
        );
0.200.230 by Jelmer Vernooij
Implement sha cache.
195
        create index if not exists blobs_sha1 on blobs(sha1);
0.200.284 by Jelmer Vernooij
Add extra indexes.
196
        create unique index if not exists blobs_fileid_revid on blobs(fileid, revid);
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
197
        create table if not exists trees(
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
198
            sha1 text unique not null check(length(sha1) == 40),
0.200.691 by Jelmer Vernooij
Add extra constraints in sqlite tables.
199
            fileid text not null,
200
            revid text not null
201
        );
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
202
        create unique index if not exists trees_sha1 on trees(sha1);
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
203
        create unique index if not exists trees_fileid_revid on trees(fileid, revid);
0.200.230 by Jelmer Vernooij
Implement sha cache.
204
""")
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
205
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
206
    def __repr__(self):
207
        return "%s(%r)" % (self.__class__.__name__, self.path)
208
    
209
    @classmethod
210
    def remove_for_repository(cls, repository):
211
        repository._transport.delete('git.db')
212
213
    @classmethod
214
    def exists_for_repository(cls, repository):
215
        try:
216
            transport = getattr(repository, "_transport", None)
217
            if transport is not None:
218
                return transport.has("git.db")
219
        except bzrlib.errors.NotLocalUrl:
220
            return False
221
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
222
    @classmethod
223
    def from_repository(cls, repository):
0.200.533 by Jelmer Vernooij
Use user home dir cache when transport for sqlite cache is readonly.
224
        try:
225
            transport = getattr(repository, "_transport", None)
226
            if transport is not None:
227
                return cls(os.path.join(transport.local_abspath("."), "git.db"))
228
        except bzrlib.errors.NotLocalUrl:
229
            pass
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
230
        return cls(os.path.join(get_cache_dir(), "remote.db"))
0.200.365 by Jelmer Vernooij
Share sha map cache connections inside threads.
231
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
232
    def lookup_commit(self, revid):
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
233
        row = self.db.execute("select sha1 from commits where revid = ?", (revid,)).fetchone()
234
        if row is not None:
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
235
            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.
236
        raise KeyError
0.200.231 by Jelmer Vernooij
Partially fix pull.
237
0.200.687 by Jelmer Vernooij
Use start_write_group() / commit_write_group() mechanism when creating git SHA maps.
238
    def commit_write_group(self):
0.200.232 by Jelmer Vernooij
Fix pull from remote branches.
239
        self.db.commit()
240
0.200.377 by Jelmer Vernooij
use executemany when inserting sha map entries.
241
    def add_entries(self, entries):
242
        trees = []
243
        blobs = []
244
        for sha, type, type_data in entries:
0.200.410 by Jelmer Vernooij
Fix compatibility with python 2.4.
245
            assert isinstance(type_data[0], str)
246
            assert isinstance(type_data[1], str)
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
247
            entry = (sha, type_data[0], type_data[1])
0.200.377 by Jelmer Vernooij
use executemany when inserting sha map entries.
248
            if type == "tree":
0.200.410 by Jelmer Vernooij
Fix compatibility with python 2.4.
249
                trees.append(entry)
0.200.377 by Jelmer Vernooij
use executemany when inserting sha map entries.
250
            elif type == "blob":
0.200.410 by Jelmer Vernooij
Fix compatibility with python 2.4.
251
                blobs.append(entry)
0.200.377 by Jelmer Vernooij
use executemany when inserting sha map entries.
252
            else:
253
                raise AssertionError
254
        if trees:
255
            self.db.executemany("replace into trees (sha1, fileid, revid) values (?, ?, ?)", trees)
256
        if blobs:
257
            self.db.executemany("replace into blobs (sha1, fileid, revid) values (?, ?, ?)", blobs)
258
259
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
260
    def add_entry(self, sha, type, type_data):
261
        """Add a new entry to the database.
262
        """
0.200.231 by Jelmer Vernooij
Partially fix pull.
263
        assert isinstance(type_data, tuple)
0.200.705 by Jelmer Vernooij
Cope with imports.
264
        if sha is None:
265
            return
0.200.231 by Jelmer Vernooij
Partially fix pull.
266
        assert isinstance(sha, str), "type was %r" % sha
0.200.230 by Jelmer Vernooij
Implement sha cache.
267
        if type == "commit":
268
            self.db.execute("replace into commits (sha1, revid, tree_sha) values (?, ?, ?)", (sha, type_data[0], type_data[1]))
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
269
        elif type in ("blob", "tree"):
270
            self.db.execute("replace into %ss (sha1, fileid, revid) values (?, ?, ?)" % type, (sha, type_data[0], type_data[1]))
0.200.230 by Jelmer Vernooij
Implement sha cache.
271
        else:
272
            raise AssertionError("Unknown type %s" % type)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
273
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
274
    def lookup_blob(self, fileid, revid):
0.230.3 by Jelmer Vernooij
Fix blob lookup.
275
        row = self.db.execute("select sha1 from blobs where fileid = ? and revid = ?", (fileid, revid)).fetchone()
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
276
        if row is None:
277
            raise KeyError((fileid, revid))
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
278
        return row[0]
0.230.2 by Jelmer Vernooij
Fix versionedfiles.
279
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
280
    def lookup_git_sha(self, sha):
281
        """Lookup a Git sha in the database.
282
283
        :param sha: Git object sha
284
        :return: (type, type_data) with type_data:
285
            revision: revid, tree sha
286
        """
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
287
        def format(type, row):
0.200.688 by Jelmer Vernooij
Use str text factory rather than encoding/decoding each time.
288
            return (type, (row[0], row[1]))
0.200.230 by Jelmer Vernooij
Implement sha cache.
289
        row = self.db.execute("select revid, tree_sha from commits where sha1 = ?", (sha,)).fetchone()
290
        if row is not None:
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
291
            return format("commit", row)
0.200.230 by Jelmer Vernooij
Implement sha cache.
292
        row = self.db.execute("select fileid, revid from blobs where sha1 = ?", (sha,)).fetchone()
293
        if row is not None:
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
294
            return format("blob", row)
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
295
        row = self.db.execute("select fileid, revid from trees where sha1 = ?", (sha,)).fetchone()
0.200.230 by Jelmer Vernooij
Implement sha cache.
296
        if row is not None:
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
297
            return format("tree", row)
0.200.230 by Jelmer Vernooij
Implement sha cache.
298
        raise KeyError(sha)
299
300
    def revids(self):
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
301
        """List the revision ids known."""
0.248.7 by Jelmer Vernooij
Avoid fetching all sha1s at once.
302
        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.
303
304
    def sha1s(self):
305
        """List the SHA1s."""
306
        for table in ("blobs", "commits", "trees"):
0.248.7 by Jelmer Vernooij
Avoid fetching all sha1s at once.
307
            trace.note(table)
308
            for (row,) in self.db.execute("select sha1 from %s" % table):
309
                yield row
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
310
311
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
312
TDB_MAP_VERSION = 3
0.239.2 by Jelmer Vernooij
Increase hash size.
313
TDB_HASH_SIZE = 50000
0.200.479 by Jelmer Vernooij
Version tdb sha map.
314
315
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
316
class TdbGitShaMap(GitShaMap):
317
    """SHA Map that uses a TDB database.
318
319
    Entries:
320
0.200.476 by Jelmer Vernooij
Fix Tdb backend, use tdb if possible by default.
321
    "git <sha1>" -> "<type> <type-data1> <type-data2>"
322
    "commit revid" -> "<sha1> <tree-id>"
0.200.477 by Jelmer Vernooij
More tests for sha maps, fix cache misses in tdb.
323
    "tree fileid revid" -> "<sha1>"
324
    "blob fileid revid" -> "<sha1>"
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
325
    """
326
327
    def __init__(self, path=None):
328
        import tdb
329
        self.path = path
330
        if path is None:
331
            self.db = {}
332
        else:
333
            if not mapdbs().has_key(path):
0.200.676 by Jelmer Vernooij
Avoid iterating over all keys in the tdb database.
334
                mapdbs()[path] = tdb.Tdb(path, TDB_HASH_SIZE, tdb.DEFAULT,
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
335
                                          os.O_RDWR|os.O_CREAT)
0.200.676 by Jelmer Vernooij
Avoid iterating over all keys in the tdb database.
336
            self.db = mapdbs()[path]
337
        try:
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
338
            if int(self.db["version"]) not in (2, 3):
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
339
                trace.warning("SHA Map is incompatible (%s -> %d), rebuilding database.",
340
                              self.db["version"], TDB_MAP_VERSION)
341
                self.db.clear()
0.200.676 by Jelmer Vernooij
Avoid iterating over all keys in the tdb database.
342
        except KeyError:
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
343
            pass
344
        self.db["version"] = str(TDB_MAP_VERSION)
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
345
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
346
    def __repr__(self):
347
        return "%s(%r)" % (self.__class__.__name__, self.path)
348
349
    @classmethod
350
    def exists_for_repository(cls, repository):
351
        try:
352
            transport = getattr(repository, "_transport", None)
353
            if transport is not None:
354
                return transport.has("git.tdb")
355
        except bzrlib.errors.NotLocalUrl:
356
            return False
357
358
    @classmethod
359
    def remove_for_repository(cls, repository):
360
        repository._transport.delete('git.tdb')
361
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
362
    @classmethod
363
    def from_repository(cls, repository):
0.200.482 by Jelmer Vernooij
Use tdb file in the config dir if it's remote.
364
        try:
0.200.500 by Jelmer Vernooij
Cope with repositories that don't have a _transport attribute.
365
            transport = getattr(repository, "_transport", None)
366
            if transport is not None:
367
                return cls(os.path.join(transport.local_abspath("."), "git.tdb"))
0.200.482 by Jelmer Vernooij
Use tdb file in the config dir if it's remote.
368
        except bzrlib.errors.NotLocalUrl:
0.200.500 by Jelmer Vernooij
Cope with repositories that don't have a _transport attribute.
369
            pass
0.200.534 by Jelmer Vernooij
Use XDG cache directory if the python xdg module is available.
370
        return cls(os.path.join(get_cache_dir(), "remote.tdb"))
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
371
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
372
    def lookup_commit(self, revid):
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
373
        return sha_to_hex(self.db["commit\0" + revid][:20])
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
374
0.200.593 by Jelmer Vernooij
Avoid writing empty trees.
375
    def add_entry(self, hexsha, type, type_data):
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
376
        """Add a new entry to the database.
377
        """
0.200.593 by Jelmer Vernooij
Avoid writing empty trees.
378
        if hexsha is None:
379
            sha = ""
380
        else:
381
            sha = hex_to_sha(hexsha)
382
            self.db["git\0" + sha] = "\0".join((type, type_data[0], type_data[1]))
0.200.476 by Jelmer Vernooij
Fix Tdb backend, use tdb if possible by default.
383
        if type == "commit":
0.200.593 by Jelmer Vernooij
Avoid writing empty trees.
384
            self.db["commit\0" + type_data[0]] = "\0".join((sha, type_data[1]))
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
385
        elif type == "blob":
386
            self.db["\0".join(("blob", type_data[0], type_data[1]))] = sha
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
387
388
    def lookup_blob(self, fileid, revid):
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
389
        return sha_to_hex(self.db["\0".join(("blob", fileid, revid))])
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
390
391
    def lookup_git_sha(self, sha):
392
        """Lookup a Git sha in the database.
393
394
        :param sha: Git object sha
395
        :return: (type, type_data) with type_data:
396
            revision: revid, tree sha
397
        """
0.200.564 by Jelmer Vernooij
Accept 'binary' shas.
398
        if len(sha) == 40:
399
            sha = hex_to_sha(sha)
400
        data = self.db["git\0" + sha].split("\0")
0.200.476 by Jelmer Vernooij
Fix Tdb backend, use tdb if possible by default.
401
        return (data[0], (data[1], data[2]))
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
402
0.200.677 by Jelmer Vernooij
Implement TdbCache.missing_revisions().
403
    def missing_revisions(self, revids):
404
        ret = set()
405
        for revid in revids:
406
            if self.db.get("commit\0" + revid) is None:
407
                ret.add(revid)
408
        return ret
409
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
410
    def revids(self):
411
        """List the revision ids known."""
412
        for key in self.db.iterkeys():
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
413
            if key.startswith("commit\0"):
414
                yield key[7:]
0.200.475 by Jelmer Vernooij
Add Tdb database backend.
415
416
    def sha1s(self):
417
        """List the SHA1s."""
418
        for key in self.db.iterkeys():
0.235.1 by Jelmer Vernooij
Store sha map more efficiently.
419
            if key.startswith("git\0"):
420
                yield sha_to_hex(key[4:])
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
421
422
423
def migrate(source, target):
424
    """Migrate from one cache map to another."""
425
    pb = ui.ui_factory.nested_progress_bar()
426
    try:
427
        target.start_write_group()
428
        try:
429
            for i, sha in enumerate(source.sha1s()):
430
                pb.update("migrating sha map", i)
431
                (kind, info) = source.lookup_git_sha(sha)
432
                target.add_entry(sha, kind, info)
433
        except:
434
            target.abort_write_group()
435
            raise
436
        else:
437
            target.commit_write_group()
438
    finally:
439
        pb.finished()
440
441
442
def from_repository(repository):
0.200.751 by Jelmer Vernooij
Unrelated small fixes - import, avoid storing tree info (no longer used).
443
    upgrade_from = []
444
    try:
445
        shamap = TdbGitShaMap.from_repository(repository)
446
        upgrade_from = [SqliteGitShaMap]
447
    except ImportError:
448
        shamap = SqliteGitShaMap.from_repository(repository)
449
    for cls in upgrade_from:
0.200.750 by Jelmer Vernooij
Remove unused tree code, add mechanism for migrating between sha maps.
450
        if not cls.exists_for_repository(repository):
451
            continue
452
        old_shamap = cls.from_repository(repository)
453
        trace.info('Importing SHA map from %r into %r',
454
            old_shamap, shamap)
455
        migrate(old_shamap, shamap)
456
        cls.remove_for_repository(repository)
457
    return shamap