/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: Gustav Hartvigsson
  • Date: 2021-01-09 21:36:27 UTC
  • Revision ID: gustav.hartvigsson@gmail.com-20210109213627-h1xwcutzy9m7a99b
Added 'Case Preserving Working Tree Use Cases' from Canonical Wiki

* Addod a page from the Canonical Bazaar wiki
  with information on the scmeatics of case
  perserving filesystems an a case insensitive
  filesystem works.
  
  * Needs re-work, but this will do as it is the
    same inforamoton as what was on the linked
    page in the currint documentation.

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')
211
201
        return PermissionDenied(url, message)
212
202
    if message.endswith(' does not appear to be a git repository'):
213
203
        return NotBranchError(url, message)
 
204
    if message == 'pre-receive hook declined':
 
205
        return PermissionDenied(url, message)
214
206
    if re.match('(.+) is not a valid repository name',
215
207
                message.splitlines()[0]):
216
208
        return NotBranchError(url, message)
 
209
    if message == (
 
210
            'GitLab: You are not allowed to push code to protected branches '
 
211
            'on this project.'):
 
212
        return PermissionDenied(url, message)
217
213
    m = re.match(r'Permission to ([^ ]+) denied to ([^ ]+)\.', message)
218
214
    if m:
219
215
        return PermissionDenied(m.group(1), 'denied to %s' % m.group(2))
221
217
    return RemoteGitError(message)
222
218
 
223
219
 
 
220
def parse_git_hangup(url, e):
 
221
    """Parse the error lines from a git servers stderr on hangup.
 
222
 
 
223
    :param url: URL of the remote repository
 
224
    :param e: A HangupException
 
225
    """
 
226
    stderr_lines = getattr(e, 'stderr_lines', None)
 
227
    if not stderr_lines:
 
228
        return e
 
229
    if all(line.startswith(b'remote: ') for line in stderr_lines):
 
230
        stderr_lines = [
 
231
            line[len(b'remote: '):] for line in stderr_lines]
 
232
    interesting_lines = [
 
233
        line for line in stderr_lines
 
234
        if line and line.replace(b'=', b'')]
 
235
    if len(interesting_lines) == 1:
 
236
        interesting_line = interesting_lines[0]
 
237
        return parse_git_error(
 
238
            url, interesting_line.decode('utf-8', 'surrogateescape'))
 
239
    return RemoteGitError(
 
240
        b'\n'.join(stderr_lines).decode('utf-8', 'surrogateescape'))
 
241
 
 
242
 
224
243
class GitSmartTransport(Transport):
225
244
 
226
245
    def __init__(self, url, _client=None):
417
436
                write_error,
418
437
                format=(format.encode('ascii') if format else None),
419
438
                subdirs=subdirs,
420
 
                prefix=(prefix.encode('utf-8') if prefix else None))
 
439
                prefix=(encode_git_path(prefix) if prefix else None))
 
440
        except HangupException as e:
 
441
            raise parse_git_hangup(self.transport.external_url(), e)
421
442
        except GitProtocolError as e:
422
443
            raise parse_git_error(self.transport.external_url(), e)
423
444
        finally:
440
461
            self._refs = remote_refs_dict_to_container(
441
462
                result.refs, result.symrefs)
442
463
            return result
 
464
        except HangupException as e:
 
465
            raise parse_git_hangup(self.transport.external_url(), e)
443
466
        except GitProtocolError as e:
444
467
            raise parse_git_error(self.transport.external_url(), e)
445
468
        finally:
461
484
            return self._client.send_pack(
462
485
                self._client_path, get_changed_refs_wrapper,
463
486
                generate_pack_data, progress)
 
487
        except HangupException as e:
 
488
            raise parse_git_hangup(self.transport.external_url(), e)
464
489
        except GitProtocolError as e:
465
490
            raise parse_git_error(self.transport.external_url(), e)
466
491
        finally:
491
516
 
492
517
        def generate_pack_data(have, want, ofs_delta=False):
493
518
            return pack_objects_to_data([])
494
 
        self.send_pack(get_changed_refs, generate_pack_data)
 
519
        result = self.send_pack(get_changed_refs, generate_pack_data)
 
520
        if result is not None and not isinstance(result, dict):
 
521
            error = result.ref_status.get(refname)
 
522
            if error:
 
523
                raise RemoteGitError(error)
495
524
 
496
525
    @property
497
526
    def user_url(self):
561
590
            # No revision supplied by the user, default to the branch
562
591
            # revision
563
592
            revision_id = source.last_revision()
 
593
        else:
 
594
            if not source.repository.has_revision(revision_id):
 
595
                raise NoSuchRevision(source, revision_id)
564
596
 
565
597
        push_result = GitPushResult()
566
598
        push_result.workingtree_updated = None
570
602
        push_result.branch_push_result = None
571
603
        repo = self.find_repository()
572
604
        refname = self._get_selected_ref(name)
573
 
        ref_chain, old_sha = self.get_refs_container().follow(refname)
574
 
        if ref_chain:
575
 
            actual_refname = ref_chain[-1]
576
 
        else:
 
605
        try:
 
606
            ref_chain, old_sha = self.get_refs_container().follow(refname)
 
607
        except NotBranchError:
577
608
            actual_refname = refname
 
609
            old_sha = None
 
