/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

ImplementĀ GitBranch.__repr__.

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