/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.228 by Jelmer Vernooij
Split out map.
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.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
19
from dulwich.objects import (
20
    Blob,
21
    Tree,
22
    )
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
23
from dulwich.object_store import (
0.200.457 by Jelmer Vernooij
Use BaseObjectStore.
24
    BaseObjectStore,
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
25
    ObjectStoreIterator,
26
    )
0.200.249 by Jelmer Vernooij
Implement Tree.
27
import stat
28
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
29
from bzrlib import (
0.200.440 by Jelmer Vernooij
Remove silly mapping of timezones; dulwich uses offsets now as well.
30
    debug,
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
31
    errors,
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
32
    trace,
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
33
    ui,
34
    )
0.200.541 by Jelmer Vernooij
Cope with NULL_REVISION.
35
from bzrlib.revision import (
36
    NULL_REVISION,
37
    )
0.200.228 by Jelmer Vernooij
Split out map.
38
0.200.467 by Jelmer Vernooij
Raise proper errors for ghosts.
39
from bzrlib.plugins.git.errors import (
40
    GhostRevision,
41
    )
42
0.200.229 by Jelmer Vernooij
More work on converter.
43
from bzrlib.plugins.git.mapping import (
0.200.463 by Jelmer Vernooij
Support remote dpush (except for references).
44
    default_mapping,
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
45
    directory_to_tree,
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
46
    extract_unusual_modes,
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
47
    mapping_registry,
0.200.229 by Jelmer Vernooij
More work on converter.
48
    revision_to_commit,
49
    )
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
50
from bzrlib.plugins.git.shamap import (
51
    SqliteGitShaMap,
0.200.476 by Jelmer Vernooij
Fix Tdb backend, use tdb if possible by default.
52
    TdbGitShaMap,
0.200.231 by Jelmer Vernooij
Partially fix pull.
53
    )
54
0.200.228 by Jelmer Vernooij
Split out map.
55
0.200.452 by Jelmer Vernooij
Rename converter -> object_store, provide utility function for getting ObjectStore's.
56
def get_object_store(repo, mapping=None):
57
    git = getattr(repo, "_git", None)
58
    if git is not None:
59
        return git.object_store
60
    return BazaarObjectStore(repo, mapping)
61
62
0.200.457 by Jelmer Vernooij
Use BaseObjectStore.
63
class BazaarObjectStore(BaseObjectStore):
0.200.320 by Jelmer Vernooij
Handle lightweight checkouts.
64
    """A Git-style object store backed onto a Bazaar repository."""
0.200.228 by Jelmer Vernooij
Split out map.
65
66
    def __init__(self, repository, mapping=None):
67
        self.repository = repository
68
        if mapping is None:
0.200.463 by Jelmer Vernooij
Support remote dpush (except for references).
69
            self.mapping = default_mapping
0.200.228 by Jelmer Vernooij
Split out map.
70
        else:
71
            self.mapping = mapping
0.200.476 by Jelmer Vernooij
Fix Tdb backend, use tdb if possible by default.
72
        try:
73
            self._idmap = TdbGitShaMap.from_repository(repository)
74
        except ImportError:
75
            self._idmap = SqliteGitShaMap.from_repository(repository)
0.200.228 by Jelmer Vernooij
Split out map.
76
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
77
    def _update_sha_map(self, stop_revision=None):
78
        if stop_revision is None:
79
            all_revids = self.repository.all_revision_ids()
80
        else:
81
            all_revids = self.repository.get_ancestry(stop_revision)
82
            first = all_revids.pop(0) # Pop leading None
83
            assert first is None
0.200.231 by Jelmer Vernooij
Partially fix pull.
84
        graph = self.repository.get_graph()
0.200.230 by Jelmer Vernooij
Implement sha cache.
85
        present_revids = set(self._idmap.revids())
0.200.347 by Jelmer Vernooij
Simplify converter a bit.
86
        missing_revids = [revid for revid in graph.iter_topo_order(all_revids) if revid not in present_revids]
0.200.231 by Jelmer Vernooij
Partially fix pull.
87
        pb = ui.ui_factory.nested_progress_bar()
88
        try:
0.200.347 by Jelmer Vernooij
Simplify converter a bit.
89
            for i, revid in enumerate(missing_revids):
90
                pb.update("updating git map", i, len(missing_revids))
0.200.231 by Jelmer Vernooij
Partially fix pull.
91
                self._update_sha_map_revision(revid)
92
        finally:
0.200.232 by Jelmer Vernooij
Fix pull from remote branches.
93
            self._idmap.commit()
0.200.231 by Jelmer Vernooij
Partially fix pull.
94
            pb.finished()
0.200.229 by Jelmer Vernooij
More work on converter.
95
0.200.422 by Jelmer Vernooij
'bzr git-object' without arguments now prints the available git objects.
96
    def __iter__(self):
