/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
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
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
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
33
from ..push import (
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
34
    PushResult,
35
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
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
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
50
from ..revisiontree import RevisionTree
6986.2.2 by Jelmer Vernooij
Merge trunk.
51
from ..sixish import text_type
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
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):
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
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):
7018.3.2 by Jelmer Vernooij
Fix some git tests.
337
        text = text.rstrip(b"\r\n")
338
        text = text.decode('utf-8')
0.407.1 by Jelmer Vernooij
Improve progress reporting.
339
        if text.startswith('error: '):
7018.3.2 by Jelmer Vernooij
Fix some git tests.
340
            trace.show_error('git: %s', text[len(b'error: '):])
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
341
        else:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
342
            trace.mutter("git: %s", text)
343
            g = self._GIT_PROGRESS_PARTIAL_RE.match(text)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
344
            if g is not None:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
345
                (text, pct, current, total) = g.groups()
346
                self.pb.update(text, int(current), int(total))
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
347
            else:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
348
                g = self._GIT_PROGRESS_TOTAL_RE.match(text)
349
                if g is not None:
350
                    (text, total) = g.groups()
351
                    self.pb.update(text, None, int(total))
352
                else:
353
                    trace.note("%s", text)
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
354
355
0.200.148 by Jelmer Vernooij
Share more infrastructure between LocalGitDir and RemoteGitDir.
356
class RemoteGitDir(GitDir):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
357
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
358
    def __init__(self, transport, format, client, client_path):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
359
        self._format = format
360
        self.root_transport = transport
361
        self.transport = transport
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
362
        self._mode_check_done = None
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
363
        self._client = client
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
364
        self._client_path = client_path
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
365
        self.base = self.root_transport.base
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
366
        self._refs = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
367
0.322.1 by Jelmer Vernooij
Fix access of remote git branches.
368
    @property
369
    def _gitrepository_class(self):
370
        return RemoteGitRepository
371
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
372
    def archive(self, format, committish, write_data, progress=None, write_error=None,
373
                subdirs=None, prefix=None):
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
374
        if format not in ('tar', 'zip'):
375
            raise errors.NoSuchExportFormat(format)
376
        if progress is None:
377
            pb = ui.ui_factory.nested_progress_bar()
378
            progress = DefaultProgressReporter(pb).progress
379
        else:
380
            pb = None
381
        try:
382
            self._client.archive(self._client_path, committish,
383
                write_data, progress, write_error, format=format,
384
                subdirs=subdirs, prefix=prefix)
385
        except GitProtocolError as e:
386
            raise parse_git_error(self.transport.external_url(), e)
387
        finally:
388
            if pb is not None:
389
                pb.finished()
390
0.200.1335 by Jelmer Vernooij
Move _get_client.
391
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
392
        if progress is None:
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
393
            pb = ui.ui_factory.nested_progress_bar()
0.407.1 by Jelmer Vernooij
Improve progress reporting.
394
            progress = DefaultProgressReporter(pb).progress
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
395
        else:
396
            pb = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
397
        try:
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
398
            result = self._client.fetch_pack(self._client_path, determine_wants,
0.200.1335 by Jelmer Vernooij
Move _get_client.
399
                graph_walker, pack_data, progress)
0.376.1 by Jelmer Vernooij
Add tests for remote operations.
400
            if result.refs is None:
401
                result.refs = {}
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
402
            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.
403
            return result
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
404
        except GitProtocolError as e:
0.200.1335 by Jelmer Vernooij
Move _get_client.
405
            raise parse_git_error(self.transport.external_url(), e)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
406
        finally:
407
            if pb is not None:
408
                pb.finished()
0.200.1335 by Jelmer Vernooij
Move _get_client.
409
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
410
    def send_pack(self, get_changed_refs, generate_pack_data, progress=None):
411
        if progress is None:
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
412
            pb = ui.ui_factory.nested_progress_bar()
0.407.1 by Jelmer Vernooij
Improve progress reporting.
413
            progress = DefaultProgressReporter(pb).progress
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
414
        else:
415
            pb = None
0.419.1 by Jelmer Vernooij
Simplify pushing to Git directories.
416
        def get_changed_refs_wrapper(refs):
417
            # TODO(jelmer): This drops symref information
418
            self._refs = remote_refs_dict_to_container(refs)
