15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
from bzrlib.bzrdir import (
28
from bzrlib.errors import (
33
from bzrlib.foreign import (
36
from bzrlib.lockable_files import (
39
from bzrlib.repository import (
42
from bzrlib.trace import (
45
from bzrlib.transport import (
49
from bzrlib.plugins.git import (
54
from bzrlib.plugins.git.branch import (
57
from bzrlib.plugins.git.errors import (
58
GitSmartRemoteNotSupported,
61
from bzrlib.plugins.git.dir import (
64
from bzrlib.plugins.git.repository import (
70
from dulwich.errors import (
73
from dulwich.pack import (
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
26
from bzrlib.plugins.git import git
27
from bzrlib.plugins.git.branch import GitBranch
28
from bzrlib.plugins.git.errors import NoSuchRef
29
from bzrlib.plugins.git.dir import GitDir
30
from bzrlib.plugins.git.foreign import ForeignBranch
31
from bzrlib.plugins.git.repository import GitFormat, GitRepository
83
from dulwich.pack import load_pack_index
85
from dulwich.pack import PackIndex as load_pack_index
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():
38
from dulwich.pack import PackData, Pack
94
41
class GitSmartTransport(Transport):
96
43
def __init__(self, url, _client=None):
97
44
Transport.__init__(self, url)
98
45
(scheme, _, loc, _, _) = urlparse.urlsplit(url)
46
assert scheme == "git"
99
47
hostport, self._path = urllib.splithost(loc)
100
(self._host, self._port) = urllib.splitnport(hostport, None)
48
(self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
101
49
self._client = _client
103
def has(self, relpath):
106
51
def _get_client(self):
107
raise NotImplementedError(self._get_client)
52
if self._client is not None:
56
return git.client.TCPGitClient(self._host, self._port)
109
58
def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
110
59
if progress is None:
111
60
def progress(text):
112
61
info("git: %s" % text)
113
client = self._get_client()
115
client.fetch_pack(self._path, determine_wants,
116
graph_walker, pack_data, progress)
117
except GitProtocolError, e:
62
self._get_client().fetch_pack(self._path, determine_wants,
63
graph_walker, pack_data, progress)
120
65
def get(self, path):
121
66
raise NoSuchFile(path)
131
76
newurl = urlutils.join(self.base, offset)
133
return self.__class__(newurl, self._client)
136
class TCPGitSmartTransport(GitSmartTransport):
140
def _get_client(self):
141
if self._client is not None:
145
return git.client.TCPGitClient(self._host, self._port, thin_packs=False,
146
report_activity=self._report_activity)
149
class SSHGitSmartTransport(GitSmartTransport):
153
def _get_client(self):
154
if self._client is not None:
158
return git.client.SSHGitClient(self._host, self._port, thin_packs=False,
159
report_activity=self._report_activity)
78
return GitSmartTransport(newurl, self._client)
162
81
class RemoteGitDir(GitDir):
179
98
raise NotLocalUrl(self.transport.base)
182
class EmptyObjectStoreIterator(dict):
184
def iterobjects(self):
188
class TemporaryPackIterator(Pack):
190
def __init__(self, path, resolve_ext_ref):
191
super(TemporaryPackIterator, self).__init__(path)
192
self.resolve_ext_ref = resolve_ext_ref
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()
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)
207
self._idx = load_pack_index(self._idx_path)
211
os.remove(self._data_path)
212
os.remove(self._idx_path)
215
101
class RemoteGitRepository(GitRepository):
217
103
def __init__(self, gitdir, lockfiles):
218
104
GitRepository.__init__(self, gitdir, lockfiles)
222
def inventories(self):
223
raise GitSmartRemoteNotSupported()
227
raise GitSmartRemoteNotSupported()
231
raise GitSmartRemoteNotSupported()
234
if self._refs is not None:
236
def determine_wants(heads):
239
self.bzrdir.root_transport.fetch_pack(determine_wants, None,
240
lambda x: None, lambda x: mutter("git: %s" % x))
243
106
def fetch_pack(self, determine_wants, graph_walker, pack_data,
245
108
self._transport.fetch_pack(determine_wants, graph_walker, pack_data,
248
def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
111
def fetch_objects(self, determine_wants, graph_walker, progress=None):
249
112
fd, path = tempfile.mkstemp(suffix=".pack")
250
113
self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
252
if os.path.getsize(path) == 0:
253
return EmptyObjectStoreIterator()
254
return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
257
class RemoteGitTagDict(tag.BasicTags):
259
def __init__(self, branch):
261
self.repository = branch.repository
263
def get_tag_dict(self):
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)
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)
116
basename = path[:-len(".pack")]
118
p.create_index_v2(basename+".idx")
119
for o in Pack(basename).iterobjects():
277
125
class RemoteGitBranch(GitBranch):
279
127
def __init__(self, bzrdir, repository, name, lockfiles):
280
heads = repository.get_refs()
281
if not name in heads:
282
raise NoSuchRef(name)
283
self._ref = heads[name]
128
def determine_wants(heads):
129
if not name in heads:
130
raise NoSuchRef(name)
131
self._ref = heads[name]
132
bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None,
133
lambda x: mutter("git: %s" % x))
284
134
super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
286
136
def last_revision(self):