97
        self._update_sha_map()
98
        return iter(self._idmap.sha1s())
99
0.200.229 by Jelmer Vernooij
More work on converter.
100
    def _update_sha_map_revision(self, revid):
101
        inv = self.repository.get_inventory(revid)
102
        rev = self.repository.get_revision(revid)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
103
        unusual_modes = extract_unusual_modes(rev)
104
        tree_sha = self._get_ie_sha1(inv.root, inv, unusual_modes)
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
105
        commit_obj = revision_to_commit(rev, tree_sha,
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
106
                                        self._idmap.lookup_commit)
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
107
        try:
108
            foreign_revid, mapping = mapping_registry.parse_revision_id(revid)
109
        except errors.InvalidRevisionId:
110
            pass
111
        else:
112
            if foreign_revid != commit_obj.id:
0.200.440 by Jelmer Vernooij
Remove silly mapping of timezones; dulwich uses offsets now as well.
113
                if not "fix-shamap" in debug.debug_flags:
114
                    raise AssertionError("recreated git commit had different sha1: expected %s, got %s" % (foreign_revid, commit_obj.id))
0.231.1 by Jelmer Vernooij
Check that regenerated objects have the expected sha1.
115
        self._idmap.add_entry(commit_obj.id, "commit", (revid, tree_sha))
0.200.229 by Jelmer Vernooij
More work on converter.
116
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
117
    def _check_expected_sha(self, expected_sha, object):
118
        if expected_sha is None:
119
            return
120
        if expected_sha != object.id:
121
            raise AssertionError("Invalid sha for %r: %s" % (object, expected_sha))
122
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
123
    def _get_ie_object(self, entry, inv, unusual_modes):  
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
124
        if entry.kind == "directory":
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
125
            return self._get_tree(entry.file_id, inv.revision_id, inv, unusual_modes)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
126
        else:
127
            return self._get_blob(entry.file_id, entry.revision)
128
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
129
    def _get_ie_object_or_sha1(self, entry, inv, unusual_modes):
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
130
        if entry.kind == "directory":
131
            try:
132
                return self._idmap.lookup_tree(entry.file_id, inv.revision_id), None
133
            except KeyError:
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
134
                ret = self._get_ie_object(entry, inv, unusual_modes)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
135
                self._idmap.add_entry(ret.id, "tree", (entry.file_id, inv.revision_id))
136
                return ret.id, ret
137
        else:
138
            try:
139
                return self._idmap.lookup_blob(entry.file_id, entry.revision), None
140
            except KeyError:
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
141
                ret = self._get_ie_object(entry, inv, unusual_modes)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
142
                self._idmap.add_entry(ret.id, "blob", (entry.file_id, entry.revision))
143
                return ret.id, ret
144
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
145
    def _get_ie_sha1(self, entry, inv, unusual_modes):
146
        return self._get_ie_object_or_sha1(entry, inv, unusual_modes)[0]
0.200.359 by Jelmer Vernooij
Simplify file mode handling, avoid inventory_to_tree_and_blobs as it is expensive if trees/blobs have already been converted.
147
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
148
    def _get_blob(self, fileid, revision, expected_sha=None):
0.200.236 by Jelmer Vernooij
require bzr 1.13.
149
        """Return a Git Blob object from a fileid and revision stored in bzr.
150
        
151
        :param fileid: File id of the text
152
        :param revision: Revision of the text
153
        """
0.200.260 by Jelmer Vernooij
Add DictGitShaMap, useful for testing.
154
        text = self.repository.texts.get_record_stream([(fileid, revision)],
155
            "unordered", True).next().get_bytes_as("fulltext")
0.200.229 by Jelmer Vernooij
More work on converter.
156
        blob = Blob()
157
        blob._text = text
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
158
        self._check_expected_sha(expected_sha, blob)
0.200.229 by Jelmer Vernooij
More work on converter.
159
        return blob
160
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
161
    def _get_tree(self, fileid, revid, inv, unusual_modes, expected_sha=None):
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
162
        """Return a Git Tree object from a file id and a revision stored in bzr.
0.200.249 by Jelmer Vernooij
Implement Tree.
163
0.200.343 by Jelmer Vernooij
Use file ids consistently in map.
164
        :param fileid: fileid in the tree.
0.200.249 by Jelmer Vernooij
Implement Tree.
165
        :param revision: Revision of the tree.
166
        """
0.200.549 by Jelmer Vernooij
Fix storing of unusual file modes.
167
        tree = directory_to_tree(inv[fileid], 
168
            lambda ie: self._get_ie_sha1(ie, inv, unusual_modes),
169
            unusual_modes)
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
170
        self._check_expected_sha(expected_sha, tree)
0.200.249 by Jelmer Vernooij
Implement Tree.
171
        return tree