419
            return get_changed_refs(refs)
0.200.1335 by Jelmer Vernooij
Move _get_client.
420
        try:
0.419.1 by Jelmer Vernooij
Simplify pushing to Git directories.
421
            return self._client.send_pack(self._client_path,
422
                    get_changed_refs_wrapper, generate_pack_data, progress)
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
423
        except GitProtocolError as e:
0.200.1335 by Jelmer Vernooij
Move _get_client.
424
            raise parse_git_error(self.transport.external_url(), e)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
425
        finally:
426
            if pb is not None:
427
                pb.finished()
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
428
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
429
    def create_branch(self, name=None, repository=None,
430
                      append_revisions_only=None, ref=None):
431
        refname = self._get_selected_ref(name, ref)
432
        if refname != b'HEAD' and refname in self.get_refs_container():
433
            raise AlreadyBranchError(self.user_url)
434
        if refname in self.get_refs_container():
435
            ref_chain, unused_sha = self.get_refs_container().follow(self._get_selected_ref(None))
436
            if ref_chain[0] == b'HEAD':
437
                refname = ref_chain[1]
438
        repo = self.open_repository()
439
        return RemoteGitBranch(self, repo, refname)
440
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
441
    def destroy_branch(self, name=None):
442
        refname = self._get_selected_ref(name)
443
        def get_changed_refs(old_refs):
444
            ret = dict(old_refs)
445
            if not refname in ret:
0.200.1395 by Jelmer Vernooij
Fix error reporting.
446
                raise NotBranchError(self.user_url)
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
447
            ret[refname] = dulwich.client.ZERO_SHA
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
448
            return ret
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
449
        def generate_pack_data(have, want, ofs_delta=False):
450
            return pack_objects_to_data([])
451
        self.send_pack(get_changed_refs, generate_pack_data)
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
452
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
453
    @property
454
    def user_url(self):
455
        return self.control_url
456
0.200.1314 by Jelmer Vernooij
Provide RemoteGitDir.user_transport.
457
    @property
458
    def user_transport(self):
459
        return self.root_transport
460
0.200.1395 by Jelmer Vernooij
Fix error reporting.
461
    @property
462
    def control_url(self):
463
        return self.control_transport.base
464
465
    @property
466
    def control_transport(self):
467
        return self.root_transport
468
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
469
    def open_repository(self):
0.200.1415 by Jelmer Vernooij
Fix lock files for remote directories.
470
        return RemoteGitRepository(self)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
