/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/git/remote.py

  • Committer: Breezy landing bot
  • Author(s): Jelmer Vernooij
  • Date: 2020-07-28 02:47:10 UTC
  • mfrom: (7519.1.1 merge-3.1)
  • Revision ID: breezy.the.bot@gmail.com-20200728024710-a2ylds219f1lsl62
Merge lp:brz/3.1.

Merged from https://code.launchpad.net/~jelmer/brz/merge-3.1/+merge/388173

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
"""Remote dirs, repositories and branches."""
18
18
 
19
 
from __future__ import absolute_import
20
 
 
21
19
import gzip
22
20
from io import BytesIO
23
21
import re
50
48
    )
51
49
from ..revision import NULL_REVISION
52
50
from ..revisiontree import RevisionTree
53
 
from ..sixish import (
54
 
    text_type,
55
 
    viewitems,
56
 
    )
57
51
from ..transport import (
58
52
    Transport,
59
53
    register_urlparse_netloc_protocol,
82
76
    NoSuchRef,
83
77
    )
84
78
from .mapping import (
 
79
    encode_git_path,
85
80
    mapping_registry,
86
81
    )
87
82
from .object_store import (
121
116
    )
122
117
import os
123
118
import select
124
 
import tempfile
125
119
 
126
 
try:
127
 
    import urllib.parse as urlparse
128
 
    from urllib.parse import splituser
129
 
except ImportError:
130
 
    import urlparse
131
 
    from urllib import splituser
 
120
import urllib.parse as urlparse
 
121
from urllib.parse import splituser
132
122
 
133
123
# urlparse only supports a limited number of schemes by default
134
124
register_urlparse_netloc_protocol('git')
214
204
    if re.match('(.+) is not a valid repository name',
215
205
                message.splitlines()[0]):
216
206
        return NotBranchError(url, message)
 
207
    if message == (
 
208
            'GitLab: You are not allowed to push code to protected branches '
 
209
            'on this project.'):
 
210
        return PermissionDenied(url, message)
217
211
    m = re.match(r'Permission to ([^ ]+) denied to ([^ ]+)\.', message)
218
212
    if m:
219
213
        return PermissionDenied(m.group(1), 'denied to %s' % m.group(2))
221
215
    return RemoteGitError(message)
222
216
 
223
217
 
 
218
def parse_git_hangup(url, e):
 
219
    """Parse the error lines from a git servers stderr on hangup.
 
220
 
 
221
    :param url: URL of the remote repository
 
222
    :param e: A HangupException
 
223
    """
 
224
    stderr_lines = getattr(e, 'stderr_lines', None)
 
225
    if not stderr_lines:
 
226
        return e
 
227
    if all(line.startswith(b'remote: ') for line in stderr_lines):
 
228
        stderr_lines = [
 
229
            line[len(b'remote: '):] for line in stderr_lines]
 
230
    interesting_lines = [
 
231
        line for line in stderr_lines
 
232
        if line and line.replace(b'=', b'')]
 
233
    if len(interesting_lines) == 1:
 
234
        interesting_line = interesting_lines[0]
 
235
        return parse_git_error(
 
236
            url, interesting_line.decode('utf-8', 'surrogateescape'))
 
237
    return RemoteGitError(
 
238
        b'\n'.join(stderr_lines).decode('utf-8', 'surrogateescape'))
 
239
 
 
240
 
224
241
class GitSmartTransport(Transport):
225
242
 
226
243
    def __init__(self, url, _client=None):
417
434
                write_error,
418
435
                format=(format.encode('ascii') if format else None),
419
436
                subdirs=subdirs,
420
 
                prefix=(prefix.encode('utf-8') if prefix else None))
 
437
                prefix=(encode_git_path(prefix) if prefix else None))
 
438
        except HangupException as e:
 
439
            raise parse_git_hangup(self.transport.external_url(), e)
421
440
        except GitProtocolError as e:
422
441
            raise parse_git_error(self.transport.external_url(), e)
423
442
        finally:
440
459
            self._refs = remote_refs_dict_to_container(
441
460
                result.refs, result.symrefs)
442
461
            return result
 
462
        except HangupException as e:
 
463
            raise parse_git_hangup(self.transport.external_url(), e)
443
464
        except GitProtocolError as e:
444
465
            raise parse_git_error(self.transport.external_url(), e)
445
466
        finally:
461
482
            return self._client.send_pack(
462
483
                self._client_path, get_changed_refs_wrapper,
463
484
                generate_pack_data, progress)
 
485
        except HangupException as e:
 
486
            raise parse_git_hangup(self.transport.external_url(), e)
464
487
        except GitProtocolError as e:
465
488
            raise parse_git_error(self.transport.external_url(), e)
466
489
        finally:
491
514
 
492
515
        def generate_pack_data(have, want, ofs_delta=False):
493
516
            return pack_objects_to_data([])
494
 
        self.send_pack(get_changed_refs, generate_pack_data)
 
517
        result = self.send_pack(get_changed_refs, generate_pack_data)
 
518
        if result is not None and not isinstance(result, dict):
 
519
            error = result.ref_status.get(refname)
 
520
            if error:
 
521
                raise RemoteGitError(error)
495
522
 
496
523
    @property
497
524
    def user_url(self):