0.200.229 by Jelmer Vernooij
More work on converter.
172
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
173
    def _get_commit(self, rev, tree_sha, expected_sha=None):
0.200.467 by Jelmer Vernooij
Raise proper errors for ghosts.
174
        try:
175
            commit = revision_to_commit(rev, tree_sha, self._lookup_revision_sha1)
176
        except errors.NoSuchRevision, e:
177
            raise GhostRevision(e.branch, e.revision)
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
178
        self._check_expected_sha(expected_sha, commit)
179
        return commit
0.200.228 by Jelmer Vernooij
Split out map.
180
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
181
    def get_parents(self, sha):
0.200.454 by Jelmer Vernooij
Use ObjectStore.find_missing_objects in server.
182
        """Retrieve the parents of a Git commit by SHA1.
183
184
        :param sha: SHA1 of the commit
185
        :raises: KeyError, NotCommitError
186
        """
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
187
        return self[sha].parents
188
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
189
    def _lookup_revision_sha1(self, revid):
0.200.449 by Jelmer Vernooij
Use BazaarObjectStore to find matching SHA1s for bzr revisions.
190
        """Return the SHA1 matching a Bazaar revision."""
0.200.541 by Jelmer Vernooij
Cope with NULL_REVISION.
191
        if revid == NULL_REVISION:
192
            return "0" * 40
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
193
        try:
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
194
            return self._idmap.lookup_commit(revid)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
195
        except KeyError:
0.200.487 by Jelmer Vernooij
Prevent deep recursion if the shamap is out of date.
196
            self._update_sha_map(revid)
197
            return self._idmap.lookup_commit(revid)
0.200.364 by Jelmer Vernooij
Reimplement dpush, but more efficient and only writing a single pack file rather than one per revision.
198
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
199
    def get_raw(self, sha):
0.200.454 by Jelmer Vernooij
Use ObjectStore.find_missing_objects in server.
200
        """Get the raw representation of a Git object by SHA1.
201
202
        :param sha: SHA1 of the git object
203
        """
0.200.421 by Jelmer Vernooij
Use public method to access raw git object text.
204
        return self[sha].as_raw_string()
0.200.310 by Jelmer Vernooij
Fix pull from remote branches.
205
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
206
    def __contains__(self, sha):
207
        # See if sha is in map
208
        try:
209
            self._lookup_git_sha(sha)
210
        except KeyError:
211
            return False
212
        else:
213
            return True
214
215
    def _lookup_git_sha(self, sha):
216
        # See if sha is in map
217
        try:
218
            return self._idmap.lookup_git_sha(sha)
0.200.228 by Jelmer Vernooij
Split out map.
219
        except KeyError:
220
            # if not, see if there are any unconverted revisions and add them 
221
            # to the map, search for sha in map again
222
            self._update_sha_map()
0.200.437 by Jelmer Vernooij
Implement BazaarObjectStore.__contains__, BazaarObjectStore.iter_shas, BazaarObjectStore.get_parents.
223
            return self._idmap.lookup_git_sha(sha)
224
225
    def __getitem__(self, sha):
226
        (type, type_data) = self._lookup_git_sha(sha)
0.200.228 by Jelmer Vernooij
Split out map.
227
        # convert object to git object
0.200.229 by Jelmer Vernooij
More work on converter.
228
        if type == "commit":
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
229
            try:
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
230
                rev = self.repository.get_revision(type_data[0])
0.200.478 by Jelmer Vernooij
Cope with disappeared revisions.
231
            except errors.NoSuchRevision:
232
                trace.mutter('entry for %s %s in shamap: %r, but not found in repository', type, sha, type_data)
233
                raise KeyError(sha)
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
234
            return self._get_commit(rev, type_data[1], expected_sha=sha)
0.200.229 by Jelmer Vernooij
More work on converter.
235
        elif type == "blob":
0.200.353 by Jelmer Vernooij
fileids/revids are plain strings, not unicode
236
            return self._get_blob(type_data[0], type_data[1], expected_sha=sha)
0.200.229 by Jelmer Vernooij
More work on converter.
237
        elif type == "tree":
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
238
            inv = self.repository.get_inventory(type_data[1])
239
            rev = self._get_unusual_modes(type_data[1])
0.200.491 by Jelmer Vernooij
Cope with map for Tree objects becoming invalid.
240
            try:
0.200.548 by Jelmer Vernooij
Extract unusual file modes from revision when reconstructing Trees.
241
                return self._get_tree(type_data[0], type_data[1], inv, unusual_modes,
0.200.491 by Jelmer Vernooij
Cope with map for Tree objects becoming invalid.
242
                                      expected_sha=sha)
243
            except errors.NoSuchRevision:
244
                raise KeyError(sha)
0.200.228 by Jelmer Vernooij
Split out map.
245
        else:
246
            raise AssertionError("Unknown object type '%s'" % type)