471
0.200.1310 by Jelmer Vernooij
Add _get_selected_ref method.
472
    def open_branch(self, name=None, unsupported=False,
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
473
            ignore_fallbacks=False, ref=None, possible_transports=None,
474
            nascent_ok=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
475
        repo = self.open_repository()
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
476
        ref = self._get_selected_ref(name, ref)
477
        if not nascent_ok and ref not in self.get_refs_container():
478
            raise NotBranchError(self.root_transport.base,
479
                    controldir=self)
480
        ref_chain, unused_sha = self.get_refs_container().follow(ref)
481
        return RemoteGitBranch(self, repo, ref_chain[-1])
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
482
0.200.662 by Jelmer Vernooij
Deal with recommend_upgrade argument to open_workingtree.
483
    def open_workingtree(self, recommend_upgrade=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
484
        raise NotLocalUrl(self.transport.base)
485
0.310.4 by Jelmer Vernooij
Implement RemoteControlDir.has_workingtree.
486
    def has_workingtree(self):
487
        return False
488
0.200.1489 by Jelmer Vernooij
More fixes to peel handling.
489
    def get_peeled(self, name):
490
        return self.get_refs_container().get_peeled(name)
491
0.200.1487 by Jelmer Vernooij
Use peeling.
492
    def get_refs_container(self):
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
493
        if self._refs is not None:
494
            return self._refs
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
495
        result = self.fetch_pack(lambda x: None, None,
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
496
            lambda x: None, lambda x: trace.mutter("git: %s" % x))
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
497
        self._refs = remote_refs_dict_to_container(
498
                result.refs, result.symrefs)
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
499
        return self._refs
500
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
501
    def push_branch(self, source, revision_id=None, overwrite=False,
502
                    remember=False, create_prefix=False, lossy=False,
503
                    name=None):
504
        """Push the source branch into this ControlDir."""
505
        if revision_id is None:
506
            # No revision supplied by the user, default to the branch
507
            # revision
508
            revision_id = source.last_revision()
509
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
510
        push_result = GitPushResult()
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
511
        push_result.workingtree_updated = None
512
        push_result.master_branch = None
513
        push_result.source_branch = source
514
        push_result.stacked_on = None
515
        push_result.branch_push_result = None
516
        repo = self.find_repository()
517
        refname = self._get_selected_ref(name)
0.407.1 by Jelmer Vernooij
Improve progress reporting.
518
        if isinstance(source, GitBranch) and lossy:
519
            raise errors.LossyPushToSameVCS(source.controldir, self)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
520
        source_store = get_object_store(source.repository)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
521
        with source_store.lock_read():
522
            def get_changed_refs(refs):
523
                self._refs = remote_refs_dict_to_container(refs)
524
                ret = dict(refs)
525
                # TODO(jelmer): Unpeel if necessary
0.406.4 by Jelmer Vernooij
Fall back to local branch for revno.
526
                push_result.new_original_revid = revision_id
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
527
                if lossy:
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
528
                    new_sha = source_store._lookup_revision_sha1(revision_id)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
529
                else:
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
530
                    new_sha = repo.lookup_bzr_revision_id(revision_id)[0]
531
                if not overwrite:
532
                    if remote_divergence(ret.get(refname), new_sha, source_store):
533
                        raise DivergedBranches(
534
                                source, self.open_branch(name, nascent_ok=True))
535
                ret[refname] = new_sha
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
536
                return ret
537
            if lossy:
538
                generate_pack_data = source_store.generate_lossy_pack_data
539
            else:
540
                generate_pack_data = source_store.generate_pack_data
541
            new_refs = self.send_pack(get_changed_refs, generate_pack_data)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
542
        push_result.new_revid = repo.lookup_foreign_revision_id(
543
                new_refs[refname])
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
544
        try:
545
            old_remote = self._refs[refname]
546
        except KeyError:
547
            old_remote = ZERO_SHA
548
        push_result.old_revid = repo.lookup_foreign_revision_id(old_remote)
549
        self._refs = remote_refs_dict_to_container(new_refs)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
550
        push_result.target_branch = self.open_branch(name)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
551
        if old_remote != ZERO_SHA:
552
            push_result.branch_push_result = GitBranchPushResult()
553
            push_result.branch_push_result.source_branch = source
554
            push_result.branch_push_result.target_branch = push_result.target_branch
555
            push_result.branch_push_result.local_branch = None
556
            push_result.branch_push_result.master_branch = push_result.target_branch
557
            push_result.branch_push_result.old_revid = push_result.old_revid
558
            push_result.branch_push_result.new_revid = push_result.new_revid
0.406.4 by Jelmer Vernooij
Fall back to local branch for revno.
559
            push_result.branch_push_result.new_original_revid = push_result.new_original_revid
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
560
        if source.get_push_location() is None or remember:
561
            source.set_push_location(push_result.target_branch.base)
562
        return push_result
563
0.409.1 by Jelmer Vernooij
Don't probe for commondir over remote transport.
564
    def _find_commondir(self):
565
        # There is no way to find the commondir, if there is any.
566
        return self
567
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
568
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
569
class EmptyObjectStoreIterator(dict):
570
571
    def iterobjects(self):
572
        return []
573
574
0.200.218 by Jelmer Vernooij
Simplify TemporaryPack implementation.
575
class TemporaryPackIterator(Pack):
576
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
577
    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.
578
        super(TemporaryPackIterator, self).__init__(
579
            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.
580
        self._idx_load = lambda: self._idx_load_or_generate(self._idx_path)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
581
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
582
    def _idx_load_or_generate(self, path):
583
        if not os.path.exists(path):
584
            pb = ui.ui_factory.nested_progress_bar()
585
            try:
586
                def report_progress(cur, total):
587
                    pb.update("generating index", cur, total)
588
                self.data.create_index(path,
589
                    progress=report_progress)
590
            finally:
591
                pb.finished()
592
        return load_pack_index(path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
593
594
    def __del__(self):
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
595
        if self._idx is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
596
            self._idx.close()
597
            os.remove(self._idx_path)
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
598
        if self._data is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
599
            self._data.close()
600
            os.remove(self._data_path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
601
602
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
603
class BzrGitHttpClient(dulwich.client.HttpGitClient):
604
605
    def __init__(self, transport, *args, **kwargs):
606
        self.transport = transport
607
        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.
608
609
    def _http_request(self, url, headers=None, data=None,
610
                      allow_compression=False):
611
        """Perform HTTP request.
612
613
        :param url: Request URL.
614
        :param headers: Optional custom headers to override defaults.
615
        :param data: Request data.
616
        :param allow_compression: Allow GZipped communication.
617
        :return: Tuple (`response`, `read`), where response is an `urllib3`
618
            response object with additional `content_type` and
619
            `redirect_location` properties, and `read` is a consumable read
620
            method for the response data.
621
        """
622
        from breezy.transport.http._urllib2_wrappers import Request
623
        headers['User-agent'] = user_agent_for_github()
624
        headers["Pragma"] = "no-cache"
625
        if allow_compression:
626
            headers["Accept-Encoding"] = "gzip"
627
        else:
628
            headers["Accept-Encoding"] = "identity"
629
630
        request = Request(
631
            ('GET' if data is None else 'POST'),
632
            url, data, headers,
633
            accepted_errors=[200, 404])
634
635
        response = self.transport._perform(request)
636
637
        if response.code == 404:
638
            raise NotGitRepository()
639
        elif response.code != 200:
640
            raise GitProtocolError("unexpected http resp %d for %s" %
641
                                   (response.code, url))
642
643
        # TODO: Optimization available by adding `preload_content=False` to the
644
        # request and just passing the `read` method on instead of going via
645
        # `BytesIO`, if we can guarantee that the entire response is consumed
646
        # before issuing the next to still allow for connection reuse from the
647
        # pool.
648
        if response.getheader("Content-Encoding") == "gzip":
649
            read = gzip.GzipFile(fileobj=response).read
650
        else:
651
            read = response.read
652
653
        class WrapResponse(object):
654
655
            def __init__(self, response):
656
                self._response = response
657
                self.status = response.code
658
                self.content_type = response.getheader("Content-Type")
659
                self.redirect_location = response.geturl()
660
661
            def close(self):
662
                self._response.close()
663
664
        return WrapResponse(response), read
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
665
666
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
667
class RemoteGitControlDirFormat(GitControlDirFormat):
668
    """The .git directory control format."""
669
670
    supports_workingtrees = False
671
672
    @classmethod
673
    def _known_formats(self):
674
        return set([RemoteGitControlDirFormat()])
675
0.295.1 by Jelmer Vernooij
Split up branch formats.
676
    def get_branch_format(self):
677
        return RemoteGitBranchFormat()
678
0.200.1413 by Jelmer Vernooij
Fix is_initializable()
679
    def is_initializable(self):
680
        return False
681
682
    def is_supported(self):
683
        return True
684
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
685
    def open(self, transport, _found=None):
686
        """Open this directory.
687
688
        """
689
        # we dont grok readonly - git isn't integrated with transport.
690
        url = transport.base
691
        if url.startswith('readonly+'):
692
            url = url[len('readonly+'):]
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
693
        scheme = urlparse.urlsplit(transport.external_url())[0]
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
694
        if isinstance(transport, GitSmartTransport):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
695
            client = transport._get_client()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
696
            client_path = transport._get_path()
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
697
        elif scheme in ("http", "https"):
698
            client = BzrGitHttpClient(transport)
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
699
            client_path, _ = urlutils.split_segment_parameters(transport._path)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
700
        elif scheme == 'file':
701
            client = dulwich.client.LocalGitClient()
702
            client_path = transport.local_abspath('.')
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
703
        else:
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
704
            raise NotBranchError(transport.base)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
705
        if not _found:
706
            pass # TODO(jelmer): Actually probe for something
707
        return RemoteGitDir(transport, self, client, client_path)
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
708
709
    def get_format_description(self):
710
        return "Remote Git Repository"
711
712
    def initialize_on_transport(self, transport):
713
        raise UninitializableFormat(self)
714
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
715
    def supports_transport(self, transport):
716
        try:
717
            external_url = transport.external_url()
718
        except InProcessTransport:
719
            raise NotBranchError(path=transport.base)
720
        return (external_url.startswith("http:") or
721
                external_url.startswith("https:") or
722
                external_url.startswith("git+") or
723
                external_url.startswith("git:"))
724
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
725
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
726
class GitRemoteRevisionTree(RevisionTree):
727
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
728
    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.
729
        """Create an archive of this tree.
730
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
731
        :param format: Format name (e.g. 'tar')
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
732
        :param name: target file name
733
        :param root: Root directory name (or None)
734
        :param subdir: Subdirectory to export (or None)
735
        :return: Iterator over archive chunks
736
        """
737
        commit = self._repository.lookup_bzr_revision_id(
738
            self.get_revision_id())[0]
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
739
        f = tempfile.SpooledTemporaryFile()
740
        # git-upload-archive(1) generaly only supports refs. So let's see if we
741
        # can find one.
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
742
        reverse_refs = {
743
                v: k for (k, v) in
744
                self._repository.controldir.get_refs_container().as_dict().items()}
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
745
        try:
746
            committish = reverse_refs[commit]
747
        except KeyError:
748
            # No? Maybe the user has uploadArchive.allowUnreachable enabled.
749
            # Let's hope for the best.
750
            committish = commit
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
751
        self._repository.archive(
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
752
                format, committish, f.write,
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
753
                subdirs=([subdir] if subdir else None),
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
754
                prefix=(root+'/') if root else '')
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
755
        f.seek(0)
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
756
        return osutils.file_iterator(f)
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
757
758
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
759
class RemoteGitRepository(GitRepository):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
760
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
761
    @property
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
762
    def user_url(self):
763
        return self.control_url
764
0.200.1288 by Jelmer Vernooij
Properly raise GitRemoteNotSupported from RemoteGitRepository.
765
    def get_parent_map(self, revids):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
766
        raise GitSmartRemoteNotSupported(self.get_parent_map, self)
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
767
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
768
    def archive(self, *args, **kwargs):
769
        return self.controldir.archive(*args, **kwargs)
770
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
771
    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.
772
                   progress=None):
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
773
        return self.controldir.fetch_pack(determine_wants, graph_walker,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
774
                                          pack_data, progress)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
775
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
776
    def send_pack(self, get_changed_refs, generate_pack_data):
777
        return self.controldir.send_pack(get_changed_refs, generate_pack_data)
0.200.427 by Jelmer Vernooij
make send_pack accessible.
778
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
779
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
780
                      progress=None):
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
781
        fd, path = tempfile.mkstemp(suffix=".pack")
0.200.1299 by Jelmer Vernooij
Make sure file gets closed.
782
        try:
783
            self.fetch_pack(determine_wants, graph_walker,
784
                lambda x: os.write(fd, x), progress)
785
        finally:
786
            os.close(fd)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
787
        if os.path.getsize(path) == 0:
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
788
            return EmptyObjectStoreIterator()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
789
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
790
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
791
    def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
792
        # This won't work for any round-tripped bzr revisions, but it's a start..
793
        try:
794
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
795
        except InvalidRevisionId:
796
            raise NoSuchRevision(self, bzr_revid)
797
0.252.48 by Jelmer Vernooij
Implement lookup_foreign_revision for remote branches.
798
    def lookup_foreign_revision_id(self, foreign_revid, mapping=None):
799
        """Lookup a revision id.
800
801
        """
802
        if mapping is None:
803
            mapping = self.get_mapping()
804
        # Not really an easy way to parse foreign revids here..
805
        return mapping.revision_id_foreign_to_bzr(foreign_revid)
806
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
807
    def revision_tree(self, revid):
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
808
        return GitRemoteRevisionTree(self, revid)
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
809
0.200.1481 by Jelmer Vernooij
'Implement' RemoteGitRepository.get_revisions.
810
    def get_revisions(self, revids):
811
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
812
0.200.1557 by Jelmer Vernooij
Implement RemoteGitRepository.has_revisions.
813
    def has_revisions(self, revids):
814
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
815
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
816
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
817
class RemoteGitTagDict(GitTags):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
818
819
    def set_tag(self, name, revid):
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
820
        sha = self.branch.lookup_bzr_revision_id(revid)[0]
821
        self._set_ref(name, sha)
822
823
    def delete_tag(self, name):
824
        self._set_ref(name, dulwich.client.ZERO_SHA)
825
826
    def _set_ref(self, name, sha):
827
        ref = tag_name_to_ref(name)
828
        def get_changed_refs(old_refs):
829
            ret = dict(old_refs)
830
            if sha == dulwich.client.ZERO_SHA and ref not in ret:
831
                raise NoSuchTag(name)
832
            ret[ref] = sha
833
            return ret
834
        def generate_pack_data(have, want, ofs_delta=False):
835
            return pack_objects_to_data([])
836
        self.repository.send_pack(get_changed_refs, generate_pack_data)
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
837
838
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
839
class RemoteGitBranch(GitBranch):
840
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
841
    def __init__(self, controldir, repository, name):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
842
        self._sha = None
0.295.1 by Jelmer Vernooij
Split up branch formats.
843
        super(RemoteGitBranch, self).__init__(controldir, repository, name,
844
                RemoteGitBranchFormat())
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
845
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
846
    def last_revision_info(self):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
847
        raise GitSmartRemoteNotSupported(self.last_revision_info, self)
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
848
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
849
    @property
850
    def user_url(self):
851
        return self.control_url
852
853
    @property
854
    def control_url(self):
855
        return self.base
856
0.200.1436 by Jelmer Vernooij
Raise UnsupportedOperation for `Branch.revision_id_to_dotted_revno`,
857
    def revision_id_to_revno(self, revision_id):
858
        raise GitSmartRemoteNotSupported(self.revision_id_to_revno, self)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
859
860
    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.
861
        return self.lookup_foreign_revision_id(self.head)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
862
863
    @property
864
    def head(self):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
865
        if self._sha is not None:
866
            return self._sha
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
867
        refs = self.controldir.get_refs_container()
0.200.1561 by Jelmer Vernooij
Some fixes for colocated branch handling.
868
        name = branch_name_to_ref(self.name)
0.200.1386 by Jelmer Vernooij
Friendlier message if HEAD is not found.
869
        try:
870
            self._sha = refs[name]
871
        except KeyError:
872
            raise NoSuchRef(name, self.repository.user_url, refs)
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
873
        return self._sha
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
874
0.200.169 by Jelmer Vernooij
Fix branch cloning.
875
    def _synchronize_history(self, destination, revision_id):
876
        """See Branch._synchronize_history()."""
877
        destination.generate_revision_history(self.last_revision())
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
878
0.289.1 by Jelmer Vernooij
No parent location for remote repos.
879
    def _get_parent_location(self):
880
        return None
881
0.200.499 by Jelmer Vernooij
Implement RemoteBranch.{get,set}_push_location.
882
    def get_push_location(self):
883
        return None
884
885
    def set_push_location(self, url):
886
        pass
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
887
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
888
    def _iter_tag_refs(self):
889
        """Iterate over the tag refs.
890
891
        :param refs: Refs dictionary (name -> git sha1)
892
        :return: iterator over (ref_name, tag_name, peeled_sha1, unpeeled_sha1)
893
        """
894
        refs = self.controldir.get_refs_container()
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
895
        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.
896
            try:
897
                tag_name = ref_to_tag_name(ref_name)
898
            except (ValueError, UnicodeDecodeError):
899
                continue
900
            peeled = refs.get_peeled(ref_name)
901
            if peeled is None:
902
                try:
903
                    peeled = refs.peel_sha(unpeeled).id
904
                except KeyError:
905
                    # Let's just hope it's a commit
906
                    peeled = unpeeled
6973.6.2 by Jelmer Vernooij
Fix more tests.
907
            if not isinstance(tag_name, text_type):
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
908
                raise TypeError(tag_name)
909
            yield (ref_name, tag_name, peeled, unpeeled)
910
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
911
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
912
def remote_refs_dict_to_container(refs_dict, symrefs_dict={}):
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
913
    base = {}
914
    peeled = {}
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
915
    for k, v in refs_dict.items():
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
916
        if is_peeled(k):
917
            peeled[k[:-3]] = v
918
        else:
919
            base[k] = v
920
            peeled[k] = v
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
921
    for name, target in symrefs_dict.items():
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
922
        base[name] = SYMREF + target
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
923
    ret = DictRefsContainer(base)
924
    ret._peeled = peeled
925
    return ret