561
588
            # No revision supplied by the user, default to the branch
562
589
            # revision
563
590
            revision_id = source.last_revision()
 
591
        else:
 
592
            if not source.repository.has_revision(revision_id):
 
593
                raise NoSuchRevision(source, revision_id)
564
594
 
565
595
        push_result = GitPushResult()
566
596
        push_result.workingtree_updated = None
599
629
                        source, self.open_branch(name, nascent_ok=True))
600
630
            ret[actual_refname] = new_sha
601
631
            if fetch_tags:
602
 
                for tagname, revid in viewitems(source.tags.get_tag_dict()):
 
632
                for tagname, revid in source.tags.get_tag_dict().items():
603
633
                    if tag_selector and not tag_selector(tagname):
604
634
                        continue
605
635
                    if lossy:
613
643
                            new_sha = repo.lookup_bzr_revision_id(revid)[0]
614
644
                        except errors.NoSuchRevision:
615
645
                            continue
 
646
                        else:
 
647
                            if not source.repository.has_revision(revid):
 
648
                                continue
616
649
                    ret[tag_name_to_ref(tagname)] = new_sha
617
650
            return ret
618
651
        with source_store.lock_read():
619
 
            if lossy:
620
 
                generate_pack_data = source_store.generate_lossy_pack_data
621
 
            else:
622
 
                generate_pack_data = source_store.generate_pack_data
623
 
            new_refs = self.send_pack(get_changed_refs, generate_pack_data)
 
652
            def generate_pack_data(have, want, progress=None,
 
653
                                   ofs_delta=True):
 
654
                git_repo = getattr(source.repository, '_git', None)
 
655
                if git_repo:
 
656
                    shallow = git_repo.get_shallow()
 
657
                else:
 
658
                    shallow = None
 
659
                if lossy:
 
660
                    return source_store.generate_lossy_pack_data(
 
661
                        have, want, shallow=shallow,
 
662
                        progress=progress, ofs_delta=ofs_delta)
 
663
                elif shallow:
 
664
                    return source_store.generate_pack_data(
 
665
                        have, want, shallow=shallow,
 
666
                        progress=progress, ofs_delta=ofs_delta)
 
667
                else:
 
668
                    return source_store.generate_pack_data(
 
669
                        have, want, progress=progress, ofs_delta=ofs_delta)
 
670
            dw_result = self.send_pack(get_changed_refs, generate_pack_data)
 
671
            if not isinstance(dw_result, dict):
 
672
                new_refs = dw_result.refs
 
673
                error = dw_result.ref_status.get(actual_refname)
 
674
                if error:
 
675
                    raise RemoteGitError(error)
 
676
                for ref, error in dw_result.ref_status.items():
 
677
                    if error:
 
678
                        trace.warning('unable to open ref %s: %s',
 
679
                                      ref, error)
 
680
            else:  # dulwich < 0.20.4
 
681
                new_refs = dw_result
624
682
        push_result.new_revid = repo.lookup_foreign_revision_id(
625
683
            new_refs[actual_refname])
626
684
        if old_sha is not None:
825
883
        """
826
884
        commit = self._repository.lookup_bzr_revision_id(
827
885
            self.get_revision_id())[0]
 
886
        import tempfile
828
887
        f = tempfile.SpooledTemporaryFile()
829
888
        # git-upload-archive(1) generaly only supports refs. So let's see if we
830
889
        # can find one.
881
940
 
882
941
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
883
942
                      progress=None):
 
943
        import tempfile
884
944
        fd, path = tempfile.mkstemp(suffix=".pack")
885
945
        try:
886
946
            self.fetch_pack(determine_wants, graph_walker,
939
999
 
940
1000
        def generate_pack_data(have, want, ofs_delta=False):
941
1001
            return pack_objects_to_data([])
942
 
        self.repository.send_pack(get_changed_refs, generate_pack_data)
 
1002
        result = self.repository.send_pack(
 
1003
            get_changed_refs, generate_pack_data)
 
1004
        if result and not isinstance(result, dict):
 
1005
            error = result.ref_status.get(ref)
 
1006
            if error:
 
1007
                raise RemoteGitError(error)
943
1008
 
944
1009
 
945
1010
class RemoteGitBranch(GitBranch):
1009
1074
            if peeled is None:
1010
1075
                # Let's just hope it's a commit
1011
1076
                peeled = unpeeled
1012
 
            if not isinstance(tag_name, text_type):
 
1077
            if not isinstance(tag_name, str):
1013
1078
                raise TypeError(tag_name)
1014
1079
            yield (ref_name, tag_name, peeled, unpeeled)
1015
1080
 
1023
1088
            return {self.ref: sha}
1024
1089
        def generate_pack_data(have, want, ofs_delta=False):
1025
1090
            return pack_objects_to_data([])
1026
 
        self.repository.send_pack(get_changed_refs, generate_pack_data)
 
1091
        result = self.repository.send_pack(
 
1092
            get_changed_refs, generate_pack_data)
 
1093
        if result is not None and not isinstance(result, dict):
 
1094
            error = result.ref_status.get(self.ref)
 
1095
            if error:
 
1096
                raise RemoteGitError(error)
1027
1097
        self._sha = sha
1028
1098
 
1029
1099