/brz/remove-bazaar

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

« back to all changes in this revision

Viewing changes to cache.py

More work on roundtrip push support.

Show diffs side-by-side

added added

removed removed

Lines of Context:
54
54
    return ret
55
55
 
56
56
 
57
 
def get_remote_cache_transport(repository):
 
57
def get_remote_cache_transport():
58
58
    """Retrieve the transport to use when accessing (unwritable) remote 
59
59
    repositories.
60
60
    """
61
 
    uuid = getattr(repository, "uuid", None)
62
 
    if uuid is None:
63
 
        path = get_cache_dir()
64
 
    else:
65
 
        path = os.path.join(get_cache_dir(), uuid)
66
 
        if not os.path.isdir(path):
67
 
            os.mkdir(path)
68
 
    return get_transport(path)
 
61
    return get_transport(get_cache_dir())
69
62
 
70
63
 
71
64
def check_pysqlite_version(sqlite3):
107
100
    def lookup_git_sha(self, sha):
108
101
        """Lookup a Git sha in the database.
109
102
        :param sha: Git object sha
110
 
        :return: list with (type, type_data) tuples with type_data:
 
103
        :return: (type, type_data) with type_data:
111
104
            commit: revid, tree_sha, verifiers
112
105
            blob: fileid, revid
113
106
            tree: fileid, revid
127
120
        """
128
121
        raise NotImplementedError(self.lookup_tree_id)
129
122
 
130
 
    def lookup_commit(self, revid):
131
 
        """Retrieve a Git commit SHA by Bazaar revision id.
132
 
        """
133
 
        raise NotImplementedError(self.lookup_commit)
134
 
 
135
123
    def revids(self):
136
124
        """List the revision ids known."""
137
125
        raise NotImplementedError(self.revids)
215
203
        :param repository: Repository to open the cache for
216
204
        :return: A `BzrGitCache`
217
205
        """
218
 
        from bzrlib.transport.local import LocalTransport
219
206
        repo_transport = getattr(repository, "_transport", None)
220
 
        if repo_transport is not None and isinstance(repo_transport, LocalTransport):
221
 
            # Even if we don't write to this repo, we should be able
 
207
        if repo_transport is not None:
 
208
            # Even if we don't write to this repo, we should be able 
222
209
            # to update its cache.
223
210
            repo_transport = remove_readonly_transport_decorator(repo_transport)
224
211
            try:
227
214
                pass
228
215
            transport = repo_transport.clone('git')
229
216
        else:
230
 
            transport = get_remote_cache_transport(repository)
 
217
            transport = get_remote_cache_transport()
231
218
        return cls.from_transport(transport)
232
219
 
233
220
 
280
267
        if obj.type_name == "commit":
281
268
            self._commit = obj
282
269
            assert type(ie) is dict
283
 
            key = self.revid
284
270
            type_data = (self.revid, self._commit.tree, ie)
285
271
            self.cache.idmap._by_revid[self.revid] = obj.id
286
272
        elif obj.type_name in ("blob", "tree"):
289
275
                    revision = ie.revision
290
276
                else:
291
277
                    revision = self.revid
292
 
                key = type_data = (ie.file_id, revision)
 
278
                type_data = (ie.file_id, revision)
293
279
                self.cache.idmap._by_fileid.setdefault(type_data[1], {})[type_data[0]] = obj.id
294
280
        else:
295
281
            raise AssertionError
296
 
        entry = (obj.type_name, type_data)
297
 
        self.cache.idmap._by_sha.setdefault(obj.id, {})[key] = entry
 
282
        self.cache.idmap._by_sha[obj.id] = (obj.type_name, type_data)
298
283
 
299
284
    def finish(self):
300
285
        if self._commit is None:
314
299
        return self._by_fileid[revision][fileid]
315
300
 
316
301
    def lookup_git_sha(self, sha):
317
 
        for entry in self._by_sha[sha].itervalues():
318
 
            yield entry
 
302
        return self._by_sha[sha]
319
303
 
320
304
    def lookup_tree_id(self, fileid, revision):
321
305
        return self._by_fileid[revision][fileid]
324
308
        return self._by_revid[revid]
325
309
 
326
310
    def revids(self):
327
 
        for key, entries in self._by_sha.iteritems():
328
 
            for (type, type_data) in entries.values():
329
 
                if type == "commit":
330
 
                    yield type_data[0]
 
311
        for key, (type, type_data) in self._by_sha.iteritems():
 
312
            if type == "commit":
 
313
                yield type_data[0]
331
314
 
332
315
    def sha1s(self):
333
316
        return self._by_sha.iterkeys()
346
329
    def add_object(self, obj, ie, path):
347
330
        if obj.type_name == "commit":
348
331
            self._commit = obj
349
 
            self._testament3_sha1 = ie.get("testament3-sha1")
 
332
            self._testament3_sha1 = ie["testament3-sha1"]
350
333
            assert type(ie) is dict
351
334
        elif obj.type_name == "tree":
352
335
            if ie is not None:
464
447
            tree: fileid, revid
465
448
            blob: fileid, revid
466
449
        """
