/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

Specify inventory and texts to inventory_to_tree_and_blobs rather than full repository.

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
    ui,
 
22
    urlutils,
 
23
    )
 
24
from bzrlib.bzrdir import (
 
25
    BzrDir,
 
26
    BzrDirFormat,
 
27
    )
 
28
from bzrlib.errors import (
 
29
    BzrError,
 
30
    NoSuchFile,
 
31
    NotLocalUrl,
 
32
    )
 
33
from bzrlib.foreign import (
 
34
    ForeignBranch,
 
35
    )
 
36
from bzrlib.lockable_files import (
 
37
    TransportLock,
 
38
    )
 
39
from bzrlib.repository import (
 
40
    Repository,
 
41
    )
 
42
from bzrlib.trace import (
 
43
    info,
 
44
    )
 
45
from bzrlib.transport import (
 
46
    Transport,
 
47
    )
 
48
 
 
49
from bzrlib.plugins.git import (
 
50
    lazy_check_versions,
 
51
    )
 
52
lazy_check_versions()
 
53
 
 
54
from bzrlib.plugins.git.branch import (
 
55
    GitBranch,
 
56
    )
 
57
from bzrlib.plugins.git.errors import (
 
58
    GitSmartRemoteNotSupported,
 
59
    NoSuchRef,
 
60
    )
 
61
from bzrlib.plugins.git.dir import (
 
62
    GitDir,
 
63
    )
 
64
from bzrlib.plugins.git.repository import (
 
65
    GitRepositoryFormat,
 
66
    GitRepository,
 
67
    )
 
68
 
 
69
import dulwich as git
 
70
from dulwich.errors import (
 
71
    GitProtocolError,
 
72
    )
 
73
from dulwich.pack import (
 
74
    Pack,
 
75
    PackData,
 
76
    )
 
77
import os
 
78
import tempfile
32
79
import urllib
33
80
import urlparse
34
81
 
35
 
from dulwich.pack import PackData
 
82
try:
 
83
    from dulwich.pack import load_pack_index
 
84
except ImportError:
 
85
    from dulwich.pack import PackIndex as load_pack_index
 
86
 
 
87
 
 
88
# Don't run any tests on GitSmartTransport as it is not intended to be 
 
89
# a full implementation of Transport
 
90
def get_test_permutations():
 
91
    return []
36
92
 
37
93
 
38
94
class GitSmartTransport(Transport):
40
96
    def __init__(self, url, _client=None):
41
97
        Transport.__init__(self, url)
42
98
        (scheme, _, loc, _, _) = urlparse.urlsplit(url)
43
 
        assert scheme == "git"
44
99
        hostport, self._path = urllib.splithost(loc)
45
 
        (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._host, self._port) = urllib.splitnport(hostport, None)
 
101
        self._client = _client
 
102
 
 
103
    def has(self, relpath):
 
104
        return False
 
105
 
 
106
    def _get_client(self):
 
107
        raise NotImplementedError(self._get_client)
50
108
 
51
109
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
52
110
        if progress is None:
53
111
            def progress(text):
54
112
                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)
 
113
        client = self._get_client()
62
114
        try:
63
 
            p = PackData(path)
64
 
            for o in p.iterobjects():
65
 
                yield o
66
 
        finally:
67
 
            os.remove(path)
 
115
            client.fetch_pack(self._path, determine_wants, 
 
116
                graph_walker, pack_data, progress)
 
117
        except GitProtocolError, e:
 
118
            raise BzrError(e)
68
119
 
69
120
    def get(self, path):
70
121
        raise NoSuchFile(path)
71
122
 
 
123
    def abspath(self, relpath):
 
124
        return urlutils.join(self.base, relpath)
 
125
 
72
126
    def clone(self, offset=None):
73
127
        """See Transport.clone()."""
74
128
        if offset is None:
76
130
        else:
77
131
            newurl = urlutils.join(self.base, offset)
78
132
 
79
 
        return GitSmartTransport(newurl, self._client)
 
133
        return self.__class__(newurl, self._client)
 
134
 
 
135
 
 
136
class TCPGitSmartTransport(GitSmartTransport):
 
137
 
 
138
    _scheme = 'git'
 
139
 
 
140
    def _get_client(self):
 
141
        if self._client is not None:
 
142
            ret = self._client
 
143
            self._client = None
 
144
            return ret
 
145
        return git.client.TCPGitClient(self._host, self._port, thin_packs=False,
 
146
            report_activity=self._report_activity)
 
147
 
 
148
 
 
149
class SSHGitSmartTransport(GitSmartTransport):
 
150
 
 
151
    _scheme = 'git+ssh'
 
152
 
 
153
    def _get_client(self):
 
