/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 converter.py

  • Committer: Andrew Bennetts
  • Date: 2009-10-21 11:13:40 UTC
  • mto: This revision was merged to the branch mainline in revision 4762.
  • Revision ID: andrew.bennetts@canonical.com-20091021111340-w7x4d5yf83qwjncc
Add test that WSGI glue allows request handlers to access paths above that request's. backing transport, so long as it is within the WSGI app's backing transport.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009 Jelmer Vernooij <jelmer@samba.org>
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
 
 
19
 
from dulwich.objects import (
20
 
    Blob,
21
 
    Tree,
22
 
    )
23
 
import stat
24
 
 
25
 
from bzrlib import (
26
 
    errors,
27
 
    ui,
28
 
    )
29
 
 
30
 
from bzrlib.plugins.git.mapping import (
31
 
    directory_to_tree,
32
 
    mapping_registry,
33
 
    revision_to_commit,
34
 
    )
35
 
from bzrlib.plugins.git.shamap import (
36
 
    SqliteGitShaMap,
37
 
    )
38
 
 
39
 
 
40
 
class BazaarObjectStore(object):
41
 
    """A Git-style object store backed onto a Bazaar repository."""
42
 
 
43
 
    def __init__(self, repository, mapping=None):
44
 
        self.repository = repository
45
 
        if mapping is None:
46
 
            self.mapping = self.repository.get_mapping()
47
 
        else:
48
 
            self.mapping = mapping
49
 
        self._idmap = SqliteGitShaMap.from_repository(repository)
50
 
 
51
 
    def _update_sha_map(self):
52
 
        all_revids = self.repository.all_revision_ids()
53
 
        graph = self.repository.get_graph()
54
 
        present_revids = set(self._idmap.revids())
55
 
        missing_revids = [revid for revid in graph.iter_topo_order(all_revids) if revid not in present_revids]
56
 
        pb = ui.ui_factory.nested_progress_bar()
57
 
        try:
58
 
            for i, revid in enumerate(missing_revids):
59
 
                pb.update("updating git map", i, len(missing_revids))
60
 
                self._update_sha_map_revision(revid)
61
 
        finally:
62
 
            self._idmap.commit()
63
 
            pb.finished()
64
 
 
65
 
    def __iter__(self):
66
 
        self._update_sha_map()
67
 
        return iter(self._idmap.sha1s())
68
 
 
69
 
    def _update_sha_map_revision(self, revid):
70
 
        inv = self.repository.get_inventory(revid)
71
 
        tree_sha = self._get_ie_sha1(inv.root, inv)
72
 
        rev = self.repository.get_revision(revid)
73
 
        commit_obj = revision_to_commit(rev, tree_sha,
74
 
            self._idmap._parent_lookup)
75
 
        try:
76
 
            foreign_revid, mapping = mapping_registry.parse_revision_id(revid)
77
 
        except errors.InvalidRevisionId:
78
 
            pass
79
 
        else:
80
 
            if foreign_revid != commit_obj.id:
81
 
                raise AssertionError("recreated git commit had different sha1: expected %s, got %s" % (foreign_revid, commit_obj.id))
82
 
        self._idmap.add_entry(commit_obj.id, "commit", (revid, tree_sha))
83
 
 
84
 
    def _check_expected_sha(self, expected_sha, object):
85
 
        if expected_sha is None:
86
 
            return
87
 
        if expected_sha != object.id:
88
 
            raise AssertionError("Invalid sha for %r: %s" % (object, expected_sha))
89
 
 
90
 
    def _get_ie_object(self, entry, inv):  
91
 
        if entry.kind == "directory":
92
 
            return self._get_tree(entry.file_id, inv.revision_id, inv=inv)
93
 
        else:
94
 
            return self._get_blob(entry.file_id, entry.revision)
95
 
 
96
 
    def _get_ie_object_or_sha1(self, entry, inv):
97
 
        if entry.kind == "directory":
98
 
            try:
