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

  • Committer: John Arbash Meinel
  • Date: 2010-01-12 22:51:31 UTC
  • mto: This revision was merged to the branch mainline in revision 4955.
  • Revision ID: john@arbash-meinel.com-20100112225131-he8h411p6aeeb947
Delay grabbing an output stream until we actually go to show a diff.

This makes the test suite happy, but it also seems to be reasonable.
If we aren't going to write anything, we don't need to hold an
output stream open.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007 Canonical Ltd
2
 
# Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
3
 
#
4
 
# This program is free software; you can redistribute it and/or modify
5
 
# it under the terms of the GNU General Public License as published by
6
 
# the Free Software Foundation; either version 2 of the License, or
7
 
# (at your option) any later version.
8
 
#
9
 
# This program is distributed in the hope that it will be useful,
10
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
# GNU General Public License for more details.
13
 
#
14
 
# You should have received a copy of the GNU General Public License
15
 
# along with this program; if not, write to the Free Software
16
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
 
 
18
 
"""An adapter between a Git Repository and a Bazaar Branch"""
19
 
 
20
 
from bzrlib import (
21
 
    errors,
22
 
    inventory,
23
 
    repository,
24
 
    revision,
25
 
    revisiontree,
26
 
    )
27
 
from bzrlib.foreign import (
28
 
    ForeignRepository,
29
 
    )
30
 
 
31
 
from bzrlib.plugins.git.commit import (
32
 
    GitCommitBuilder,
33
 
    )
34
 
from bzrlib.plugins.git.mapping import (
35
 
    default_mapping,
36
 
    foreign_git,
37
 
    mapping_registry,
38
 
    )
39
 
from bzrlib.plugins.git.tree import (
40
 
    GitRevisionTree,
41
 
    )
42
 
from bzrlib.plugins.git.versionedfiles import (
43
 
    GitRevisions,
44
 
    GitTexts,
45
 
    )
46
 
 
47
 
 
48
 
from dulwich.objects import (
49
 
    Commit,
50
 
    )
51
 
 
52
 
 
53
 
class GitRepository(ForeignRepository):
54
 
    """An adapter to git repositories for bzr."""
55
 
 
56
 
    _serializer = None
57
 
    _commit_builder_class = GitCommitBuilder
58
 
    vcs = foreign_git
59
 
 
60
 
    def __init__(self, gitdir, lockfiles):
61
 
        ForeignRepository.__init__(self, GitRepositoryFormat(), gitdir,
62
 
            lockfiles)
63
 
        from bzrlib.plugins.git import fetch, push
64
 
        for optimiser in [fetch.InterRemoteGitNonGitRepository,
65
 
                          fetch.InterLocalGitNonGitRepository,
66
 
                          fetch.InterGitGitRepository,
67
 
                          push.InterToLocalGitRepository,
68
 
                          push.InterToRemoteGitRepository]:
69
 
            repository.InterRepository.register_optimiser(optimiser)
70
 
 
71
 
    def is_shared(self):
72
 
        return False
73
 
 
74
 
    def supports_rich_root(self):
75
 
        return True
76
 
 
77
 
    def _warn_if_deprecated(self, branch=None):
78
 
        # This class isn't deprecated
79
 
        pass
80
 
 
81
 
    def get_mapping(self):
82
 
        return default_mapping
83
 
 
84
 
    def make_working_trees(self):
85
 
        return not self._git.bare
86
 
 
87
 
    def revision_graph_can_have_wrong_parents(self):
88
 
        return False
89
 
 
90
 
    def dfetch(self, source, stop_revision):
91
 
        interrepo = repository.InterRepository.get(source, self)
92
 
        return interrepo.dfetch(stop_revision)
93
 
 
94
 
 
95
 
class LocalGitRepository(GitRepository):
96
 
    """Git repository on the file system."""
97
 
 
98
 
    def __init__(self, gitdir, lockfiles):
99
 
        GitRepository.__init__(self, gitdir, lockfiles)
100
 
        self.base = gitdir.root_transport.base
101
 
        self._git = gitdir._git