610
        else:
 
611
            if ref_chain:
 
612
                actual_refname = ref_chain[-1]
 
613
            else:
 
614
                actual_refname = refname
578
615
        if isinstance(source, GitBranch) and lossy:
579
616
            raise errors.LossyPushToSameVCS(source.controldir, self)
580
617
        source_store = get_object_store(source.repository)
594
631
                    raise errors.NoRoundtrippingSupport(
595
632
                        source, self.open_branch(name=name, nascent_ok=True))
596
633
            if not overwrite:
 
634
                old_sha = remote_refs.get(actual_refname)
597
635
                if remote_divergence(old_sha, new_sha, source_store):
598
636
                    raise DivergedBranches(
599
637
                        source, self.open_branch(name, nascent_ok=True))
600
638
            ret[actual_refname] = new_sha
601
639
            if fetch_tags:
602
 
                for tagname, revid in viewitems(source.tags.get_tag_dict()):
 
640
                for tagname, revid in source.tags.get_tag_dict().items():
603
641
                    if tag_selector and not tag_selector(tagname):
604
642
                        continue
605
643
                    if lossy:
613
651
                            new_sha = repo.lookup_bzr_revision_id(revid)[0]
614
652
                        except errors.NoSuchRevision:
615
653
                            continue
 
654
                        else:
 
655
                            if not source.repository.has_revision(revid):
 
656
                                continue
616
657
                    ret[tag_name_to_ref(tagname)] = new_sha
617
658
            return ret
618
659
        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)
 
660
            def generate_pack_data(have, want, progress=None,
 
661
                                   ofs_delta=True):
 
662
                git_repo = getattr(source.repository, '_git', None)
 
663
                if git_repo:
 
664
                    shallow = git_repo.get_shallow()
 
665
                else:
 
666
                    shallow = None
 
667
                if lossy:
 
668
                    return source_store.generate_lossy_pack_data(
 
669
                        have, want, shallow=shallow,
 
670
                        progress=progress, ofs_delta=ofs_delta)
 
671
                elif shallow:
 
672
                    return source_store.generate_pack_data(
 
673
                        have, want, shallow=shallow,
 
674
                        progress=progress, ofs_delta=ofs_delta)
 
675
                else:
 
676
                    return source_store.generate_pack_data(
 
677
                        have, want, progress=progress, ofs_delta=ofs_delta)
 
678
            dw_result = self.send_pack(get_changed_refs, generate_pack_data)
 
679
            if not isinstance(dw_result, dict):
 
680
                new_refs = dw_result.refs
 
681
                error = dw_result.ref_status.get(actual_refname)
 
682
                if error:
 
683
                    raise RemoteGitError(error)
 
684
                for ref, error in dw_result.ref_status.items():
 
685
                    if error:
 
686
                        trace.warning('unable to open ref %s: %s',
 
687
                                      ref, error)
 
688
            else:  # dulwich < 0.20.4
 
689
                new_refs = dw_result
624
690
        push_result.new_revid = repo.lookup_foreign_revision_id(
625
691
            new_refs[actual_refname])
626
692
        if old_sha is not None:
825
891
        """
826
892
        commit = self._repository.lookup_bzr_revision_id(
827
893
            self.get_revision_id())[0]
 
894
        import tempfile
828
895
        f = tempfile.SpooledTemporaryFile()
829
896
        # git-upload-archive(1) generaly only supports refs. So let's see if we
830
897
        # can find one.
881
948
 
882
949
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
883
950
                      progress=None):
 
951
        import tempfile
884
952
        fd, path = tempfile.mkstemp(suffix=".pack")
885
953
        try:
886
954
            self.fetch_pack(determine_wants, graph_walker,
939
1007
 
940
1008
        def generate_pack_data(have, want, ofs_delta=False):
941
1009
            return pack_objects_to_data([])
942
 
        self.repository.send_pack(get_changed_refs, generate_pack_data)
 
1010
        result = self.repository.send_pack(
 
1011
            get_changed_refs, generate_pack_data)
 
1012
        if result and not isinstance(result, dict):
 
1013
            error = result.ref_status.get(ref)
 
1014
            if error:
 
1015
                raise RemoteGitError(error)
943
1016
 
944
1017
 
945
1018
class RemoteGitBranch(GitBranch):
1009
1082
            if peeled is None:
1010
1083
                # Let's just hope it's a commit
1011
1084
                peeled = unpeeled
1012
 
            if not isinstance(tag_name, text_type):
 
1085
            if not isinstance(tag_name, str):
1013
1086
                raise TypeError(tag_name)
1014
1087
            yield (ref_name, tag_name, peeled, unpeeled)
1015
1088
 
1023
1096
            return {self.ref: sha}
1024
1097
        def generate_pack_data(have, want, ofs_delta=False):
1025
1098
            return pack_objects_to_data([])
1026
 
        self.repository.send_pack(get_changed_refs, generate_pack_data)
 
1099
        result = self.repository.send_pack(
 
1100
            get_changed_refs, generate_pack_data)
 
1101
        if result is not None and not isinstance(result, dict):
 
1102
            error = result.ref_status.get(self.ref)
 
1103
            if error:
 
1104
                raise RemoteGitError(error)
1027
1105
        self._sha = sha
1028
1106
 
1029
1107