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

Fix tests, split up InterGitNonGitRepository.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2008 Canonical Ltd
 
1
# Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import bzrlib
18
 
from bzrlib import urlutils
19
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
20
 
from bzrlib.errors import NoSuchFile, NotLocalUrl
21
 
from bzrlib.lockable_files import TransportLock
22
 
from bzrlib.repository import Repository
23
 
from bzrlib.trace import info
24
 
from bzrlib.transport import Transport
25
 
 
26
 
from bzrlib.plugins.git import git
27
 
from bzrlib.plugins.git.branch import GitBranch
28
 
from bzrlib.plugins.git.dir import GitDir
29
 
from bzrlib.plugins.git.foreign import ForeignBranch
30
 
from bzrlib.plugins.git.repository import GitFormat, GitRepository
31
 
 
 
18
from bzrlib import (
 
19
    branch,
 
20
    tag,
 
21
    urlutils,
 
22
    )
 
23
from bzrlib.bzrdir import (
 
24
    BzrDir,
 
25
    BzrDirFormat,
 
26
    )
 
27
from bzrlib.errors import (
 
28
    BzrError,
 
29
    NoSuchFile,
 
30
    NotLocalUrl,
 
31
    )
 
32
from bzrlib.lockable_files import (
 
33
    TransportLock,
 
34
    )
 
35
from bzrlib.repository import (
 
36
    Repository,
 
37
    )
 
38
from bzrlib.trace import (
 
39
    info,
 
40
    )
 
41
from bzrlib.transport import (
 
42
    Transport,
 
43
    )
 
44
 
 
45
from bzrlib.plugins.git import (
 
46
    lazy_check_versions,
 
47
    )
 
48
lazy_check_versions()
 
49
 
 
50
from bzrlib.plugins.git.branch import (
 
51
    GitBranch,
 
52
    )
 
53
from bzrlib.plugins.git.errors import (
 
54
    NoSuchRef,
 
55
    )
 
56
from bzrlib.plugins.git.dir import (
 
57
    GitDir,
 
58
    )
 
59
from bzrlib.plugins.git.foreign import (
 
60
    ForeignBranch,
 
61
    )
 
62
from bzrlib.plugins.git.repository import (
 
63
    GitRepositoryFormat,
 
64
    GitRepository,
 
65
    )
 
66
 
 
67
import dulwich as git
 
68
from dulwich.errors import (
 
69
    GitProtocolError,
 
70
    )
 
71
from dulwich.pack import (
 
72
    Pack,
 
73
    PackData,
 
74
    )
 
75
import os
 
76
import tempfile
32
77
import urllib
33
78
import urlparse
34
79
 
35
 
from dulwich.pack import PackData
 
80
try:
 
81
    from dulwich.pack import load_pack_index
 
82
except ImportError:
 
83
    from dulwich.pack import PackIndex as load_pack_index
 
84
 
 
85
 
 
86
# Don't run any tests on GitSmartTransport as it is not intended to be 
 
87
# a full implementation of Transport
 
88
def get_test_permutations():
 
89
    return []
36
90
 
37
91
 
38
92
class GitSmartTransport(Transport):
43
97
        assert scheme == "git"
44
98
        hostport, self._path = urllib.splithost(loc)