467
 
        found = False
468
 
        cursor = self.db.execute("select revid, tree_sha, testament3_sha1 from commits where sha1 = ?", (sha,))
469
 
        for row in cursor.fetchall():
470
 
            found = True
471
 
            if row[2] is not None:
472
 
                verifiers = {"testament3-sha1": row[2]}
473
 
            else:
474
 
                verifiers = {}
475
 
            yield ("commit", (row[0], row[1], verifiers))
476
 
        cursor = self.db.execute("select fileid, revid from blobs where sha1 = ?", (sha,))
477
 
        for row in cursor.fetchall():
478
 
            found = True
479
 
            yield ("blob", row)
480
 
        cursor = self.db.execute("select fileid, revid from trees where sha1 = ?", (sha,))
481
 
        for row in cursor.fetchall():
482
 
            found = True
483
 
            yield ("tree", row)
484
 
        if not found:
485
 
            raise KeyError(sha)
 
450
        row = self.db.execute("select revid, tree_sha, testament3_sha1 from commits where sha1 = ?", (sha,)).fetchone()
 
451
        if row is not None:
 
452
            return ("commit", (row[0], row[1], {"testament3-sha1": row[2]}))
 
453
        row = self.db.execute("select fileid, revid from blobs where sha1 = ?", (sha,)).fetchone()
 
454
        if row is not None:
 
455
            return ("blob", row)
 
456
        row = self.db.execute("select fileid, revid from trees where sha1 = ?", (sha,)).fetchone()
 
457
        if row is not None:
 
458
            return ("tree", row)
 
459
        raise KeyError(sha)
486
460
 
487
461
    def revids(self):
488
462
        """List the revision ids known."""
511
485
        if obj.type_name == "commit":
512
486
            self.db["commit\0" + self.revid] = "\0".join((sha, obj.tree))
513
487
            assert type(ie) is dict, "was %r" % ie
514
 
            type_data = (self.revid, obj.tree)
515
 
            try:
516
 
                type_data += (ie["testament3-sha1"],)
517
 
            except KeyError:
518
 
                pass
 
488
            type_data = (self.revid, obj.tree, ie["testament3-sha1"])
519
489
            self._commit = obj
520
490
        elif obj.type_name == "blob":
521
491
            if ie is None:
528
498
            type_data = (ie.file_id, self.revid)
529
499
        else:
530
500
            raise AssertionError
531
 
        entry = "\0".join((obj.type_name, ) + type_data) + "\n"
532
 
        key = "git\0" + sha
533
 
        try:
534
 
            oldval = self.db[key]
535
 
        except KeyError:
536
 
            self.db[key] = entry
537
 
        else:
538
 
            if oldval[-1] != "\n":
539
 
                self.db[key] = "".join([oldval, "\n", entry])
540
 
            else:
541
 
                self.db[key] = "".join([oldval, entry])
 
501
        self.db["git\0" + sha] = "\0".join((obj.type_name, ) + type_data)
542
502
 
543
503
    def finish(self):
544
504
        if self._commit is None:
548
508
 
549
509
TdbBzrGitCache = lambda p: BzrGitCache(TdbGitShaMap(p), None, TdbCacheUpdater)
550
510
 
551
 
 
552
511
class TdbGitCacheFormat(BzrGitCacheFormat):
553
512
    """Cache format for tdb-based caches."""
554
513
 
557
516
 
558
517
    def open(self, transport):
559
518
        try:
560
 
            basepath = transport.local_abspath(".").encode(osutils._fs_enc)
 
519
            basepath = transport.local_abspath(".")
561
520
        except bzrlib.errors.NotLocalUrl:
562
521
            basepath = get_cache_dir()
563
 
        assert isinstance(basepath, str)
564
522
        try:
565
523
            return TdbBzrGitCache(os.path.join(basepath, "idmap.tdb"))
566
524
        except ImportError:
589
547
        if path is None:
590
548
            self.db = {}
591
549
        else:
592
 
            assert isinstance(path, str)
593
550
            if not mapdbs().has_key(path):
594
551
                mapdbs()[path] = tdb.Tdb(path, self.TDB_HASH_SIZE, tdb.DEFAULT,
595
552
                                          os.O_RDWR|os.O_CREAT)