102
 
        self.signatures = None
103
 
        self.revisions = GitRevisions(self, self._git.object_store)
104
 
        self.inventories = None
105
 
        self.texts = GitTexts(self)
106
 
 
107
 
    def _iter_revision_ids(self):
108
 
        mapping = self.get_mapping()
109
 
        for sha in self._git.object_store:
110
 
            o = self._git.object_store[sha]
111
 
            if not isinstance(o, Commit):
112
 
                continue
113
 
            rev, roundtrip_revid, verifiers = mapping.import_commit(o,
114
 
                self.lookup_foreign_revision_id)
115
 
            yield o.id, rev.revision_id, roundtrip_revid
116
 
 
117
 
    def all_revision_ids(self):
118
 
        ret = set([])
119
 
        for git_sha, revid, roundtrip_revid in self._iter_revision_ids():
120
 
            ret.add(revid)
121
 
            if roundtrip_revid:
122
 
                ret.add(roundtrip_revid)
123
 
        return ret
124
 
 
125
 
    def get_parent_map(self, revids):
126
 
        parent_map = {}
127
 
        for revision_id in revids:
128
 
            assert isinstance(revision_id, str)
129
 
            if revision_id == revision.NULL_REVISION:
130
 
                parent_map[revision_id] = ()
131
 
                continue
132
 
            hexsha, mapping = self.lookup_bzr_revision_id(revision_id)
133
 
            try:
134
 
                commit = self._git[hexsha]
135
 
            except KeyError:
136
 
                continue
137
 
            parent_map[revision_id] = [
138
 
                self.lookup_foreign_revision_id(p, mapping)
139
 
                for p in commit.parents]
140
 
        return parent_map
141
 
 
142
 
    def get_ancestry(self, revision_id, topo_sorted=True):
143
 
        """See Repository.get_ancestry().
144
 
        """
145
 
        if revision_id is None:
146
 
            return [None, revision.NULL_REVISION] + self._all_revision_ids()
147
 
        assert isinstance(revision_id, str)
148
 
        ancestry = []
149
 
        graph = self.get_graph()
150
 
        for rev, parents in graph.iter_ancestry([revision_id]):
151
 
            ancestry.append(rev)
152
 
        ancestry.reverse()
153
 
        return [None] + ancestry
154
 
 
155
 
    def get_signature_text(self, revision_id):
156
 
        raise errors.NoSuchRevision(self, revision_id)
157
 
 
158
 
    def pack(self, hint=None, clean_obsolete_packs=False):
159
 
        self._git.object_store.pack_loose_objects()
160
 
 
161
 
    def lookup_foreign_revision_id(self, foreign_revid, mapping=None):
162
 
        """Lookup a revision id.
163
 
 
164
 
        """
165
 
        assert type(foreign_revid) is str
166
 
        if mapping is None:
167
 
            mapping = self.get_mapping()
168
 
        from dulwich.protocol import (
169
 
            ZERO_SHA,
170
 
            )
171
 
        if foreign_revid == ZERO_SHA:
172
 
            return revision.NULL_REVISION
173
 
        commit = self._git[foreign_revid]
174
 
        rev, roundtrip_revid, verifiers = mapping.import_commit(commit,
175
 
            lambda x: None)
176
 
        # FIXME: check testament before doing this?
177
 
        if roundtrip_revid:
178
 
            return roundtrip_revid
179
 
        else:
180
 
            return rev.revision_id
181
 
 
182
 
    def has_signature_for_revision_id(self, revision_id):
183
 
        return False
184
 
 
185
 
    def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
186
 
        try:
187
 
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
188
 
        except errors.InvalidRevisionId:
189
 
            if mapping is None:
190
 
                mapping = self.get_mapping()
191
 
            try:
192
 
                return (self._git.refs[mapping.revid_as_refname(bzr_revid)],
193
 
                        mapping)
194
 
            except KeyError:
195
 
                # Update refs from Git commit objects
196
 
                # FIXME: Hitting this a lot will be very inefficient...