45
99
        (self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
46
 
        if _client is not None:
47
 
            self._client = _client
48
 
        else:
49
 
            self._client = git.client.TCPGitClient(self._host, self._port)
 
100
        self._client = _client
 
101
 
 
102
    def has(self, relpath):
 
103
        return False
 
104
 
 
105
    def _get_client(self):
 
106
        if self._client is not None:
 
107
            ret = self._client
 
108
            self._client = None
 
109
            return ret
 
110
        return git.client.TCPGitClient(self._host, self._port, thin_packs=False)
50
111
 
51
112
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
52
113
        if progress is None:
53
114
            def progress(text):
54
115
                info("git: %s" % text)
55
 
        self._client.fetch_pack(self._path, determine_wants, graph_walker, 
56
 
                pack_data, progress)
57
 
 
58
 
    def fetch_objects(self, determine_wants, graph_walker, progress=None):
59
 
        fd, path = tempfile.mkstemp(dir=self.pack_dir(), suffix=".pack")
60
 
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
61
 
        os.close(fd)
 
116
        client = self._get_client()
62
117
        try:
63
 
            p = PackData(path)
64
 
            for o in p.iterobjects():
65
 
                yield o
66
 
        finally:
67
 
            os.remove(path)
 
118
            client.fetch_pack(self._path, determine_wants, 
 
119
                graph_walker, pack_data, progress)
 
120
        except GitProtocolError, e:
 
121
            raise BzrError(e)
68
122
 
69
123
    def get(self, path):
70
124
        raise NoSuchFile(path)
71
125
 
 
126
    def abspath(self, relpath):
 
127
        return urlutils.join(self.base, relpath)
 
128
 
72
129
    def clone(self, offset=None):
73
130
        """See Transport.clone()."""
74
131
        if offset is None:
90
147
    def open_repository(self):
91
148
        return RemoteGitRepository(self, self._lockfiles)
92
149
 
93
 
    def open_branch(self):
 
150
    def open_branch(self, _unsupported=False):
94
151
        repo = self.open_repository()
95
152
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
96
153
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
99
156
        raise NotLocalUrl(self.transport.base)
100
157
 
101
158
 
 
159
class EmptyObjectStoreIterator(dict):
 
160
 
 
161
    def iterobjects(self):
 
162
        return []
 
163
 
 
164
 
 
165
class TemporaryPackIterator(Pack):
 
166
 
 
167
    def __init__(self, path, resolve_ext_ref):
 
168
        self.resolve_ext_ref = resolve_ext_ref
 
169
        super(TemporaryPackIterator, self).__init__(path)
 
170
 
 
171
    @property
 
172
    def idx(self):
 
173
        if self._idx is None:
 
174
            if self._data is None:
 
175
                self._data = PackData(self._data_path)
 
176
            self._data.create_index_v2(self._idx_path, self.resolve_ext_ref)
 
177
            self._idx = load_pack_index(self._idx_path)
 
178
        return self._idx
 
179
 
 
180
    def __del__(self):
 
181
        os.remove(self._data_path)
 
182
        os.remove(self._idx_path)
 
183
 
 
184
 
102
185
class RemoteGitRepository(GitRepository):
103
186
 
104
187
    def __init__(self, gitdir, lockfiles):
105
188
        GitRepository.__init__(self, gitdir, lockfiles)
 
189
        self._refs = None
 
190
 
 
191
    def get_refs(self):
 
192
        if self._refs is not None:
 
193
            return self._refs
 
194
        def determine_wants(heads):
 
195
            self._refs = heads
 
196
            return []
 
197
        self.bzrdir.root_transport.fetch_pack(determine_wants, None, 
 
198
            lambda x: None, lambda x: mutter("git: %s" % x))
 
199
        return self._refs
106
200
 
107
201
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
108
202
                   progress=None):
109
203
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
110
204
            progress)
111
205
 
 
206
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
 
207
        fd, path = tempfile.mkstemp(suffix=".pack")
 
208
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
 
209
        os.close(fd)
 
210
        if os.path.getsize(path) == 0:
 
211
            return EmptyObjectStoreIterator()
 
212
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
 
213
 
 
214
 
 
215
class RemoteGitTagDict(tag.BasicTags):
 
216
 
 
217
    def __init__(self, branch):
 
218
        self.branch = branch
 
219
        self.repository = branch.repository
 
220
 
 
221
    def get_tag_dict(self):
 
222
        ret = {}
 
223
        refs = self.repository.get_refs()
 
224
        for k,v in refs.iteritems():
 
225
            if k.startswith("refs/tags/") and not k.endswith("^{}"):
 
226
                v = refs.get(k+"^{}", v)
 
227
                ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
 
228
        return ret
 
229
 
 
230
    def set_tag(self, name, revid):
 
231
        # FIXME: Not supported yet, should do a push of a new ref
 
232
        raise NotImplementedError(self.set_tag)
 
233
 
112
234
 
113
235
class RemoteGitBranch(GitBranch):
114
236
 
115
237
    def __init__(self, bzrdir, repository, name, lockfiles):
116
 
        def determine_wants(heads):
117
 
            self._ref = heads[name]
118
 
        bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None, 
119
 
                             lambda x: mutter("git: %s" % x))
 
238
        heads = repository.get_refs()
 
239
        if not name in heads:
 
240
            raise NoSuchRef(name)
 
241
        self._ref = heads[name]
120
242
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
121
243
 
122
244
    def last_revision(self):
123
245
        return self.mapping.revision_id_foreign_to_bzr(self._ref)
124
246
 
 
247
    def _synchronize_history(self, destination, revision_id):
 
248
        """See Branch._synchronize_history()."""
 
249
        destination.generate_revision_history(self.last_revision())
 
250