154
        if self._client is not None:
 
155
            ret = self._client
 
156
            self._client = None
 
157
            return ret
 
158
        return git.client.SSHGitClient(self._host, self._port, thin_packs=False,
 
159
            report_activity=self._report_activity)
80
160
 
81
161
 
82
162
class RemoteGitDir(GitDir):
90
170
    def open_repository(self):
91
171
        return RemoteGitRepository(self, self._lockfiles)
92
172
 
93
 
    def open_branch(self):
 
173
    def open_branch(self, ignore_fallbacks=False):
94
174
        repo = self.open_repository()
95
175
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
96
176
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
99
179
        raise NotLocalUrl(self.transport.base)
100
180
 
101
181
 
 
182
class EmptyObjectStoreIterator(dict):
 
183
 
 
184
    def iterobjects(self):
 
185
        return []
 
186
 
 
187
 
 
188
class TemporaryPackIterator(Pack):
 
189
 
 
190
    def __init__(self, path, resolve_ext_ref):
 
191
        super(TemporaryPackIterator, self).__init__(path)
 
192
        self.resolve_ext_ref = resolve_ext_ref
 
193
 
 
194
    @property
 
195
    def idx(self):
 
196
        if self._idx is None:
 
197
            if self._data is None:
 
198
                self._data = PackData(self._data_path)
 
199
            pb = ui.ui_factory.nested_progress_bar()
 
200
            try:
 
201
                def report_progress(cur, total):
 
202
                    pb.update("generating index", cur, total)
 
203
                self._data.create_index_v2(self._idx_path, self.resolve_ext_ref,
 
204
                    progress=report_progress)
 
205
            finally:
 
206
                pb.finished()
 
207
            self._idx = load_pack_index(self._idx_path)
 
208
        return self._idx
 
209
 
 
210
    def __del__(self):
 
211
        os.remove(self._data_path)
 
212
        os.remove(self._idx_path)
 
213
 
 
214
 
102
215
class RemoteGitRepository(GitRepository):
103
216
 
104
217
    def __init__(self, gitdir, lockfiles):
105
218
        GitRepository.__init__(self, gitdir, lockfiles)
 
219
        self._refs = None
 
220
 
 
221
    @property
 
222
    def inventories(self):
 
223
        raise GitSmartRemoteNotSupported()
 
224
 
 
225
    @property
 
226
    def revisions(self):
 
227
        raise GitSmartRemoteNotSupported()
 
228
 
 
229
    @property
 
230
    def texts(self):
 
231
        raise GitSmartRemoteNotSupported()
 
232
 
 
233
    def get_refs(self):
 
234
        if self._refs is not None:
 
235
            return self._refs
 
236
        def determine_wants(heads):
 
237
            self._refs = heads
 
238
            return []
 
239
        self.bzrdir.root_transport.fetch_pack(determine_wants, None, 
 
240
            lambda x: None, lambda x: mutter("git: %s" % x))
 
241
        return self._refs
106
242
 
107
243
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
108
244
                   progress=None):
109
245
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
110
246
            progress)
111
247
 
 
248
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
 
249
        fd, path = tempfile.mkstemp(suffix=".pack")
 
250
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
 
251
        os.close(fd)
 
252
        if os.path.getsize(path) == 0:
 
253
            return EmptyObjectStoreIterator()
 
254
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
 
255
 
 
256
 
 
257
class RemoteGitTagDict(tag.BasicTags):
 
258
 
 
259
    def __init__(self, branch):
 
260
        self.branch = branch
 
261
        self.repository = branch.repository
 
262
 
 
263
    def get_tag_dict(self):
 
264
        ret = {}
 
265
        refs = self.repository.get_refs()
 
266
        for k,v in refs.iteritems():
 
267
            if k.startswith("refs/tags/") and not k.endswith("^{}"):
 
268
                v = refs.get(k+"^{}", v)
 
269
                ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
 
270
        return ret
 
271
 
 
272
    def set_tag(self, name, revid):
 
273
        # FIXME: Not supported yet, should do a push of a new ref
 
274
        raise NotImplementedError(self.set_tag)
 
275
 
112
276
 
113
277
class RemoteGitBranch(GitBranch):
114
278
 
115
279
    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))
 
280
        heads = repository.get_refs()
 
281
        if not name in heads:
 
282
            raise NoSuchRef(name)
 
283
        self._ref = heads[name]
120
284
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
121
285
 
122
286
    def last_revision(self):
123
287
        return self.mapping.revision_id_foreign_to_bzr(self._ref)
124
288
 
 
289
    def _synchronize_history(self, destination, revision_id):
 
290
        """See Branch._synchronize_history()."""
 
291
        destination.generate_revision_history(self.last_revision())
 
292