635
592
        """
636
593
        if len(sha) == 40:
637
594
            sha = hex_to_sha(sha)
638
 
        value = self.db["git\0" + sha]
639
 
        for data in value.splitlines():
640
 
            data = data.split("\0")
641
 
            if data[0] == "commit":
642
 
                if len(data) == 3:
643
 
                    yield (data[0], (data[1], data[2], {}))
644
 
                else:
645
 
                    yield (data[0], (data[1], data[2], {"testament3-sha1": data[3]}))
646
 
            elif data[0] in ("tree", "blob"):
647
 
                yield (data[0], tuple(data[1:]))
 
595
        data = self.db["git\0" + sha].split("\0")
 
596
        if data[0] == "commit":
 
597
            if len(data) == 3:
 
598
                return (data[0], (data[1], data[2], {}))
648
599
            else:
649
 
                raise AssertionError("unknown type %r" % data[0])
 
600
                return (data[0], (data[1], data[2], {"testament3-sha1": data[3]}))
 
601
        else:
 
602
            return (data[0], tuple(data[1:]))
650
603
 
651
604
    def missing_revisions(self, revids):
652
605
        ret = set()
869
822
            except StopIteration:
870
823
                raise KeyError
871
824
 
872
 
    def _iter_entries_prefix(self, prefix):
 
825
    def _iter_keys_prefix(self, prefix):
873
826
        for entry in self._index.iter_entries_prefix([prefix]):
874
 
            yield (entry[1], entry[2])
 
827
            yield entry[1]
875
828
        if self._builder is not None:
876
829
            for entry in self._builder.iter_entries_prefix([prefix]):
877
 
                yield (entry[1], entry[2])
 
830
                yield entry[1]
878
831
 
879
832
    def lookup_commit(self, revid):
880
833
        return self._get_entry(("commit", revid, "X"))[:40]
883
836
        if hexsha is not None:
884
837
            self._name.update(hexsha)
885
838
            if type == "commit":
886
 
                td = (type_data[0], type_data[1])
887
 
                try:
888
 
                    td += (type_data[2]["testament3-sha1"],)
889
 
                except KeyError:
890
 
                    pass
 
839
                td = (type_data[0], type_data[1], type_data[2]["testament3-sha1"])
891
840
            else:
892
841
                td = type_data
893
842
            self._add_node(("git", hexsha, "X"), " ".join((type,) + td))
902
851
    def lookup_git_sha(self, sha):
903
852
        if len(sha) == 20:
904
853
            sha = sha_to_hex(sha)
905
 
        found = False
906
 
        for key, value in self._iter_entries_prefix(("git", sha, None)):
907
 
            found = True
908
 
            data = value.split(" ", 3)
909
 
            if data[0] == "commit":
910
 
                if data[3]:
911
 
                    verifiers = {"testament3-sha1": data[3]}
912
 
                else:
913
 
                    verifiers = {}
914
 
                yield ("commit", (data[1], data[2], verifiers))
915
 
            else:
916
 
                yield (data[0], tuple(data[1:]))
917
 
        if not found:
918
 
            raise KeyError(sha)
 
854
        data = self._get_entry(("git", sha, "X")).split(" ", 3)
 
855
        if data[0] == "commit":
 
856
            return ("commit", (data[1], data[2], {"testament3-sha1": data[3]}))
 
857
        else:
 
858
            return (data[0], tuple(data[1:]))
919
859
 
920
860
    def revids(self):
921
861
        """List the revision ids known."""
922
 
        for key, value in self._iter_entries_prefix(("commit", None, None)):
 
862
        for key in self._iter_keys_prefix(("commit", None, None)):
923
863
            yield key[1]
924
864
 
925
865
    def missing_revisions(self, revids):
932
872
 
933
873
    def sha1s(self):
934
874
        """List the SHA1s."""
935
 
        for key, value in self._iter_entries_prefix(("git", None, None)):
 
875
        for key in self._iter_keys_prefix(("git", None, None)):
936
876
            yield key[1]
937
877
 
938
878
 
955
895
 
956
896
 
957
897
def migrate_ancient_formats(repo_transport):
958
 
    # Migrate older cache formats
959
 
    repo_transport = remove_readonly_transport_decorator(repo_transport)
960
 
    has_sqlite = repo_transport.has("git.db")
961
 
    has_tdb = repo_transport.has("git.tdb")
962
 
    if not has_sqlite or has_tdb:
963
 
        return
964
 
    try:
965
 
        repo_transport.mkdir("git")
966
 
    except bzrlib.errors.FileExists:
967
 
        return
968
898
    # Prefer migrating git.db over git.tdb, since the latter may not 
969
899
    # be openable on some platforms.
970
 
    if has_sqlite:
 
900
    if repo_transport.has("git.db"):
971
901
        SqliteGitCacheFormat().initialize(repo_transport.clone("git"))
972
902
        repo_transport.rename("git.db", "git/idmap.db")
973
 
    elif has_tdb:
 
903
    elif repo_transport.has("git.tdb"):
974
904
        TdbGitCacheFormat().initialize(repo_transport.clone("git"))
975
905
        repo_transport.rename("git.tdb", "git/idmap.tdb")
976
906
 
992
922
    """
993
923
    repo_transport = getattr(repository, "_transport", None)
994
924
    if repo_transport is not None:
995
 
        migrate_ancient_formats(repo_transport)
 
925
        # Migrate older cache formats
 
926
        repo_transport = remove_readonly_transport_decorator(repo_transport)
 
927
        try:
 
928
            repo_transport.mkdir("git")
 
929
        except bzrlib.errors.FileExists:
 
930
            pass
 
931
        else:
 
932
            migrate_ancient_formats(repo_transport)
996
933
    return BzrGitCacheFormat.from_repository(repository)