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