/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: Jelmer Vernooij
  • Date: 2020-03-22 20:02:36 UTC
  • mto: (7490.7.7 work)
  • mto: This revision was merged to the branch mainline in revision 7501.
  • Revision ID: jelmer@jelmer.uk-20200322200236-fsbl91ktcn6fcbdd
Fix tests.

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
 
19
21
import gzip
20
22
from io import BytesIO
21
23
import re
48
50
    )
49
51
from ..revision import NULL_REVISION
50
52
from ..revisiontree import RevisionTree
 
53
from ..sixish import (
 
54
    text_type,
 
55
    viewitems,
 
56
    )
51
57
from ..transport import (
52
58
    Transport,
53
59
    register_urlparse_netloc_protocol,
76
82
    NoSuchRef,
77
83
    )
78
84
from .mapping import (
79
 
    encode_git_path,
80
85
    mapping_registry,
81
86
    )
82
87
from .object_store import (
116
121
    )
117
122
import os
118
123
import select
 
124
import tempfile
119
125
 
120
 
import urllib.parse as urlparse
121
 
from urllib.parse import splituser
 
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
122
132
 
123
133
# urlparse only supports a limited number of schemes by default
124
134
register_urlparse_netloc_protocol('git')
204
214
    if re.match('(.+) is not a valid repository name',
205
215
                message.splitlines()[0]):
206
216
        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)
211
217
    m = re.match(r'Permission to ([^ ]+) denied to ([^ ]+)\.', message)
212
218
    if m:
213
219
        return PermissionDenied(m.group(1), 'denied to %s' % m.group(2))
215
221
    return RemoteGitError(message)
216
222
 
217
223
 
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
 
 
241
224
class GitSmartTransport(Transport):
242
225
 
243
226
    def __init__(self, url, _client=None):
434
417
                write_error,
435
418
                format=(format.encode('ascii') if format else None),
436
419
                subdirs=subdirs,
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)
 
420
                prefix=(prefix.encode('utf-8') if prefix else None))
440
421
        except GitProtocolError as e:
441
422
            raise parse_git_error(self.transport.external_url(), e)
442
423
        finally:
459
440
            self._refs = remote_refs_dict_to_container(
460
441
                result.refs, result.symrefs)
461
442
            return result
462
 
        except HangupException as e:
463
 
            raise parse_git_hangup(self.transport.external_url(), e)
464
443
        except GitProtocolError as e:
465
444
            raise parse_git_error(self.transport.external_url(), e)
466
445
        finally:
482
461
            return self._client.send_pack(
483
462
                self._client_path, get_changed_refs_wrapper,
484
463
                generate_pack_data, progress)
485
 
        except HangupException as e:
486
 
            raise parse_git_hangup(self.transport.external_url(), e)
487
464
        except GitProtocolError as e:
488
465
            raise parse_git_error(self.transport.external_url(), e)
489
466
        finally:
514
491
 
515
492
        def generate_pack_data(have, want, ofs_delta=False):
516
493
            return pack_objects_to_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)
 
494
        self.send_pack(get_changed_refs, generate_pack_data)
522
495
 
523
496
    @property
524
497
    def user_url(self):
588
561
            # No revision supplied by the user, default to the branch
589
562
            # revision
590
563
            revision_id = source.last_revision()
591
 
        else:
592
 
            if not source.repository.has_revision(revision_id):
593
 
                raise NoSuchRevision(source, revision_id)
594
564
 
595
565
        push_result = GitPushResult()
596
566
        push_result.workingtree_updated = None
629
599
                        source, self.open_branch(name, nascent_ok=True))
630
600
            ret[actual_refname] = new_sha
631
601
            if fetch_tags:
632
 
                for tagname, revid in source.tags.get_tag_dict().items():
 
602
                for tagname, revid in viewitems(source.tags.get_tag_dict()):
633
603
                    if tag_selector and not tag_selector(tagname):
634
604
                        continue
635
605
                    if lossy:
643
613
                            new_sha = repo.lookup_bzr_revision_id(revid)[0]
644
614
                        except errors.NoSuchRevision:
645
615
                            continue
646
 
                        else:
647
 
                            if not source.repository.has_revision(revid):
648
 
                                continue
649
616
                    ret[tag_name_to_ref(tagname)] = new_sha
650
617
            return ret
651
618
        with source_store.lock_read():
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
 
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)
682
624
        push_result.new_revid = repo.lookup_foreign_revision_id(
683
625
            new_refs[actual_refname])
684
626
        if old_sha is not None:
780
722
            raise NotGitRepository()
781
723
        elif response.status != 200:
782
724
            raise GitProtocolError("unexpected http resp %d for %s" %
783
 
                                   (response.status, url))
 
725
                                   (response.code, url))
784
726
 
785
727
        # TODO: Optimization available by adding `preload_content=False` to the
786
728
        # request and just passing the `read` method on instead of going via
883
825
        """
884
826
        commit = self._repository.lookup_bzr_revision_id(
885
827
            self.get_revision_id())[0]
886
 
        import tempfile
887
828
        f = tempfile.SpooledTemporaryFile()
888
829
        # git-upload-archive(1) generaly only supports refs. So let's see if we
889
830
        # can find one.
940
881
 
941
882
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
942
883
                      progress=None):
943
 
        import tempfile
944
884
        fd, path = tempfile.mkstemp(suffix=".pack")
945
885
        try:
946
886
            self.fetch_pack(determine_wants, graph_walker,
999
939
 
1000
940
        def generate_pack_data(have, want, ofs_delta=False):
1001
941
            return pack_objects_to_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)
 
942
        self.repository.send_pack(get_changed_refs, generate_pack_data)
1008
943
 
1009
944
 
1010
945
class RemoteGitBranch(GitBranch):
1074
1009
            if peeled is None:
1075
1010
                # Let's just hope it's a commit
1076
1011
                peeled = unpeeled
1077
 
            if not isinstance(tag_name, str):
 
1012
            if not isinstance(tag_name, text_type):
1078
1013
                raise TypeError(tag_name)
1079
1014
            yield (ref_name, tag_name, peeled, unpeeled)
1080
1015
 
1088
1023
            return {self.ref: sha}
1089
1024
        def generate_pack_data(have, want, ofs_delta=False):
1090
1025
            return pack_objects_to_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)
 
1026
        self.repository.send_pack(get_changed_refs, generate_pack_data)
1097
1027
        self._sha = sha
1098
1028
 
1099
1029