/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.358.2 by Jelmer Vernooij
Refresh copyright headers, add my email.
1
# Copyright (C) 2007-2018 Jelmer Vernooij <jelmer@jelmer.uk>
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
0.358.1 by Jelmer Vernooij
Fix FSF address.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
16
0.358.3 by Jelmer Vernooij
Enable absolute import.
17
"""Remote dirs, repositories and branches."""
18
0.200.1594 by Jelmer Vernooij
Use absolute_import everywhere.
19
from __future__ import absolute_import
20
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
21
import re
22
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
23
from ... import (
0.200.596 by Jelmer Vernooij
Import RemoteGitBranch._get_config().
24
    config,
0.200.707 by Jelmer Vernooij
Add debug routines.
25
    debug,
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
26
    errors,
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
27
    trace,
0.200.333 by Jelmer Vernooij
Support progress reporting when creating index.
28
    ui,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
29
    urlutils,
30
    )
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
31
from ...push import (
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
32
    PushResult,
33
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
34
from ...errors import (
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
35
    AlreadyBranchError,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
36
    BzrError,
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
37
    DivergedBranches,
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
38
    InProcessTransport,
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
39
    InvalidRevisionId,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
40
    NoSuchFile,
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
41
    NoSuchRevision,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
42
    NoSuchTag,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
43
    NotBranchError,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
44
    NotLocalUrl,
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
45
    NoWorkingTree,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
46
    UninitializableFormat,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
47
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
48
from ...transport import (
0.200.292 by Jelmer Vernooij
Fix formatting.
49
    Transport,
50
    )
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
51
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
52
from . import (
0.200.292 by Jelmer Vernooij
Fix formatting.
53
    lazy_check_versions,
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
54
    user_agent_for_github,
0.200.292 by Jelmer Vernooij
Fix formatting.
55
    )
0.200.200 by Jelmer Vernooij
Register lazily where possible.
56
lazy_check_versions()
57
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
58
from .branch import (
0.200.292 by Jelmer Vernooij
Fix formatting.
59
    GitBranch,
0.295.1 by Jelmer Vernooij
Split up branch formats.
60
    GitBranchFormat,
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
61
    GitBranchPushResult,
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
62
    GitTags,
0.406.2 by Jelmer Vernooij
Add tests.
63
    _quick_lookup_revno,
0.200.292 by Jelmer Vernooij
Fix formatting.
64
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
65
from .dir import (
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
66
    GitControlDirFormat,
67
    GitDir,
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
68
    BareLocalGitControlDirFormat,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
69
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
70
from .errors import (
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
71
    GitSmartRemoteNotSupported,
0.200.292 by Jelmer Vernooij
Fix formatting.
72
    NoSuchRef,
73
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
74
from .mapping import (
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
75
    mapping_registry,
76
    )
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
77
from .object_store import (
78
    get_object_store,
79
    )
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
80
from .push import (
81
    remote_divergence,
82
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
83
from .repository import (
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
84
    GitRepository,
85
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
86
from .refs import (
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
87
    branch_name_to_ref,
0.200.1487 by Jelmer Vernooij
Use peeling.
88
    is_peeled,
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
89
    ref_to_tag_name,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
90
    tag_name_to_ref,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
91
    )
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
92
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
93
import dulwich
94
import dulwich.client
0.200.292 by Jelmer Vernooij
Fix formatting.
95
from dulwich.errors import (
96
    GitProtocolError,
97
    )
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
98
from dulwich.pack import (
99
    Pack,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
100
    pack_objects_to_data,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
101
    )
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
102
from dulwich.protocol import ZERO_SHA
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
103
from dulwich.refs import (
104
    DictRefsContainer,
105
    SYMREF,
106
    )
107
from dulwich.repo import (
108
    NotGitRepository,
109
    )
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
110
import os
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
111
import select
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
112
import tempfile
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
113
import urllib
114
import urlparse
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
115
116
# urlparse only supports a limited number of schemes by default
117
0.200.741 by Jelmer Vernooij
Cope with older versions of Python by adding git and git+ssh to the list of known schemes.
118
urlparse.uses_netloc.extend(['git', 'git+ssh'])
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
119
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
120
from dulwich.pack import load_pack_index
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
121
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
122
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
123
class GitPushResult(PushResult):
124
125
    def _lookup_revno(self, revid):
0.406.2 by Jelmer Vernooij
Add tests.
126
        try:
127
            return _quick_lookup_revno(self.source_branch, self.target_branch,
128
                revid)
129
        except GitSmartRemoteNotSupported:
130
            return None
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
131
132
    @property
133
    def old_revno(self):
134
        return self._lookup_revno(self.old_revid)
135
136
    @property
137
    def new_revno(self):
138
        return self._lookup_revno(self.new_revid)
139
140
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
141
# Don't run any tests on GitSmartTransport as it is not intended to be
0.200.181 by Jelmer Vernooij
Support setting tags.
142
# a full implementation of Transport
143
def get_test_permutations():
144
    return []
145
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
146
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
147
def split_git_url(url):
0.200.709 by Jelmer Vernooij
When unpacking URLs, strip leftmost slash to match gits behaviour.
148
    """Split a Git URL.
149
150
    :param url: Git URL
151
    :return: Tuple with host, port, username, path.
152
    """
0.200.743 by Jelmer Vernooij
Fix URL parsing.
153
    (scheme, netloc, loc, _, _) = urlparse.urlsplit(url)
154
    path = urllib.unquote(loc)
0.246.2 by Jelmer Vernooij
Improve the fix dealing with git repo's in home directories.
155
    if path.startswith("/~"):
0.200.709 by Jelmer Vernooij
When unpacking URLs, strip leftmost slash to match gits behaviour.
156
        path = path[1:]
0.200.743 by Jelmer Vernooij
Fix URL parsing.
157
    (username, hostport) = urllib.splituser(netloc)
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
158
    (host, port) = urllib.splitnport(hostport, None)
159
    return (host, port, username, path)
160
161
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
162
class RemoteGitError(BzrError):
163
0.290.1 by Jelmer Vernooij
Avoid 'message' argument in RemoteGitError; apparently it breaks some versions of Python.
164
    _fmt = "Remote server error: %(msg)s"
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
165
166
0.200.1275 by Jelmer Vernooij
recognize missing repositories
167
def parse_git_error(url, message):
168
    """Parse a remote git server error and return a bzr exception.
169
170
    :param url: URL of the remote repository
171
    :param message: Message sent by the remote git server
172
    """
173
    message = str(message).strip()
174
    if message.startswith("Could not find Repository "):
175
        return NotBranchError(url, message)
0.200.1563 by Jelmer Vernooij
Improve error message.
176
    if message == "HEAD failed to update":
177
        base_url, _ = urlutils.split_segment_parameters(url)
178
        raise BzrError(
179
            ("Unable to update remote HEAD branch. To update the master "
180
             "branch, specify the URL %s,branch=master.") % base_url)
0.200.1275 by Jelmer Vernooij
recognize missing repositories
181
    # Don't know, just return it to the user as-is
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
182
    return RemoteGitError(message)
0.200.1275 by Jelmer Vernooij
recognize missing repositories
183
184
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
185
class GitSmartTransport(Transport):
186
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
187
    def __init__(self, url, _client=None):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
188
        Transport.__init__(self, url)
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
189
        (self._host, self._port, self._username, self._path) = \
190
            split_git_url(url)
0.200.707 by Jelmer Vernooij
Add debug routines.
191
        if 'transport' in debug.debug_flags:
192
            trace.mutter('host: %r, user: %r, port: %r, path: %r',
193
                         self._host, self._username, self._port, self._path)
0.200.166 by Jelmer Vernooij
don't reuse client objects.
194
        self._client = _client
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
195
        self._stripped_path = self._path.rsplit(",", 1)[0]
0.200.166 by Jelmer Vernooij
don't reuse client objects.
196
0.200.543 by Jelmer Vernooij
Implement GitSmartTransport.external_url().
197
    def external_url(self):
198
        return self.base
199
0.200.238 by Jelmer Vernooij
Import Transport.has().
200
    def has(self, relpath):
201
        return False
202
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
203
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
204
        raise NotImplementedError(self._get_client)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
205
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
206
    def _get_path(self):
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
207
        return self._stripped_path
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
208
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
209
    def get(self, path):
210
        raise NoSuchFile(path)
211
0.200.160 by Jelmer Vernooij
Implement abspath.
212
    def abspath(self, relpath):
213
        return urlutils.join(self.base, relpath)
214
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
215
    def clone(self, offset=None):
216
        """See Transport.clone()."""
217
        if offset is None:
218
            newurl = self.base
219
        else:
220
            newurl = urlutils.join(self.base, offset)
221
0.200.307 by Jelmer Vernooij
Support git+ssh.
222
        return self.__class__(newurl, self._client)
223
224
225
class TCPGitSmartTransport(GitSmartTransport):
226
0.200.332 by Jelmer Vernooij
Support activity reporting.
227
    _scheme = 'git'
228
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
229
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
230
        if self._client is not None:
231
            ret = self._client
232
            self._client = None
233
            return ret
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
234
        if self._host == '':
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
235
            # return dulwich.client.LocalGitClient()
236
            return dulwich.client.SubprocessGitClient()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
237
        return dulwich.client.TCPGitClient(self._host, self._port,
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
238
            report_activity=self._report_activity)
0.200.307 by Jelmer Vernooij
Support git+ssh.
239
240
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
241
class SSHSocketWrapper(object):
242
243
    def __init__(self, sock):
244
        self.sock = sock
245
246
    def read(self, len=None):
247
        return self.sock.recv(len)
248
249
    def write(self, data):
250
        return self.sock.write(data)
251
252
    def can_read(self):
253
        return len(select.select([self.sock.fileno()], [], [], 0)[0]) > 0
254
255
256
class DulwichSSHVendor(dulwich.client.SSHVendor):
257
258
    def __init__(self):
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
259
        from ...transport import ssh
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
260
        self.bzr_ssh_vendor = ssh._get_ssh_vendor()
261
262
    def run_command(self, host, command, username=None, port=None):
263
        connection = self.bzr_ssh_vendor.connect_ssh(username=username,
264
            password=None, port=port, host=host, command=command)
265
        (kind, io_object) = connection.get_sock_or_pipes()
266
        if kind == 'socket':
267
            return SSHSocketWrapper(io_object)
268
        else:
269
            raise AssertionError("Unknown io object kind %r'" % kind)
270
271
272
#dulwich.client.get_ssh_vendor = DulwichSSHVendor
273
274
0.200.307 by Jelmer Vernooij
Support git+ssh.
275
class SSHGitSmartTransport(GitSmartTransport):
276
0.200.332 by Jelmer Vernooij
Support activity reporting.
277
    _scheme = 'git+ssh'
278
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
279
    def _get_path(self):
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
280
        path = self._stripped_path
0.200.1318 by Jelmer Vernooij
Strip segment parameters where necessary.
281
        if path.startswith("/~/"):
282
            return path[3:]
283
        return path
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
284
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
285
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
286
        if self._client is not None:
287
            ret = self._client
288
            self._client = None
289
            return ret
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
290
        location_config = config.LocationConfig(self.base)
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
291
        client = dulwich.client.SSHGitClient(self._host, self._port, self._username,
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
292
            report_activity=self._report_activity)
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
293
        # Set up alternate pack program paths
294
        upload_pack = location_config.get_user_option('git_upload_pack')
295
        if upload_pack:
0.200.949 by Jelmer Vernooij
merge support for specifying alternative paths for git executables.
296
            client.alternative_paths["upload-pack"] = upload_pack
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
297
        receive_pack = location_config.get_user_option('git_receive_pack')
298
        if receive_pack:
0.200.949 by Jelmer Vernooij
merge support for specifying alternative paths for git executables.
299
            client.alternative_paths["receive-pack"] = receive_pack
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
300
        return client
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
301
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
302
0.295.1 by Jelmer Vernooij
Split up branch formats.
303
class RemoteGitBranchFormat(GitBranchFormat):
304
305
    def get_format_description(self):
306
        return 'Remote Git Branch'
307
308
    @property
309
    def _matchingcontroldir(self):
310
        return RemoteGitControlDirFormat()
311
0.295.2 by Jelmer Vernooij
Make RemoteGitBranchFormat uninitializeable.
312
    def initialize(self, a_controldir, name=None, repository=None,
313
                   append_revisions_only=None):
314
        raise UninitializableFormat(self)
315
0.295.1 by Jelmer Vernooij
Split up branch formats.
316
0.407.1 by Jelmer Vernooij
Improve progress reporting.
317
class DefaultProgressReporter(object):
318
319
    _GIT_PROGRESS_PARTIAL_RE = re.compile(r"(.*?): +(\d+)% \((\d+)/(\d+)\)")
320
    _GIT_PROGRESS_TOTAL_RE = re.compile(r"(.*?): (\d+)")
321
322
    def __init__(self, pb):
323
        self.pb = pb
324
325
    def progress(self, text):
326
        text = text.rstrip("\r\n")
327
        if text.startswith('error: '):
328
            trace.show_error('git: %s', text[len('error: '):])
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
329
        else:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
330
            trace.mutter("git: %s", text)
331
            g = self._GIT_PROGRESS_PARTIAL_RE.match(text)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
332
            if g is not None:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
333
                (text, pct, current, total) = g.groups()
334
                self.pb.update(text, int(current), int(total))
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
335
            else:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
336
                g = self._GIT_PROGRESS_TOTAL_RE.match(text)
337
                if g is not None:
338
                    (text, total) = g.groups()
339
                    self.pb.update(text, None, int(total))
340
                else:
341
                    trace.note("%s", text)
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
342
343
0.200.148 by Jelmer Vernooij
Share more infrastructure between LocalGitDir and RemoteGitDir.
344
class RemoteGitDir(GitDir):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
345
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
346
    def __init__(self, transport, format, client, client_path):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
347
        self._format = format
348
        self.root_transport = transport
349
        self.transport = transport
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
350
        self._mode_check_done = None
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
351
        self._client = client
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
352
        self._client_path = client_path
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
353
        self.base = self.root_transport.base
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
354
        self._refs = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
355
0.322.1 by Jelmer Vernooij
Fix access of remote git branches.
356
    @property
357
    def _gitrepository_class(self):
358
        return RemoteGitRepository
359
0.200.1335 by Jelmer Vernooij
Move _get_client.
360
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
361
        if progress is None:
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
362
            pb = ui.ui_factory.nested_progress_bar()
0.407.1 by Jelmer Vernooij
Improve progress reporting.
363
            progress = DefaultProgressReporter(pb).progress
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
364
        else:
365
            pb = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
366
        try:
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
367
            result = self._client.fetch_pack(self._client_path, determine_wants,
0.200.1335 by Jelmer Vernooij
Move _get_client.
368
                graph_walker, pack_data, progress)
0.376.1 by Jelmer Vernooij
Add tests for remote operations.
369
            if result.refs is None:
370
                result.refs = {}
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
371
            self._refs = remote_refs_dict_to_container(result.refs, result.symrefs)
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
372
            return result
0.200.1335 by Jelmer Vernooij
Move _get_client.
373
        except GitProtocolError, e:
374
            raise parse_git_error(self.transport.external_url(), e)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
375
        finally:
376
            if pb is not None:
377
                pb.finished()
0.200.1335 by Jelmer Vernooij
Move _get_client.
378
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
379
    def send_pack(self, get_changed_refs, generate_pack_data, progress=None):
380
        if progress is None:
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
381
            pb = ui.ui_factory.nested_progress_bar()
0.407.1 by Jelmer Vernooij
Improve progress reporting.
382
            progress = DefaultProgressReporter(pb).progress
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
383
        else:
384
            pb = None
0.419.1 by Jelmer Vernooij
Simplify pushing to Git directories.
385
        def get_changed_refs_wrapper(refs):
386
            # TODO(jelmer): This drops symref information
387
            self._refs = remote_refs_dict_to_container(refs)
388
            return get_changed_refs(refs)
0.200.1335 by Jelmer Vernooij
Move _get_client.
389
        try:
0.419.1 by Jelmer Vernooij
Simplify pushing to Git directories.
390
            return self._client.send_pack(self._client_path,
391
                    get_changed_refs_wrapper, generate_pack_data, progress)
0.200.1335 by Jelmer Vernooij
Move _get_client.
392
        except GitProtocolError, e:
393
            raise parse_git_error(self.transport.external_url(), e)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
394
        finally:
395
            if pb is not None:
396
                pb.finished()
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
397
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
398
    def create_branch(self, name=None, repository=None,
399
                      append_revisions_only=None, ref=None):
400
        refname = self._get_selected_ref(name, ref)
401
        if refname != b'HEAD' and refname in self.get_refs_container():
402
            raise AlreadyBranchError(self.user_url)
403
        if refname in self.get_refs_container():
404
            ref_chain, unused_sha = self.get_refs_container().follow(self._get_selected_ref(None))
405
            if ref_chain[0] == b'HEAD':
406
                refname = ref_chain[1]
407
        repo = self.open_repository()
408
        return RemoteGitBranch(self, repo, refname)
409
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
410
    def destroy_branch(self, name=None):
411
        refname = self._get_selected_ref(name)
412
        def get_changed_refs(old_refs):
413
            ret = dict(old_refs)
414
            if not refname in ret:
0.200.1395 by Jelmer Vernooij
Fix error reporting.
415
                raise NotBranchError(self.user_url)
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
416
            ret[refname] = dulwich.client.ZERO_SHA
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
417
            return ret
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
418
        def generate_pack_data(have, want, ofs_delta=False):
419
            return pack_objects_to_data([])
420
        self.send_pack(get_changed_refs, generate_pack_data)
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
421
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
422
    @property
423
    def user_url(self):
424
        return self.control_url
425
0.200.1314 by Jelmer Vernooij
Provide RemoteGitDir.user_transport.
426
    @property
427
    def user_transport(self):
428
        return self.root_transport
429
0.200.1395 by Jelmer Vernooij
Fix error reporting.
430
    @property
431
    def control_url(self):
432
        return self.control_transport.base
433
434
    @property
435
    def control_transport(self):
436
        return self.root_transport
437
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
438
    def open_repository(self):
0.200.1415 by Jelmer Vernooij
Fix lock files for remote directories.
439
        return RemoteGitRepository(self)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
440
0.200.1310 by Jelmer Vernooij
Add _get_selected_ref method.
441
    def open_branch(self, name=None, unsupported=False,
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
442
            ignore_fallbacks=False, ref=None, possible_transports=None,
443
            nascent_ok=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
444
        repo = self.open_repository()
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
445
        ref = self._get_selected_ref(name, ref)
446
        if not nascent_ok and ref not in self.get_refs_container():
447
            raise NotBranchError(self.root_transport.base,
448
                    controldir=self)
449
        ref_chain, unused_sha = self.get_refs_container().follow(ref)
450
        return RemoteGitBranch(self, repo, ref_chain[-1])
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
451
0.200.662 by Jelmer Vernooij
Deal with recommend_upgrade argument to open_workingtree.
452
    def open_workingtree(self, recommend_upgrade=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
453
        raise NotLocalUrl(self.transport.base)
454
0.310.4 by Jelmer Vernooij
Implement RemoteControlDir.has_workingtree.
455
    def has_workingtree(self):
456
        return False
457
0.200.1489 by Jelmer Vernooij
More fixes to peel handling.
458
    def get_peeled(self, name):
459
        return self.get_refs_container().get_peeled(name)
460
0.200.1487 by Jelmer Vernooij
Use peeling.
461
    def get_refs_container(self):
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
462
        if self._refs is not None:
463
            return self._refs
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
464
        result = self.fetch_pack(lambda x: None, None,
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
465
            lambda x: None, lambda x: trace.mutter("git: %s" % x))
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
466
        self._refs = remote_refs_dict_to_container(
467
                result.refs, result.symrefs)
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
468
        return self._refs
469
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
470
    def push_branch(self, source, revision_id=None, overwrite=False,
471
                    remember=False, create_prefix=False, lossy=False,
472
                    name=None):
473
        """Push the source branch into this ControlDir."""
474
        if revision_id is None:
475
            # No revision supplied by the user, default to the branch
476
            # revision
477
            revision_id = source.last_revision()
478
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
479
        push_result = GitPushResult()
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
480
        push_result.workingtree_updated = None
481
        push_result.master_branch = None
482
        push_result.source_branch = source
483
        push_result.stacked_on = None
484
        push_result.branch_push_result = None
485
        repo = self.find_repository()
486
        refname = self._get_selected_ref(name)
0.407.1 by Jelmer Vernooij
Improve progress reporting.
487
        if isinstance(source, GitBranch) and lossy:
488
            raise errors.LossyPushToSameVCS(source.controldir, self)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
489
        source_store = get_object_store(source.repository)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
490
        with source_store.lock_read():
491
            def get_changed_refs(refs):
492
                self._refs = remote_refs_dict_to_container(refs)
493
                ret = dict(refs)
494
                # TODO(jelmer): Unpeel if necessary
0.406.4 by Jelmer Vernooij
Fall back to local branch for revno.
495
                push_result.new_original_revid = revision_id
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
496
                if lossy:
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
497
                    new_sha = source_store._lookup_revision_sha1(revision_id)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
498
                else:
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
499
                    new_sha = repo.lookup_bzr_revision_id(revision_id)[0]
500
                if not overwrite:
501
                    if remote_divergence(ret.get(refname), new_sha, source_store):
502
                        raise DivergedBranches(
503
                                source, self.open_branch(name, nascent_ok=True))
504
                ret[refname] = new_sha
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
505
                return ret
506
            if lossy:
507
                generate_pack_data = source_store.generate_lossy_pack_data
508
            else:
509
                generate_pack_data = source_store.generate_pack_data
510
            new_refs = self.send_pack(get_changed_refs, generate_pack_data)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
511
        push_result.new_revid = repo.lookup_foreign_revision_id(
512
                new_refs[refname])
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
513
        try:
514
            old_remote = self._refs[refname]
515
        except KeyError:
516
            old_remote = ZERO_SHA
517
        push_result.old_revid = repo.lookup_foreign_revision_id(old_remote)
518
        self._refs = remote_refs_dict_to_container(new_refs)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
519
        push_result.target_branch = self.open_branch(name)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
520
        if old_remote != ZERO_SHA:
521
            push_result.branch_push_result = GitBranchPushResult()
522
            push_result.branch_push_result.source_branch = source
523
            push_result.branch_push_result.target_branch = push_result.target_branch
524
            push_result.branch_push_result.local_branch = None
525
            push_result.branch_push_result.master_branch = push_result.target_branch
526
            push_result.branch_push_result.old_revid = push_result.old_revid
527
            push_result.branch_push_result.new_revid = push_result.new_revid
0.406.4 by Jelmer Vernooij
Fall back to local branch for revno.
528
            push_result.branch_push_result.new_original_revid = push_result.new_original_revid
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
529
        if source.get_push_location() is None or remember:
530
            source.set_push_location(push_result.target_branch.base)
531
        return push_result
532
0.409.1 by Jelmer Vernooij
Don't probe for commondir over remote transport.
533
    def _find_commondir(self):
534
        # There is no way to find the commondir, if there is any.
535
        return self
536
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
537
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
538
class EmptyObjectStoreIterator(dict):
539
540
    def iterobjects(self):
541
        return []
542
543
0.200.218 by Jelmer Vernooij
Simplify TemporaryPack implementation.
544
class TemporaryPackIterator(Pack):
545
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
546
    def __init__(self, path, resolve_ext_ref):
0.279.1 by William Grant
Support thin packs in fetch_pack and send_pack, since dulwich now handles them properly.
547
        super(TemporaryPackIterator, self).__init__(
548
            path, resolve_ext_ref=resolve_ext_ref)
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
549
        self._idx_load = lambda: self._idx_load_or_generate(self._idx_path)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
550
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
551
    def _idx_load_or_generate(self, path):
552
        if not os.path.exists(path):
553
            pb = ui.ui_factory.nested_progress_bar()
554
            try:
555
                def report_progress(cur, total):
556
                    pb.update("generating index", cur, total)
557
                self.data.create_index(path,
558
                    progress=report_progress)
559
            finally:
560
                pb.finished()
561
        return load_pack_index(path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
562
563
    def __del__(self):
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
564
        if self._idx is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
565
            self._idx.close()
566
            os.remove(self._idx_path)
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
567
        if self._data is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
568
            self._data.close()
569
            os.remove(self._data_path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
570
571
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
572
class BzrGitHttpClient(dulwich.client.HttpGitClient):
573
574
    def __init__(self, transport, *args, **kwargs):
575
        self.transport = transport
576
        super(BzrGitHttpClient, self).__init__(transport.external_url(), *args, **kwargs)
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
577
578
    def _http_request(self, url, headers=None, data=None,
579
                      allow_compression=False):
580
        """Perform HTTP request.
581
582
        :param url: Request URL.
583
        :param headers: Optional custom headers to override defaults.
584
        :param data: Request data.
585
        :param allow_compression: Allow GZipped communication.
586
        :return: Tuple (`response`, `read`), where response is an `urllib3`
587
            response object with additional `content_type` and
588
            `redirect_location` properties, and `read` is a consumable read
589
            method for the response data.
590
        """
591
        from breezy.transport.http._urllib2_wrappers import Request
592
        headers['User-agent'] = user_agent_for_github()
593
        headers["Pragma"] = "no-cache"
594
        if allow_compression:
595
            headers["Accept-Encoding"] = "gzip"
596
        else:
597
            headers["Accept-Encoding"] = "identity"
598
599
        request = Request(
600
            ('GET' if data is None else 'POST'),
601
            url, data, headers,
602
            accepted_errors=[200, 404])
603
604
        response = self.transport._perform(request)
605
606
        if response.code == 404:
607
            raise NotGitRepository()
608
        elif response.code != 200:
609
            raise GitProtocolError("unexpected http resp %d for %s" %
610
                                   (response.code, url))
611
612
        # TODO: Optimization available by adding `preload_content=False` to the
613
        # request and just passing the `read` method on instead of going via
614
        # `BytesIO`, if we can guarantee that the entire response is consumed
615
        # before issuing the next to still allow for connection reuse from the
616
        # pool.
617
        if response.getheader("Content-Encoding") == "gzip":
618
            read = gzip.GzipFile(fileobj=response).read
619
        else:
620
            read = response.read
621
622
        class WrapResponse(object):
623
624
            def __init__(self, response):
625
                self._response = response
626
                self.status = response.code
627
                self.content_type = response.getheader("Content-Type")
628
                self.redirect_location = response.geturl()
629
630
            def close(self):
631
                self._response.close()
632
633
        return WrapResponse(response), read
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
634
635
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
636
class RemoteGitControlDirFormat(GitControlDirFormat):
637
    """The .git directory control format."""
638
639
    supports_workingtrees = False
640
641
    @classmethod
642
    def _known_formats(self):
643
        return set([RemoteGitControlDirFormat()])
644
0.295.1 by Jelmer Vernooij
Split up branch formats.
645
    def get_branch_format(self):
646
        return RemoteGitBranchFormat()
647
0.200.1413 by Jelmer Vernooij
Fix is_initializable()
648
    def is_initializable(self):
649
        return False
650
651
    def is_supported(self):
652
        return True
653
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
654
    def open(self, transport, _found=None):
655
        """Open this directory.
656
657
        """
658
        # we dont grok readonly - git isn't integrated with transport.
659
        url = transport.base
660
        if url.startswith('readonly+'):
661
            url = url[len('readonly+'):]
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
662
        scheme = urlparse.urlsplit(transport.external_url())[0]
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
663
        if isinstance(transport, GitSmartTransport):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
664
            client = transport._get_client()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
665
            client_path = transport._get_path()
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
666
        elif scheme in ("http", "https"):
667
            client = BzrGitHttpClient(transport)
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
668
            client_path, _ = urlutils.split_segment_parameters(transport._path)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
669
        elif scheme == 'file':
670
            client = dulwich.client.LocalGitClient()
671
            client_path = transport.local_abspath('.')
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
672
        else:
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
673
            raise NotBranchError(transport.base)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
674
        if not _found:
675
            pass # TODO(jelmer): Actually probe for something
676
        return RemoteGitDir(transport, self, client, client_path)
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
677
678
    def get_format_description(self):
679
        return "Remote Git Repository"
680
681
    def initialize_on_transport(self, transport):
682
        raise UninitializableFormat(self)
683
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
684
    def supports_transport(self, transport):
685
        try:
686
            external_url = transport.external_url()
687
        except InProcessTransport:
688
            raise NotBranchError(path=transport.base)
689
        return (external_url.startswith("http:") or
690
                external_url.startswith("https:") or
691
                external_url.startswith("git+") or
692
                external_url.startswith("git:"))
693
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
694
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
695
class RemoteGitRepository(GitRepository):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
696
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
697
    @property
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
698
    def user_url(self):
699
        return self.control_url
700
0.200.1288 by Jelmer Vernooij
Properly raise GitRemoteNotSupported from RemoteGitRepository.
701
    def get_parent_map(self, revids):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
702
        raise GitSmartRemoteNotSupported(self.get_parent_map, self)
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
703
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
704
    def fetch_pack(self, determine_wants, graph_walker, pack_data,
0.200.155 by Jelmer Vernooij
Fix formatting, remove catch-all for exceptions when opening local repositories.
705
                   progress=None):
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
706
        return self.controldir.fetch_pack(determine_wants, graph_walker,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
707
                                          pack_data, progress)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
708
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
709
    def send_pack(self, get_changed_refs, generate_pack_data):
710
        return self.controldir.send_pack(get_changed_refs, generate_pack_data)
0.200.427 by Jelmer Vernooij
make send_pack accessible.
711
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
712
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
713
                      progress=None):
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
714
        fd, path = tempfile.mkstemp(suffix=".pack")
0.200.1299 by Jelmer Vernooij
Make sure file gets closed.
715
        try:
716
            self.fetch_pack(determine_wants, graph_walker,
717
                lambda x: os.write(fd, x), progress)
718
        finally:
719
            os.close(fd)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
720
        if os.path.getsize(path) == 0:
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
721
            return EmptyObjectStoreIterator()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
722
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
723
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
724
    def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
725
        # This won't work for any round-tripped bzr revisions, but it's a start..
726
        try:
727
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
728
        except InvalidRevisionId:
729
            raise NoSuchRevision(self, bzr_revid)
730
0.252.48 by Jelmer Vernooij
Implement lookup_foreign_revision for remote branches.
731
    def lookup_foreign_revision_id(self, foreign_revid, mapping=None):
732
        """Lookup a revision id.
733
734
        """
735
        if mapping is None:
736
            mapping = self.get_mapping()
737
        # Not really an easy way to parse foreign revids here..
738
        return mapping.revision_id_foreign_to_bzr(foreign_revid)
739
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
740
    def revision_tree(self, revid):
741
        raise GitSmartRemoteNotSupported(self.revision_tree, self)
742
0.200.1481 by Jelmer Vernooij
'Implement' RemoteGitRepository.get_revisions.
743
    def get_revisions(self, revids):
744
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
745
0.200.1557 by Jelmer Vernooij
Implement RemoteGitRepository.has_revisions.
746
    def has_revisions(self, revids):
747
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
748
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
749
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
750
class RemoteGitTagDict(GitTags):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
751
752
    def set_tag(self, name, revid):
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
753
        sha = self.branch.lookup_bzr_revision_id(revid)[0]
754
        self._set_ref(name, sha)
755
756
    def delete_tag(self, name):
757
        self._set_ref(name, dulwich.client.ZERO_SHA)
758
759
    def _set_ref(self, name, sha):
760
        ref = tag_name_to_ref(name)
761
        def get_changed_refs(old_refs):
762
            ret = dict(old_refs)
763
            if sha == dulwich.client.ZERO_SHA and ref not in ret:
764
                raise NoSuchTag(name)
765
            ret[ref] = sha
766
            return ret
767
        def generate_pack_data(have, want, ofs_delta=False):
768
            return pack_objects_to_data([])
769
        self.repository.send_pack(get_changed_refs, generate_pack_data)
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
770
771
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
772
class RemoteGitBranch(GitBranch):
773
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
774
    def __init__(self, controldir, repository, name):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
775
        self._sha = None
0.295.1 by Jelmer Vernooij
Split up branch formats.
776
        super(RemoteGitBranch, self).__init__(controldir, repository, name,
777
                RemoteGitBranchFormat())
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
778
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
779
    def last_revision_info(self):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
780
        raise GitSmartRemoteNotSupported(self.last_revision_info, self)
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
781
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
782
    @property
783
    def user_url(self):
784
        return self.control_url
785
786
    @property
787
    def control_url(self):
788
        return self.base
789
0.200.1436 by Jelmer Vernooij
Raise UnsupportedOperation for `Branch.revision_id_to_dotted_revno`,
790
    def revision_id_to_revno(self, revision_id):
791
        raise GitSmartRemoteNotSupported(self.revision_id_to_revno, self)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
792
793
    def last_revision(self):
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
794
        return self.lookup_foreign_revision_id(self.head)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
795
796
    @property
797
    def head(self):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
798
        if self._sha is not None:
799
            return self._sha
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
800
        refs = self.controldir.get_refs_container()
0.200.1561 by Jelmer Vernooij
Some fixes for colocated branch handling.
801
        name = branch_name_to_ref(self.name)
0.200.1386 by Jelmer Vernooij
Friendlier message if HEAD is not found.
802
        try:
803
            self._sha = refs[name]
804
        except KeyError:
805
            raise NoSuchRef(name, self.repository.user_url, refs)
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
806
        return self._sha
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
807
0.200.169 by Jelmer Vernooij
Fix branch cloning.
808
    def _synchronize_history(self, destination, revision_id):
809
        """See Branch._synchronize_history()."""
810
        destination.generate_revision_history(self.last_revision())
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
811
0.289.1 by Jelmer Vernooij
No parent location for remote repos.
812
    def _get_parent_location(self):
813
        return None
814
0.200.499 by Jelmer Vernooij
Implement RemoteBranch.{get,set}_push_location.
815
    def get_push_location(self):
816
        return None
817
818
    def set_push_location(self, url):
819
        pass
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
820
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
821
    def _iter_tag_refs(self):
822
        """Iterate over the tag refs.
823
824
        :param refs: Refs dictionary (name -> git sha1)
825
        :return: iterator over (ref_name, tag_name, peeled_sha1, unpeeled_sha1)
826
        """
827
        refs = self.controldir.get_refs_container()
828
        for ref_name, unpeeled in refs.as_dict().iteritems():
829
            try:
830
                tag_name = ref_to_tag_name(ref_name)
831
            except (ValueError, UnicodeDecodeError):
832
                continue
833
            peeled = refs.get_peeled(ref_name)
834
            if peeled is None:
835
                try:
836
                    peeled = refs.peel_sha(unpeeled).id
837
                except KeyError:
838
                    # Let's just hope it's a commit
839
                    peeled = unpeeled
840
            if type(tag_name) is not unicode:
841
                raise TypeError(tag_name)
842
            yield (ref_name, tag_name, peeled, unpeeled)
843
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
844
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
845
def remote_refs_dict_to_container(refs_dict, symrefs_dict={}):
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
846
    base = {}
847
    peeled = {}
848
    for k, v in refs_dict.iteritems():
849
        if is_peeled(k):
850
            peeled[k[:-3]] = v
851
        else:
852
            base[k] = v
853
            peeled[k] = v
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
854
    for name, target in symrefs_dict.iteritems():
855
        base[name] = SYMREF + target
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
856
    ret = DictRefsContainer(base)
857
    ret._peeled = peeled
858
    return ret