Show More
@@ -586,9 +586,9 b' def git_post_receive(unused_repo_path, r' | |||
|
586 | 586 | try: |
|
587 | 587 | subprocessio.run_command(cmd, env=os.environ.copy()) |
|
588 | 588 | except Exception: |
|
589 | cmd = [settings.GIT_EXECUTABLE, 'symbolic-ref', '"HEAD"', | |
|
590 | '"refs/heads/%s"' % push_ref['name']] | |
|
591 |
print( |
|
|
589 | push_ref_name = push_ref['name'] | |
|
590 | cmd = [settings.GIT_EXECUTABLE, 'symbolic-ref', '"HEAD"', f'"refs/heads/{push_ref_name}"'] | |
|
591 | print(f"Setting default branch to {push_ref_name}") | |
|
592 | 592 | subprocessio.run_command(cmd, env=os.environ.copy()) |
|
593 | 593 | |
|
594 | 594 | cmd = [settings.GIT_EXECUTABLE, 'for-each-ref', |
@@ -40,7 +40,7 b' from dulwich.repo import Repo as Dulwich' | |||
|
40 | 40 | from dulwich.server import update_server_info |
|
41 | 41 | |
|
42 | 42 | from vcsserver import exceptions, settings, subprocessio |
|
43 | from vcsserver.str_utils import safe_str, safe_int, safe_bytes | |
|
43 | from vcsserver.str_utils import safe_str, safe_int, safe_bytes, ascii_str, ascii_bytes | |
|
44 | 44 | from vcsserver.base import RepoFactory, obfuscate_qs, ArchiveNode, archive_repo |
|
45 | 45 | from vcsserver.hgcompat import ( |
|
46 | 46 | hg_url as url_parser, httpbasicauthhandler, httpdigestauthhandler) |
@@ -51,7 +51,7 b' DIR_STAT = stat.S_IFDIR' | |||
|
51 | 51 | FILE_MODE = stat.S_IFMT |
|
52 | 52 | GIT_LINK = objects.S_IFGITLINK |
|
53 | 53 | PEELED_REF_MARKER = b'^{}' |
|
54 | ||
|
54 | HEAD_MARKER = b'HEAD' | |
|
55 | 55 | |
|
56 | 56 | log = logging.getLogger(__name__) |
|
57 | 57 | |
@@ -107,8 +107,9 b' class GitFactory(RepoFactory):' | |||
|
107 | 107 | |
|
108 | 108 | def _create_repo(self, wire, create, use_libgit2=False): |
|
109 | 109 | if use_libgit2: |
|
110 | return Repository(wire['path']) | |
|
110 | return Repository(safe_bytes(wire['path'])) | |
|
111 | 111 | else: |
|
112 | # dulwich mode | |
|
112 | 113 | repo_path = safe_str(wire['path'], to_encoding=settings.WIRE_ENCODING) |
|
113 | 114 | return Repo(repo_path) |
|
114 | 115 | |
@@ -610,13 +611,25 b' class GitRemote(RemoteBase):' | |||
|
610 | 611 | |
|
611 | 612 | determine_wants = repo.object_store.determine_wants_all |
|
612 | 613 | if refs: |
|
613 | def determine_wants_requested(references): | |
|
614 | return [references[r] for r in references if r in refs] | |
|
614 | refs = [ascii_bytes(x) for x in refs] | |
|
615 | ||
|
616 | def determine_wants_requested(remote_refs): | |
|
617 | determined = [] | |
|
618 | for ref_name, ref_hash in remote_refs.items(): | |
|
619 | bytes_ref_name = safe_bytes(ref_name) | |
|
620 | ||
|
621 | if bytes_ref_name in refs: | |
|
622 | bytes_ref_hash = safe_bytes(ref_hash) | |
|
623 | determined.append(bytes_ref_hash) | |
|
624 | return determined | |
|
625 | ||
|
626 | # swap with our custom requested wants | |
|
615 | 627 | determine_wants = determine_wants_requested |
|
616 | 628 | |
|
617 | 629 | try: |
|
618 | 630 | remote_refs = client.fetch( |
|
619 | 631 | path=url, target=repo, determine_wants=determine_wants) |
|
632 | ||
|
620 | 633 | except NotGitRepository as e: |
|
621 | 634 | log.warning( |
|
622 | 635 | 'Trying to fetch from "%s" failed, not a Git repository.', url) |
@@ -641,13 +654,13 b' class GitRemote(RemoteBase):' | |||
|
641 | 654 | |
|
642 | 655 | if refs and not update_after: |
|
643 | 656 | # mikhail: explicitly set the head to the last ref. |
|
644 |
repo[ |
|
|
657 | repo[HEAD_MARKER] = remote_refs[refs[-1]] | |
|
645 | 658 | |
|
646 | 659 | if update_after: |
|
647 | 660 | # we want to checkout HEAD |
|
648 |
repo[ |
|
|
661 | repo[HEAD_MARKER] = remote_refs[HEAD_MARKER] | |
|
649 | 662 | index.build_index_from_tree(repo.path, repo.index_path(), |
|
650 |
repo.object_store, repo[ |
|
|
663 | repo.object_store, repo[HEAD_MARKER].tree) | |
|
651 | 664 | return remote_refs |
|
652 | 665 | |
|
653 | 666 | @reraise_safe_exceptions |
@@ -680,7 +693,7 b' class GitRemote(RemoteBase):' | |||
|
680 | 693 | log.debug("Skipping peeled reference %s", ref) |
|
681 | 694 | continue |
|
682 | 695 | # don't sync HEAD |
|
683 |
if ref in [ |
|
|
696 | if ref in [HEAD_MARKER]: | |
|
684 | 697 | continue |
|
685 | 698 | |
|
686 | 699 | remote_refs[ref] = sha |
@@ -1292,6 +1305,10 b' class GitRemote(RemoteBase):' | |||
|
1292 | 1305 | from vcsserver.hook_utils import install_git_hooks |
|
1293 | 1306 | bare = self.bare(wire) |
|
1294 | 1307 | path = wire['path'] |
|
1308 | binary_dir = settings.BINARY_DIR | |
|
1309 | executable = None | |
|
1310 | if binary_dir: | |
|
1311 | executable = os.path.join(binary_dir, 'python3') | |
|
1295 | 1312 | return install_git_hooks(path, bare, force_create=force) |
|
1296 | 1313 | |
|
1297 | 1314 | @reraise_safe_exceptions |
@@ -152,7 +152,7 b' class MercurialFactory(RepoFactory):' | |||
|
152 | 152 | |
|
153 | 153 | def _create_repo(self, wire, create): |
|
154 | 154 | baseui = self._create_config(wire["config"]) |
|
155 |
return instance(baseui, |
|
|
155 | return instance(baseui, safe_bytes(wire["path"]), create) | |
|
156 | 156 | |
|
157 | 157 | def repo(self, wire, create=False): |
|
158 | 158 | """ |
@@ -757,12 +757,13 b' class HgRemote(RemoteBase):' | |||
|
757 | 757 | |
|
758 | 758 | @reraise_safe_exceptions |
|
759 | 759 | def revs_from_revspec(self, wire, rev_spec, *args, **kwargs): |
|
760 | other_path = kwargs.pop('other_path', None) | |
|
760 | org_path = safe_bytes(wire["path"]) | |
|
761 | other_path = safe_bytes(kwargs.pop('other_path', '')) | |
|
761 | 762 | |
|
762 | 763 | # case when we want to compare two independent repositories |
|
763 | 764 | if other_path and other_path != wire["path"]: |
|
764 | 765 | baseui = self._factory._create_config(wire["config"]) |
|
765 |
repo = unionrepo.makeunionrepository(baseui, other_path, |
|
|
766 | repo = unionrepo.makeunionrepository(baseui, other_path, org_path) | |
|
766 | 767 | else: |
|
767 | 768 | repo = self._factory.repo(wire) |
|
768 | 769 | return list(repo.revs(rev_spec, *args)) |
@@ -815,9 +816,11 b' class HgRemote(RemoteBase):' | |||
|
815 | 816 | return _tags(context_uid, repo_id) |
|
816 | 817 | |
|
817 | 818 | @reraise_safe_exceptions |
|
818 |
def update(self, wire, node= |
|
|
819 | def update(self, wire, node='', clean=False): | |
|
819 | 820 | repo = self._factory.repo(wire) |
|
820 | 821 | baseui = self._factory._create_config(wire['config']) |
|
822 | node = safe_bytes(node) | |
|
823 | ||
|
821 | 824 | commands.update(baseui, repo, node=node, clean=clean) |
|
822 | 825 | |
|
823 | 826 | @reraise_safe_exceptions |
@@ -855,7 +858,7 b' class HgRemote(RemoteBase):' | |||
|
855 | 858 | repo = self._factory.repo(wire) |
|
856 | 859 | changelog = repo.changelog |
|
857 | 860 | lookup = repo.lookup |
|
858 | a = changelog.ancestor(lookup(revision1), lookup(revision2)) | |
|
861 | a = changelog.ancestor(lookup(safe_bytes(revision1)), lookup(safe_bytes(revision2))) | |
|
859 | 862 | return hex(a) |
|
860 | 863 | |
|
861 | 864 | @reraise_safe_exceptions |
@@ -933,19 +936,29 b' class HgRemote(RemoteBase):' | |||
|
933 | 936 | repo, remote, heads=commit_ids, force=None).cgresult |
|
934 | 937 | |
|
935 | 938 | @reraise_safe_exceptions |
|
936 |
def pull_cmd(self, wire, source, bookmark= |
|
|
939 | def pull_cmd(self, wire, source, bookmark='', branch='', revision='', hooks=True): | |
|
937 | 940 | repo = self._factory.repo(wire) |
|
938 | 941 | baseui = self._factory._create_config(wire['config'], hooks=hooks) |
|
939 | 942 | |
|
943 | source = safe_bytes(source) | |
|
944 | ||
|
940 | 945 | # Mercurial internally has a lot of logic that checks ONLY if |
|
941 | 946 | # option is defined, we just pass those if they are defined then |
|
942 | 947 | opts = {} |
|
943 | 948 | if bookmark: |
|
949 | if isinstance(branch, list): | |
|
950 | bookmark = [safe_bytes(x) for x in bookmark] | |
|
951 | else: | |
|
952 | bookmark = safe_bytes(bookmark) | |
|
944 | 953 | opts['bookmark'] = bookmark |
|
945 | 954 | if branch: |
|
955 | if isinstance(branch, list): | |
|
956 | branch = [safe_bytes(x) for x in branch] | |
|
957 | else: | |
|
958 | branch = safe_bytes(branch) | |
|
946 | 959 | opts['branch'] = branch |
|
947 | 960 | if revision: |
|
948 | opts['rev'] = revision | |
|
961 | opts['rev'] = safe_bytes(revision) | |
|
949 | 962 | |
|
950 | 963 | commands.pull(baseui, repo, source, **opts) |
|
951 | 964 | |
@@ -1040,10 +1053,10 b' class HgRemote(RemoteBase):' | |||
|
1040 | 1053 | raise exceptions.AbortException(e)(repr(e)) |
|
1041 | 1054 | |
|
1042 | 1055 | @reraise_safe_exceptions |
|
1043 |
def bookmark(self, wire, bookmark, revision= |
|
|
1056 | def bookmark(self, wire, bookmark, revision=''): | |
|
1044 | 1057 | repo = self._factory.repo(wire) |
|
1045 | 1058 | baseui = self._factory._create_config(wire['config']) |
|
1046 | commands.bookmark(baseui, repo, bookmark, rev=revision, force=True) | |
|
1059 | commands.bookmark(baseui, repo, safe_bytes(bookmark), rev=safe_bytes(revision), force=True) | |
|
1047 | 1060 | |
|
1048 | 1061 | @reraise_safe_exceptions |
|
1049 | 1062 | def install_hooks(self, wire, force=False): |
@@ -38,7 +38,7 b' import svn.repos' | |||
|
38 | 38 | from vcsserver import svn_diff, exceptions, subprocessio, settings |
|
39 | 39 | from vcsserver.base import RepoFactory, raise_from_original, ArchiveNode, archive_repo |
|
40 | 40 | from vcsserver.exceptions import NoContentException |
|
41 | from vcsserver.str_utils import safe_str | |
|
41 | from vcsserver.str_utils import safe_str, safe_bytes | |
|
42 | 42 | from vcsserver.vcs_base import RemoteBase |
|
43 | 43 | from vcsserver.lib.svnremoterepo import svnremoterepo |
|
44 | 44 | log = logging.getLogger(__name__) |
@@ -63,7 +63,7 b' def reraise_safe_exceptions(func):' | |||
|
63 | 63 | except Exception as e: |
|
64 | 64 | if not hasattr(e, '_vcs_kind'): |
|
65 | 65 | log.exception("Unhandled exception in svn remote call") |
|
66 | raise_from_original(exceptions.UnhandledException(e)) | |
|
66 | raise_from_original(exceptions.UnhandledException(e), e) | |
|
67 | 67 | raise |
|
68 | 68 | return wrapper |
|
69 | 69 | |
@@ -328,6 +328,7 b' class SvnRemote(RemoteBase):' | |||
|
328 | 328 | |
|
329 | 329 | cache_on, context_uid, repo_id = self._cache_on(wire) |
|
330 | 330 | region = self._region(wire) |
|
331 | ||
|
331 | 332 | @region.conditional_cache_on_arguments(condition=cache_on) |
|
332 | 333 | def _get_nodes(_repo_id, _path, _revision): |
|
333 | 334 | repo = self._factory.repo(wire) |
@@ -425,8 +426,11 b' class SvnRemote(RemoteBase):' | |||
|
425 | 426 | (src_url, )) |
|
426 | 427 | |
|
427 | 428 | def commit(self, wire, message, author, timestamp, updated, removed): |
|
428 | assert isinstance(message, str) | |
|
429 | assert isinstance(author, str) | |
|
429 | ||
|
430 | updated = [{k: safe_bytes(v) for k, v in x.items() if isinstance(v, str)} for x in updated] | |
|
431 | ||
|
432 | message = safe_bytes(message) | |
|
433 | author = safe_bytes(author) | |
|
430 | 434 | |
|
431 | 435 | repo = self._factory.repo(wire) |
|
432 | 436 | fsobj = svn.repos.fs(repo) |
@@ -477,7 +481,7 b' class SvnRemote(RemoteBase):' | |||
|
477 | 481 | @region.conditional_cache_on_arguments(condition=cache_on) |
|
478 | 482 | def _is_binary(_repo_id, _rev, _path): |
|
479 | 483 | raw_bytes = self.get_file_content(wire, path, rev) |
|
480 | return raw_bytes and '\0' in raw_bytes | |
|
484 | return raw_bytes and b'\0' in raw_bytes | |
|
481 | 485 | |
|
482 | 486 | return _is_binary(repo_id, rev, path) |
|
483 | 487 | |
@@ -530,9 +534,8 b' class SvnRemote(RemoteBase):' | |||
|
530 | 534 | binary_dir = settings.BINARY_DIR |
|
531 | 535 | executable = None |
|
532 | 536 | if binary_dir: |
|
533 | executable = os.path.join(binary_dir, 'python') | |
|
534 | return install_svn_hooks( | |
|
535 | repo_path, executable=executable, force_create=force) | |
|
537 | executable = os.path.join(binary_dir, 'python3') | |
|
538 | return install_svn_hooks(repo_path, force_create=force) | |
|
536 | 539 | |
|
537 | 540 | @reraise_safe_exceptions |
|
538 | 541 | def get_hooks_info(self, wire): |
@@ -808,7 +811,7 b' class TxnNodeProcessor(object):' | |||
|
808 | 811 | """ |
|
809 | 812 | |
|
810 | 813 | def __init__(self, node, txn_root): |
|
811 |
assert isinstance(node['path'], |
|
|
814 | assert isinstance(node['path'], bytes) | |
|
812 | 815 | |
|
813 | 816 | self.node = node |
|
814 | 817 | self.txn_root = txn_root |
@@ -844,7 +847,8 b' class TxnNodeProcessor(object):' | |||
|
844 | 847 | svn.fs.make_file(self.txn_root, self.node['path']) |
|
845 | 848 | |
|
846 | 849 | def _update_file_content(self): |
|
847 |
assert isinstance(self.node['content'], |
|
|
850 | assert isinstance(self.node['content'], bytes) | |
|
851 | ||
|
848 | 852 | handler, baton = svn.fs.apply_textdelta( |
|
849 | 853 | self.txn_root, self.node['path'], None, None) |
|
850 | 854 | svn.delta.svn_txdelta_send_string(self.node['content'], handler, baton) |
@@ -39,7 +39,7 b' def repeat(request):' | |||
|
39 | 39 | @pytest.fixture(scope='session') |
|
40 | 40 | def vcsserver_port(request): |
|
41 | 41 | port = get_available_port() |
|
42 |
print( |
|
|
42 | print(f'Using vcsserver port {port}') | |
|
43 | 43 | return port |
|
44 | 44 | |
|
45 | 45 |
@@ -66,8 +66,8 b' class TestGitFetch(object):' | |||
|
66 | 66 | |
|
67 | 67 | def test_fetches_specified_commits(self): |
|
68 | 68 | selected_refs = { |
|
69 | 'refs/tags/v0.1.8': '74ebce002c088b8a5ecf40073db09375515ecd68', | |
|
70 | 'refs/tags/v0.1.3': '5a3a8fb005554692b16e21dee62bf02667d8dc3e', | |
|
69 | 'refs/tags/v0.1.8': b'74ebce002c088b8a5ecf40073db09375515ecd68', | |
|
70 | 'refs/tags/v0.1.3': b'5a3a8fb005554692b16e21dee62bf02667d8dc3e', | |
|
71 | 71 | } |
|
72 | 72 | |
|
73 | 73 | def side_effect(determine_wants, *args, **kwargs): |
General Comments 0
You need to be logged in to leave comments.
Login now