197
 
                for git_sha, revid, roundtrip_revid in self._iter_revision_ids():
198
 
                    if not roundtrip_revid:
199
 
                        continue
200
 
                    refname = mapping.revid_as_refname(roundtrip_revid)
201
 
                    self._git.refs[refname] = git_sha
202
 
                    if roundtrip_revid == bzr_revid:
203
 
                        return git_sha, mapping
204
 
                raise errors.NoSuchRevision(self, bzr_revid)
205
 
 
206
 
    def get_revision(self, revision_id):
207
 
        git_commit_id, mapping = self.lookup_bzr_revision_id(revision_id)
208
 
        try:
209
 
            commit = self._git[git_commit_id]
210
 
        except KeyError:
211
 
            raise errors.NoSuchRevision(self, revision_id)
212
 
        revision, roundtrip_revid, verifiers = mapping.import_commit(
213
 
            commit, self.lookup_foreign_revision_id)
214
 
        assert revision is not None
215
 
        # FIXME: check verifiers ?
216
 
        if roundtrip_revid:
217
 
            revision.revision_id = roundtrip_revid
218
 
        return revision
219
 
 
220
 
    def has_revision(self, revision_id):
221
 
        try:
222
 
            git_commit_id, mapping = self.lookup_bzr_revision_id(revision_id)
223
 
        except errors.NoSuchRevision:
224
 
            return False
225
 
        return (git_commit_id in self._git)
226
 
 
227
 
    def has_revisions(self, revision_ids):
228
 
        return set(filter(self.has_revision, revision_ids))
229
 
 
230
 
    def get_revisions(self, revids):
231
 
        return [self.get_revision(r) for r in revids]
232
 
 
233
 
    def revision_trees(self, revids):
234
 
        for revid in revids:
235
 
            yield self.revision_tree(revid)
236
 
 
237
 
    def revision_tree(self, revision_id):
238
 
        revision_id = revision.ensure_null(revision_id)
239
 
        if revision_id == revision.NULL_REVISION:
240
 
            inv = inventory.Inventory(root_id=None)
241
 
            inv.revision_id = revision_id
242
 
            return revisiontree.RevisionTree(self, inv, revision_id)
243
 
        return GitRevisionTree(self, revision_id)
244
 
 
245
 
    def get_inventory(self, revision_id):
246
 
        assert revision_id != None
247
 
        return self.revision_tree(revision_id).inventory
248
 
 
249
 
    def set_make_working_trees(self, trees):
250
 
        pass
251
 
 
252
 
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
253
 
        progress=None):
254
 
        return self._git.fetch_objects(determine_wants, graph_walker, progress)
255
 
 
256
 
    def _get_versioned_file_checker(self, text_key_references=None,
257
 
                        ancestors=None):
258
 
        return GitVersionedFileChecker(self,
259
 
            text_key_references=text_key_references, ancestors=ancestors)
260
 
 
261
 
 
262
 
class GitVersionedFileChecker(repository._VersionedFileChecker):
263
 
 
264
 
    file_ids = []
265
 
 
266
 
    def _check_file_version_parents(self, texts, progress_bar):
267
 
        return {}, []
268
 
 
269
 
 
270
 
class GitRepositoryFormat(repository.RepositoryFormat):
271
 
    """Git repository format."""
272
 
 
273
 
    supports_tree_reference = False
274
 
    rich_root_data = True
275
 
 
276
 
    def get_format_description(self):
277
 
        return "Git Repository"
278
 
 
279
 
    def initialize(self, url, shared=False, _internal=False):
280
 
        raise errors.UninitializableFormat(self)
281
 
 
282
 
    def check_conversion_target(self, target_repo_format):
283
 
        return target_repo_format.rich_root_data
284
 
 
285
 
    def get_foreign_tests_repository_factory(self):
286
 
        from bzrlib.plugins.git.tests.test_repository import (
287
 
            ForeignTestsRepositoryFactory,
288
 
            )
289
 
        return ForeignTestsRepositoryFactory()
290
 
 
291
 
    def network_name(self):
292
 
        return "git"