99
 
                return self._idmap.lookup_tree(entry.file_id, inv.revision_id), None
100
 
            except KeyError:
101
 
                ret = self._get_ie_object(entry, inv)
102
 
                self._idmap.add_entry(ret.id, "tree", (entry.file_id, inv.revision_id))
103
 
                return ret.id, ret
104
 
        else:
105
 
            try:
106
 
                return self._idmap.lookup_blob(entry.file_id, entry.revision), None
107
 
            except KeyError:
108
 
                ret = self._get_ie_object(entry, inv)
109
 
                self._idmap.add_entry(ret.id, "blob", (entry.file_id, entry.revision))
110
 
                return ret.id, ret
111
 
 
112
 
    def _get_ie_sha1(self, entry, inv):
113
 
        return self._get_ie_object_or_sha1(entry, inv)[0]
114
 
 
115
 
    def _get_blob(self, fileid, revision, expected_sha=None):
116
 
        """Return a Git Blob object from a fileid and revision stored in bzr.
117
 
        
118
 
        :param fileid: File id of the text
119
 
        :param revision: Revision of the text
120
 
        """
121
 
        text = self.repository.texts.get_record_stream([(fileid, revision)],
122
 
            "unordered", True).next().get_bytes_as("fulltext")
123
 
        blob = Blob()
124
 
        blob._text = text
125
 
        self._check_expected_sha(expected_sha, blob)
126
 
        return blob
127
 
 
128
 
    def _get_tree(self, fileid, revid, inv=None, expected_sha=None):
129
 
        """Return a Git Tree object from a file id and a revision stored in bzr.
130
 
 
131
 
        :param fileid: fileid in the tree.
132
 
        :param revision: Revision of the tree.
133
 
        """
134
 
        if inv is None:
135
 
            inv = self.repository.get_inventory(revid)
136
 
        tree = directory_to_tree(inv[fileid], lambda ie: self._get_ie_sha1(ie, inv))
137
 
        self._check_expected_sha(expected_sha, tree)
138
 
        return tree
139
 
 
140
 
    def _get_commit(self, revid, tree_sha, expected_sha=None):
141
 
        rev = self.repository.get_revision(revid)
142
 
        commit = revision_to_commit(rev, tree_sha, self._lookup_revision_sha1)
143
 
        self._check_expected_sha(expected_sha, commit)
144
 
        return commit
145
 
 
146
 
    def _lookup_revision_sha1(self, revid):
147
 
        try:
148
 
            return self._idmap._parent_lookup(revid)
149
 
        except KeyError:
150
 
            inv = self.repository.get_inventory(revid)
151
 
            tree_sha = self._get_ie_sha1(inv.root, inv)
152
 
            ret = self._get_commit(revid, tree_sha).id
153
 
            self._idmap.add_entry(ret, "commit", (revid, tree_sha))
154
 
            return ret
155
 
 
156
 
    def get_raw(self, sha):
157
 
        return self[sha].as_raw_string()
158
 
 
159
 
    def __getitem__(self, sha):
160
 
        # See if sha is in map
161
 
        try:
162
 
            (type, type_data) = self._idmap.lookup_git_sha(sha)
163
 
        except KeyError:
164
 
            # if not, see if there are any unconverted revisions and add them 
165
 
            # to the map, search for sha in map again
166
 
            self._update_sha_map()
167
 
            (type, type_data) = self._idmap.lookup_git_sha(sha)
168
 
        # convert object to git object
169
 
        if type == "commit":
170
 
            return self._get_commit(type_data[0], type_data[1], 
171
 
                                    expected_sha=sha)
172
 
        elif type == "blob":
173
 
            return self._get_blob(type_data[0], type_data[1], expected_sha=sha)
174
 
        elif type == "tree":
175
 
            return self._get_tree(type_data[0], type_data[1], expected_sha=sha)
176
 
        else:
177
 
            raise AssertionError("Unknown object type '%s'" % type)