hgitaly 18.3.0a1__tar.gz → 18.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {hgitaly-18.3.0a1/hgitaly.egg-info → hgitaly-18.3.2}/PKG-INFO +1 -1
- hgitaly-18.3.2/hgitaly/VERSION +1 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/diff.py +36 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/errors.py +3 -2
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_mono.py +5 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/commit.py +5 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/diff.py +2 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/operations.py +8 -3
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_commit.py +2 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_diff.py +82 -31
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_operations.py +47 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/bundle.py +10 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/grpc.py +22 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_errors.py +4 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2/hgitaly.egg-info}/PKG-INFO +1 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/SOURCES.txt +0 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/comparison.py +13 -6
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/rhgitaly.py +9 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_commit.py +7 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_diff.py +24 -8
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_repository_service.py +2 -0
- hgitaly-18.3.0a1/hgitaly/VERSION +0 -1
- hgitaly-18.3.0a1/hgitaly/linguist/languages.json +0 -1
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/LICENSE +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/MANIFEST.in +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/README.md +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/revset.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/tests/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/tests/test_revset.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/tests/test_serve.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/branch.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/changelog.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/feature.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/file_content.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/file_context.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/git.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/gitlab_ref.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/identification.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/logging.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/manifest.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/message.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/oid.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/pagination.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/path.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/peer.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/procutil.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/repository.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/revision.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/revset.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/scripts.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/address.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/mono.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/prefork.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_address.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_prefork.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_worker.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/worker.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/analysis.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/blob.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/interceptors.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/mercurial_changeset.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/mercurial_operations.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/mercurial_repository.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/ref.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/repository.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/server.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/fixture.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_analysis.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_blob.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_default_branch.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_mercurial_changeset.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_mercurial_operations.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_mercurial_repository.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_ref.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_repository_service.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_server.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/servicer.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/ssh.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stream.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/analysis_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/analysis_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/blob_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/blob_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/commit_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/commit_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/diff_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/diff_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/errors_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/errors_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/lint_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/lint_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_aux_git_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_aux_git_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_changeset_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_changeset_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_operations_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_operations_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_repository_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_repository_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/operations_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/operations_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/ref_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/ref_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/remote_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/remote_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/repository_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/repository_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/server_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/server_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/shared_pb2.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/shared_pb2_grpc.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tag.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/context.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/multiprocessing.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/ssh.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/sshd.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/storage.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/tests/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/tests/test_sshd.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/common.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_branch.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_diff.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_feature.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_file_context.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_gitlab_ref.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_identification.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_manifest.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_messages.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_oid.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_peer.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_repository.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_revision.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_revset.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_servicer.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_stream.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_tag.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_workdir.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/util.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/workdir.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/dependency_links.txt +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/entry_points.txt +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/requires.txt +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/top_level.txt +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/install-requirements.txt +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/setup.cfg +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/setup.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/__init__.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/conftest.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/gitaly.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_blob_tree.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_comparison.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_gitaly_server.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_mercurial_aux_git.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_mercurial_operations.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_mercurial_repository.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_operations.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_ref.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_remote.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_rhgitaly_server.py +0 -0
- {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_server.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
18.3.2
|
|
@@ -32,6 +32,7 @@ from .oid import (
|
|
|
32
32
|
from .stub.diff_pb2 import (
|
|
33
33
|
ChangedPaths,
|
|
34
34
|
DiffStats,
|
|
35
|
+
FindChangedPathsRequest,
|
|
35
36
|
)
|
|
36
37
|
|
|
37
38
|
GIT_PATCH_ID_TIMEOUT_SECONDS = 10
|
|
@@ -57,8 +58,23 @@ RENAMED = ChangedPaths.Status.RENAMED
|
|
|
57
58
|
DIFF_HUNKS_START_RX = re.compile(rb'^(--- )|^(Binary file)')
|
|
58
59
|
"""To match the header line right before hunks start getting dumped."""
|
|
59
60
|
|
|
61
|
+
DiffStatus = FindChangedPathsRequest.DiffStatus
|
|
60
62
|
|
|
61
|
-
|
|
63
|
+
Status_Filter_Map = dict(
|
|
64
|
+
added=DiffStatus.DIFF_STATUS_ADDED,
|
|
65
|
+
modified=DiffStatus.DIFF_STATUS_MODIFIED,
|
|
66
|
+
removed=DiffStatus.DIFF_STATUS_DELETED,
|
|
67
|
+
copied=DiffStatus.DIFF_STATUS_COPIED,
|
|
68
|
+
renamed=DiffStatus.DIFF_STATUS_RENAMED,
|
|
69
|
+
# TODO in case TYPE_CHANGE is explicitly filtered out or included,
|
|
70
|
+
# we should make the difference.
|
|
71
|
+
)
|
|
72
|
+
"""Mapping status object attributes to DiffFilter enum."""
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def changed_paths(repo, from_ctx, to_ctx, base_path,
|
|
76
|
+
find_renames=False,
|
|
77
|
+
diff_filters=()):
|
|
62
78
|
if base_path is None:
|
|
63
79
|
matcher = None
|
|
64
80
|
path_trim_at = 0
|
|
@@ -83,19 +99,32 @@ def changed_paths(repo, from_ctx, to_ctx, base_path, find_renames=False):
|
|
|
83
99
|
status = from_ctx.status(to_ctx, match=matcher)
|
|
84
100
|
# this will remove renames from copy_info, keeping only actual copies
|
|
85
101
|
yield from status_changed_paths(from_ctx, to_ctx, status, copy_info,
|
|
102
|
+
diff_filters=diff_filters,
|
|
86
103
|
find_renames=find_renames,
|
|
87
104
|
trim_at=path_trim_at)
|
|
105
|
+
if filtered_out('copied', diff_filters):
|
|
106
|
+
return
|
|
107
|
+
|
|
88
108
|
yield from copy_changed_paths(from_ctx,
|
|
89
109
|
to_ctx,
|
|
90
110
|
copy_info,
|
|
91
111
|
trim_at=path_trim_at)
|
|
92
112
|
|
|
93
113
|
|
|
114
|
+
def filtered_out(status_type, diff_filters):
|
|
115
|
+
if not diff_filters:
|
|
116
|
+
return False
|
|
117
|
+
return Status_Filter_Map[status_type] not in diff_filters
|
|
118
|
+
|
|
119
|
+
|
|
94
120
|
def status_changed_paths(from_ctx, to_ctx, status, copy_info,
|
|
121
|
+
diff_filters=(),
|
|
95
122
|
find_renames=False, trim_at=0):
|
|
96
123
|
rcopy_info = {v: k for k, v in copy_info.items()}
|
|
97
124
|
"""Return ChangedPaths from Mercurial status object"""
|
|
98
125
|
for stype in ['added', 'modified', 'removed']:
|
|
126
|
+
if stype != 'removed' and filtered_out(stype, diff_filters):
|
|
127
|
+
continue
|
|
99
128
|
for path in status.__getattribute__(stype):
|
|
100
129
|
copied_from = copy_info.get(path)
|
|
101
130
|
if copied_from is not None:
|
|
@@ -113,17 +142,23 @@ def status_changed_paths(from_ctx, to_ctx, status, copy_info,
|
|
|
113
142
|
if stype == 'removed':
|
|
114
143
|
new_path = rcopy_info.get(path)
|
|
115
144
|
if new_path is None:
|
|
145
|
+
if filtered_out(stype, diff_filters):
|
|
146
|
+
continue
|
|
116
147
|
new_mode = OBJECT_MODE_DOES_NOT_EXIST
|
|
117
148
|
new_blob_id = NULL_BLOB_OID
|
|
118
149
|
else:
|
|
119
150
|
del copy_info[new_path]
|
|
120
151
|
if find_renames:
|
|
121
152
|
stype = 'renamed'
|
|
153
|
+
if filtered_out(stype, diff_filters):
|
|
154
|
+
continue
|
|
122
155
|
old_path = path
|
|
123
156
|
path = new_path
|
|
124
157
|
new_mode = git_perms(to_ctx.filectx(new_path))
|
|
125
158
|
new_blob_id = ctx_blob_oid(to_ctx, new_path)
|
|
126
159
|
else:
|
|
160
|
+
if filtered_out(stype, diff_filters):
|
|
161
|
+
continue
|
|
127
162
|
new_mode = OBJECT_MODE_DOES_NOT_EXIST
|
|
128
163
|
new_blob_id = NULL_BLOB_OID
|
|
129
164
|
else:
|
|
@@ -103,8 +103,9 @@ def operation_error_treatment(context, error_message_class, logger,
|
|
|
103
103
|
except GitLabPreReceiveError as exc:
|
|
104
104
|
message = exc.message
|
|
105
105
|
if isinstance(message, str):
|
|
106
|
-
#
|
|
107
|
-
#
|
|
106
|
+
# almost impossible with Mercurial 7.1, because the parent class,
|
|
107
|
+
# `error.Abort` converts automatically to bytes. Still keeping
|
|
108
|
+
# this last line of defense:
|
|
108
109
|
message = message.encode('utf-8')
|
|
109
110
|
attrs = {
|
|
110
111
|
error_message_attr: CustomHookError(
|
|
@@ -10,7 +10,10 @@ import socket
|
|
|
10
10
|
|
|
11
11
|
import grpc
|
|
12
12
|
|
|
13
|
-
from hgitaly.testing.grpc import
|
|
13
|
+
from hgitaly.testing.grpc import (
|
|
14
|
+
wait_health_check,
|
|
15
|
+
wait_server_accepts_connection,
|
|
16
|
+
)
|
|
14
17
|
from .. import mono as server
|
|
15
18
|
|
|
16
19
|
|
|
@@ -93,6 +96,7 @@ def test_server_process(tmpdir):
|
|
|
93
96
|
p.start()
|
|
94
97
|
with grpc.insecure_channel(listen_url) as channel:
|
|
95
98
|
wait_server_accepts_connection(channel)
|
|
99
|
+
wait_health_check(channel)
|
|
96
100
|
|
|
97
101
|
p.terminate()
|
|
98
102
|
|
|
@@ -613,6 +613,11 @@ class CommitServicer(CommitServiceServicer, HGitalyServicer):
|
|
|
613
613
|
context, StatusCode.NOT_FOUND, "commits not found",
|
|
614
614
|
FindCommitsError())
|
|
615
615
|
|
|
616
|
+
message_regex = request.message_regex
|
|
617
|
+
if message_regex:
|
|
618
|
+
grep = f" and grep('(?i){message_regex}')"
|
|
619
|
+
opts[b'rev'][0] += grep.encode('utf-8')
|
|
620
|
+
|
|
616
621
|
walk_opts = logcmdutil.parseopts(repo.ui, pats, opts)
|
|
617
622
|
revs, _ = logcmdutil.getrevs(repo, walk_opts)
|
|
618
623
|
|
|
@@ -525,7 +525,8 @@ class DiffServicer(DiffServiceServicer, HGitalyServicer):
|
|
|
525
525
|
for paths in chunked(path for extr in extracted
|
|
526
526
|
for path in changed_paths(
|
|
527
527
|
repo, *extr,
|
|
528
|
-
find_renames=find_renames
|
|
528
|
+
find_renames=find_renames,
|
|
529
|
+
diff_filters=request.diff_filters)):
|
|
529
530
|
yield FindChangedPathsResponse(paths=paths)
|
|
530
531
|
|
|
531
532
|
def GetPatchID(self, request: GetPatchIDRequest,
|
|
@@ -361,9 +361,14 @@ class OperationServicer(OperationServiceServicer, HGitalyServicer):
|
|
|
361
361
|
start_ctx = repo[ZERO_SHA]
|
|
362
362
|
if commit_header.branch_name:
|
|
363
363
|
old_oid = commit_header.expected_old_oid.encode('ascii')
|
|
364
|
-
if old_oid
|
|
365
|
-
|
|
366
|
-
|
|
364
|
+
if old_oid:
|
|
365
|
+
old_ctx = gitlab_revision_changeset(repo, gl_branch)
|
|
366
|
+
if (
|
|
367
|
+
(old_ctx is None and old_oid != ZERO_SHA)
|
|
368
|
+
or (old_ctx is not None and old_ctx.hex() != old_oid)
|
|
369
|
+
):
|
|
370
|
+
context.abort(StatusCode.INVALID_ARGUMENT,
|
|
371
|
+
"wrong old oid")
|
|
367
372
|
|
|
368
373
|
if to_publish and self.heptapod_permission != 'publish':
|
|
369
374
|
context.abort(
|
|
@@ -368,6 +368,8 @@ def test_find_commits(commit_fixture_empty_repo):
|
|
|
368
368
|
assert exc_info.value.code() == grpc.StatusCode.NOT_FOUND
|
|
369
369
|
# with all, return all the commits
|
|
370
370
|
assert find_commits_ids(all=True) == [sha0, sha1, sha2, sha3, sha4]
|
|
371
|
+
# with message_regex
|
|
372
|
+
assert find_commits_ids(all=True, message_regex='FOO.*zoO') == [sha2]
|
|
371
373
|
# with offset
|
|
372
374
|
assert find_commits_ids(all=True, offset=2) == [sha2, sha3, sha4]
|
|
373
375
|
# with skip_merges
|
|
@@ -34,6 +34,13 @@ from hgitaly.stub.diff_pb2_grpc import DiffServiceStub
|
|
|
34
34
|
from .fixture import ServiceFixture
|
|
35
35
|
|
|
36
36
|
StatusCode = grpc.StatusCode
|
|
37
|
+
DiffStatus = FindChangedPathsRequest.DiffStatus
|
|
38
|
+
|
|
39
|
+
DS_ADDED = DiffStatus.DIFF_STATUS_ADDED
|
|
40
|
+
DS_MODIFIED = DiffStatus.DIFF_STATUS_MODIFIED
|
|
41
|
+
DS_DELETED = DiffStatus.DIFF_STATUS_DELETED
|
|
42
|
+
DS_COPIED = DiffStatus.DIFF_STATUS_COPIED
|
|
43
|
+
DS_RENAMED = DiffStatus.DIFF_STATUS_RENAMED
|
|
37
44
|
|
|
38
45
|
|
|
39
46
|
class DiffFixture(ServiceFixture):
|
|
@@ -170,9 +177,9 @@ def test_raw_diff(diff_fixture):
|
|
|
170
177
|
message=b'added foo')
|
|
171
178
|
ctx1 = wrapper.commit_file('foo', content="I am foo\n",
|
|
172
179
|
message=b'changes foo')
|
|
173
|
-
wrapper.command(
|
|
180
|
+
wrapper.command('mv', wrapper.repo.root + b'/foo',
|
|
174
181
|
wrapper.repo.root + b'/zoo')
|
|
175
|
-
wrapper.command(
|
|
182
|
+
wrapper.command('ci', message=b"rename foo to zoo")
|
|
176
183
|
ctx2 = wrapper.repo[b'.']
|
|
177
184
|
sha0, sha1, sha2 = ctx0.hex(), ctx1.hex(), ctx2.hex()
|
|
178
185
|
|
|
@@ -367,7 +374,7 @@ def test_commit_diff(diff_fixture):
|
|
|
367
374
|
message="Add bar")
|
|
368
375
|
ctx1 = wrapper.commit_file('bar', content="I am in\nbar\n",
|
|
369
376
|
message="Changes bar")
|
|
370
|
-
wrapper.command(
|
|
377
|
+
wrapper.command('mv', wrapper.repo.root + b'/bar',
|
|
371
378
|
wrapper.repo.root + b'/zar')
|
|
372
379
|
ctx2 = wrapper.commit([b'bar', b'zar'], message="Rename bar to zar")
|
|
373
380
|
ctx3 = wrapper.commit_file('zoo', content="I am in\nzoo\n",
|
|
@@ -470,7 +477,7 @@ def test_commit_delta(diff_fixture):
|
|
|
470
477
|
message="Add bar")
|
|
471
478
|
ctx1 = wrapper.commit_file('bar', content="I am in\nbar\n",
|
|
472
479
|
message="Changes bar")
|
|
473
|
-
wrapper.command(
|
|
480
|
+
wrapper.command('mv', wrapper.repo.root + b'/bar',
|
|
474
481
|
wrapper.repo.root + b'/zar')
|
|
475
482
|
ctx2 = wrapper.commit([b'bar', b'zar'], message="Rename bar to zar")
|
|
476
483
|
ctx3 = wrapper.commit_file('zoo', content="I am in\nzoo\n",
|
|
@@ -545,7 +552,7 @@ def test_diff_stats(diff_fixture):
|
|
|
545
552
|
message="Add bar")
|
|
546
553
|
ctx1 = wrapper.commit_file('bar', content="I am in\nbar\n",
|
|
547
554
|
message="Changes bar")
|
|
548
|
-
wrapper.command(
|
|
555
|
+
wrapper.command('mv', wrapper.repo.root + b'/bar',
|
|
549
556
|
wrapper.repo.root + b'/zar')
|
|
550
557
|
ctx2 = wrapper.commit([b'bar', b'zar'], message="Rename bar to zar")
|
|
551
558
|
ctx3 = wrapper.commit_file('zoo', content="I am in\nzoo\n",
|
|
@@ -586,8 +593,15 @@ def test_diff_stats(diff_fixture):
|
|
|
586
593
|
assert exc_info.value.code() == grpc.StatusCode.FAILED_PRECONDITION
|
|
587
594
|
|
|
588
595
|
|
|
596
|
+
def sub_dict(d, *keys):
|
|
597
|
+
"""Sub dict with given keys, after encoding to bytes."""
|
|
598
|
+
return {k.encode('ascii'): d[k.encode('ascii')]
|
|
599
|
+
for k in keys}
|
|
600
|
+
|
|
601
|
+
|
|
589
602
|
def test_find_changed_paths(diff_fixture):
|
|
590
603
|
wrapper = diff_fixture.repo_wrapper
|
|
604
|
+
repo = wrapper.repo
|
|
591
605
|
|
|
592
606
|
(wrapper.path / 'sub').mkdir()
|
|
593
607
|
(wrapper.path / 'sub/foo').write_text('foo content')
|
|
@@ -599,8 +613,7 @@ def test_find_changed_paths(diff_fixture):
|
|
|
599
613
|
(wrapper.path / 'too').chmod(0o755)
|
|
600
614
|
(wrapper.path / 'sub/foo').write_text('foo content modified')
|
|
601
615
|
(wrapper.path / 'bar').unlink()
|
|
602
|
-
wrapper.command(
|
|
603
|
-
wrapper.repo.root + b'/zaz')
|
|
616
|
+
wrapper.command('cp', repo.root + b'/zoo', repo.root + b'/zaz')
|
|
604
617
|
ctx1 = wrapper.commit(rel_paths=['sub/foo', 'bar', 'zaz', 'too'],
|
|
605
618
|
add_remove=True)
|
|
606
619
|
|
|
@@ -635,6 +648,15 @@ def test_find_changed_paths(diff_fixture):
|
|
|
635
648
|
assert diff_fixture.find_changed_paths_commits(
|
|
636
649
|
[ctx1.hex(), ctx2.hex()]) == resp_dict
|
|
637
650
|
|
|
651
|
+
# diff_filters
|
|
652
|
+
def fcp_filtered(filters):
|
|
653
|
+
return diff_fixture.find_changed_paths_commits(
|
|
654
|
+
[ctx1.hex(), ctx2.hex()], diff_filters=filters)
|
|
655
|
+
|
|
656
|
+
assert fcp_filtered([DS_ADDED]) == sub_dict(resp_dict, 'too')
|
|
657
|
+
assert fcp_filtered([DS_MODIFIED]) == sub_dict(resp_dict, 'sub/foo')
|
|
658
|
+
assert fcp_filtered([DS_COPIED]) == sub_dict(resp_dict, 'zaz')
|
|
659
|
+
|
|
638
660
|
# Testing by passing "parents" (changesets to compare to)
|
|
639
661
|
ctx3 = wrapper.commit_file("toto")
|
|
640
662
|
assert diff_fixture.find_changed_paths_commits(
|
|
@@ -648,7 +670,6 @@ def test_find_changed_paths(diff_fixture):
|
|
|
648
670
|
}
|
|
649
671
|
|
|
650
672
|
# Tree requests
|
|
651
|
-
repo = wrapper.repo
|
|
652
673
|
sub0_oid, sub1_oid = [tree_oid(repo, ctx.hex().decode('ascii'), b'sub')
|
|
653
674
|
for ctx in (ctx0, ctx1)]
|
|
654
675
|
assert diff_fixture.find_changed_paths_tree(sub0_oid, sub1_oid) == {
|
|
@@ -669,17 +690,16 @@ def test_find_changed_paths(diff_fixture):
|
|
|
669
690
|
|
|
670
691
|
def test_find_changed_paths_copy_in_tree(diff_fixture):
|
|
671
692
|
wrapper = diff_fixture.repo_wrapper
|
|
693
|
+
repo = wrapper.repo
|
|
672
694
|
|
|
673
695
|
(wrapper.path / 'subdir').mkdir() # avoid all lengths to be 3
|
|
674
696
|
(wrapper.path / 'subdir/bar').write_text('some bar')
|
|
675
697
|
ctx0 = wrapper.commit(rel_paths=['subdir'], add_remove=True)
|
|
676
698
|
|
|
677
|
-
wrapper.command(
|
|
678
|
-
|
|
699
|
+
wrapper.command('cp', repo.root + b'/subdir/bar',
|
|
700
|
+
repo.root + b'/subdir/baz')
|
|
679
701
|
ctx1 = wrapper.commit(rel_paths=['subdir'])
|
|
680
702
|
|
|
681
|
-
repo = wrapper.repo
|
|
682
|
-
|
|
683
703
|
sub0_oid, sub1_oid = [tree_oid(repo, ctx.hex().decode('ascii'), b'subdir')
|
|
684
704
|
for ctx in (ctx0, ctx1)]
|
|
685
705
|
assert diff_fixture.find_changed_paths_tree(sub0_oid, sub1_oid) == {
|
|
@@ -689,25 +709,23 @@ def test_find_changed_paths_copy_in_tree(diff_fixture):
|
|
|
689
709
|
|
|
690
710
|
def test_find_changed_paths_rename(diff_fixture):
|
|
691
711
|
wrapper = diff_fixture.repo_wrapper
|
|
712
|
+
repo = wrapper.repo
|
|
692
713
|
|
|
693
714
|
(wrapper.path / 'subdir').mkdir() # avoid all lengths to be 3
|
|
694
715
|
(wrapper.path / 'subdir/bar').write_text('some bar')
|
|
695
716
|
ctx0 = wrapper.commit(rel_paths=['subdir'], add_remove=True)
|
|
696
717
|
|
|
697
|
-
wrapper.command(
|
|
698
|
-
|
|
718
|
+
wrapper.command('mv', repo.root + b'/subdir/bar',
|
|
719
|
+
repo.root + b'/subdir/baz')
|
|
699
720
|
ctx1 = wrapper.commit(rel_paths=['subdir'])
|
|
700
721
|
|
|
701
|
-
|
|
722
|
+
def fcp(**opts):
|
|
723
|
+
return diff_fixture.find_changed_paths_commits(
|
|
724
|
+
[ctx1.hex()],
|
|
725
|
+
compare_to=[ctx0.hex()],
|
|
726
|
+
**opts)
|
|
702
727
|
|
|
703
|
-
|
|
704
|
-
for ctx in (ctx0, ctx1)]
|
|
705
|
-
ret = diff_fixture.find_changed_paths_commits(
|
|
706
|
-
[ctx1.hex()],
|
|
707
|
-
compare_to=[ctx0.hex()],
|
|
708
|
-
find_renames=False,
|
|
709
|
-
)
|
|
710
|
-
assert ret == {
|
|
728
|
+
expected_no_renames = {
|
|
711
729
|
b'subdir/baz': [(ChangedPaths.Status.ADDED,
|
|
712
730
|
(OBJECT_MODE_DOES_NOT_EXIST,
|
|
713
731
|
OBJECT_MODE_NON_EXECUTABLE),
|
|
@@ -718,17 +736,50 @@ def test_find_changed_paths_rename(diff_fixture):
|
|
|
718
736
|
)],
|
|
719
737
|
}
|
|
720
738
|
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
739
|
+
assert fcp(find_renames=False) == expected_no_renames
|
|
740
|
+
assert fcp(find_renames=False,
|
|
741
|
+
diff_filters=[DS_ADDED],
|
|
742
|
+
) == sub_dict(expected_no_renames, 'subdir/baz')
|
|
743
|
+
assert fcp(find_renames=False,
|
|
744
|
+
diff_filters=[DS_DELETED],
|
|
745
|
+
) == sub_dict(expected_no_renames, 'subdir/bar')
|
|
746
|
+
|
|
747
|
+
expected_renames = {
|
|
727
748
|
b'subdir/baz': [(ChangedPaths.Status.RENAMED, None)],
|
|
728
749
|
}
|
|
750
|
+
assert fcp(find_renames=True) == expected_renames
|
|
751
|
+
assert fcp(find_renames=True,
|
|
752
|
+
diff_filters=[DS_ADDED, DS_MODIFIED, DS_DELETED]
|
|
753
|
+
) == {}
|
|
754
|
+
assert fcp(find_renames=True,
|
|
755
|
+
diff_filters=[DS_RENAMED]) == expected_renames
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
def test_find_changed_paths_rename_and_copy(diff_fixture):
|
|
759
|
+
wrapper = diff_fixture.repo_wrapper
|
|
760
|
+
repo = wrapper.repo
|
|
761
|
+
|
|
762
|
+
ctx0 = wrapper.commit_file('foo')
|
|
763
|
+
wrapper.command('cp', repo.root + b'/foo', repo.root + b'/bar')
|
|
764
|
+
wrapper.command('mv', repo.root + b'/foo', repo.root + b'/bar2')
|
|
765
|
+
ctx1 = wrapper.commit(rel_paths=['foo', 'bar', 'bar2'])
|
|
766
|
+
|
|
767
|
+
def fcp(find_renames=True, **opts):
|
|
768
|
+
return diff_fixture.find_changed_paths_commits(
|
|
769
|
+
[ctx1.hex()],
|
|
770
|
+
compare_to=[ctx0.hex()],
|
|
771
|
+
find_renames=find_renames,
|
|
772
|
+
**opts)
|
|
773
|
+
|
|
774
|
+
expected = {
|
|
775
|
+
b'bar': [(ChangedPaths.Status.COPIED, None)],
|
|
776
|
+
b'bar2': [(ChangedPaths.Status.RENAMED, None)],
|
|
777
|
+
}
|
|
729
778
|
|
|
730
|
-
|
|
731
|
-
|
|
779
|
+
assert fcp() == expected
|
|
780
|
+
assert fcp(diff_filters=[DS_ADDED]) == {}
|
|
781
|
+
assert fcp(diff_filters=[DS_RENAMED]) == sub_dict(expected, 'bar2')
|
|
782
|
+
assert fcp(diff_filters=[DS_COPIED]) == sub_dict(expected, 'bar')
|
|
732
783
|
|
|
733
784
|
|
|
734
785
|
def test_get_patch_id(diff_fixture):
|
|
@@ -24,6 +24,7 @@ from hgext3rd.heptapod.branch import (
|
|
|
24
24
|
gitlab_branches,
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
+
from hgitaly.revision import ZERO_SHA_STR
|
|
27
28
|
from hgitaly.stub.operations_pb2 import (
|
|
28
29
|
OperationBranchUpdate,
|
|
29
30
|
UserCommitFilesAction,
|
|
@@ -832,3 +833,49 @@ def test_user_commit_files(operations_fixture, tmpdir):
|
|
|
832
833
|
UserCommitFilesRequest(action=UserCommitFilesAction())
|
|
833
834
|
])
|
|
834
835
|
assert exc_info.value.code() == StatusCode.INVALID_ARGUMENT
|
|
836
|
+
|
|
837
|
+
|
|
838
|
+
def test_user_commit_files_null_old_oid(operations_fixture, tmpdir):
|
|
839
|
+
fixture = operations_fixture
|
|
840
|
+
commit_files = fixture.user_commit_files
|
|
841
|
+
ActionType = UserCommitFilesActionHeader.ActionType
|
|
842
|
+
|
|
843
|
+
fixture.hg_native = True # TODO just remove hg-git now
|
|
844
|
+
fixture.heptapod_permission = 'publish'
|
|
845
|
+
wrapper = fixture.repo_wrapper
|
|
846
|
+
with open(wrapper.path / '.hg/hgrc', 'a') as hgrcf:
|
|
847
|
+
# this is part of the normally included `required.hgrc` of
|
|
848
|
+
# py-heptapod
|
|
849
|
+
hgrcf.write('\n'.join((
|
|
850
|
+
"[experimental]",
|
|
851
|
+
"topic.publish-bare-branch = yes"
|
|
852
|
+
""
|
|
853
|
+
)))
|
|
854
|
+
|
|
855
|
+
gl_topic = b'topic/default/zetop'
|
|
856
|
+
gl_branch = b'branch/default'
|
|
857
|
+
|
|
858
|
+
wrapper.commit_file('foo') # first commit on `branch/default`
|
|
859
|
+
|
|
860
|
+
# now let's start a topic, passing explicitely old_oid indicating
|
|
861
|
+
# that is does not exist yet
|
|
862
|
+
two_lines = b"zz\nsecond proto message"
|
|
863
|
+
resp = commit_files(
|
|
864
|
+
branch_name=gl_topic,
|
|
865
|
+
start_branch_name=gl_branch,
|
|
866
|
+
commit_message=b'New topic',
|
|
867
|
+
expected_old_oid=ZERO_SHA_STR,
|
|
868
|
+
actions=(dict(action=ActionType.CREATE,
|
|
869
|
+
file_path=b'intop',
|
|
870
|
+
content=two_lines,
|
|
871
|
+
),
|
|
872
|
+
)
|
|
873
|
+
)
|
|
874
|
+
hex1 = resp.branch_update.commit_id.encode()
|
|
875
|
+
|
|
876
|
+
wrapper.reload()
|
|
877
|
+
ctx1 = wrapper.repo[hex1]
|
|
878
|
+
|
|
879
|
+
assert ctx1.description() == b'New topic'
|
|
880
|
+
assert ctx1.branch() == b'default'
|
|
881
|
+
assert ctx1.topic() == b'zetop'
|
|
@@ -19,6 +19,14 @@ from mercurial_testhelpers import (
|
|
|
19
19
|
)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
+
def delta_node(delta): # pragma no cover (coverage_mercurial not ready for v7)
|
|
23
|
+
"""Compatibility wrapper for changes in Mercurial 7.1"""
|
|
24
|
+
if isinstance(delta, tuple): # hg<7.1
|
|
25
|
+
return delta[0]
|
|
26
|
+
else: # hg>7.0
|
|
27
|
+
return delta.node
|
|
28
|
+
|
|
29
|
+
|
|
22
30
|
def list_bundle_contents(path):
|
|
23
31
|
"""Simple utility to list the contents.
|
|
24
32
|
|
|
@@ -35,5 +43,6 @@ def list_bundle_contents(path):
|
|
|
35
43
|
version = part.params.get(b'version', b'01')
|
|
36
44
|
cg = changegroup.getunbundler(version, part, b'UN')
|
|
37
45
|
cg.changelogheader()
|
|
38
|
-
nodes.extend(node_hex(delta
|
|
46
|
+
nodes.extend(node_hex(delta_node(delta))
|
|
47
|
+
for delta in cg.deltaiter())
|
|
39
48
|
return dict(nodes=nodes)
|
|
@@ -1,8 +1,30 @@
|
|
|
1
|
+
import grpc
|
|
2
|
+
from grpc_health.v1.health_pb2 import (
|
|
3
|
+
HealthCheckRequest,
|
|
4
|
+
HealthCheckResponse,
|
|
5
|
+
)
|
|
6
|
+
from grpc_health.v1.health_pb2_grpc import HealthStub
|
|
7
|
+
|
|
1
8
|
from hgitaly.stub.repository_pb2 import RepositoryExistsRequest
|
|
2
9
|
from hgitaly.stub.shared_pb2 import Repository
|
|
3
10
|
from hgitaly.stub.repository_pb2_grpc import RepositoryServiceStub
|
|
4
11
|
|
|
5
12
|
|
|
13
|
+
def wait_health_check(gitaly_channel):
|
|
14
|
+
health_stub = HealthStub(gitaly_channel)
|
|
15
|
+
req = HealthCheckRequest()
|
|
16
|
+
attempts = 0
|
|
17
|
+
while attempts < 3:
|
|
18
|
+
try:
|
|
19
|
+
resp = health_stub.Check(req, timeout=5)
|
|
20
|
+
assert resp.status == HealthCheckResponse.SERVING
|
|
21
|
+
break
|
|
22
|
+
except (AssertionError, grpc.RpcError): # pragma no cover
|
|
23
|
+
attempts += 1
|
|
24
|
+
if attempts >= 3:
|
|
25
|
+
raise
|
|
26
|
+
|
|
27
|
+
|
|
6
28
|
def wait_server_accepts_connection(gitaly_channel, timeout=5):
|
|
7
29
|
"""Wait for a server using the Gitaly protocol to accept connections.
|
|
8
30
|
|
|
@@ -94,7 +94,10 @@ def test_operation_error_treatment():
|
|
|
94
94
|
context = FakeContext() # making sure test does not pass by coincidence
|
|
95
95
|
with pytest.raises(RuntimeError):
|
|
96
96
|
with operation_error_treatment(context, PublishChangesetError, logger):
|
|
97
|
-
|
|
97
|
+
# we have to force the message to `str`
|
|
98
|
+
err = GitLabPreReceiveError("converted by parent to bytes")
|
|
99
|
+
err.message = 'again protected'
|
|
100
|
+
raise err
|
|
98
101
|
|
|
99
102
|
assert context.code() == StatusCode.PERMISSION_DENIED
|
|
100
103
|
trailing = context.trailing_metadata()
|
|
@@ -43,6 +43,7 @@ from hgitaly.gitlab_ref import (
|
|
|
43
43
|
)
|
|
44
44
|
from hgitaly.servicer import SKIP_HOOKS_MD_KEY
|
|
45
45
|
from hgitaly.stub.shared_pb2 import Repository
|
|
46
|
+
from hgitaly.testing.grpc import wait_health_check
|
|
46
47
|
from hgitaly.testing.storage import (
|
|
47
48
|
DEFAULT_STORAGE_NAME,
|
|
48
49
|
storage_path,
|
|
@@ -489,15 +490,21 @@ class RpcHelper(BaseRpcHelper):
|
|
|
489
490
|
self.chunked_fields_remover = chunked_fields_remover
|
|
490
491
|
self.chunks_concatenator = chunks_concatenator
|
|
491
492
|
|
|
492
|
-
def
|
|
493
|
-
|
|
493
|
+
def channel(self, vcs):
|
|
494
|
+
if vcs == 'git':
|
|
495
|
+
return self.comparison.gitaly_channel
|
|
494
496
|
|
|
495
497
|
if self.hg_server == 'rhgitaly':
|
|
496
|
-
|
|
498
|
+
return self.comparison.rhgitaly_channel
|
|
497
499
|
else:
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
500
|
+
return self.comparison.hgitaly_channel
|
|
501
|
+
|
|
502
|
+
def wait_health_check(self, vcs):
|
|
503
|
+
wait_health_check(self.channel(vcs))
|
|
504
|
+
|
|
505
|
+
def init_stubs(self):
|
|
506
|
+
self.stubs = {vcs: self.stub_cls(self.channel(vcs))
|
|
507
|
+
for vcs in ('hg', 'git')}
|
|
501
508
|
|
|
502
509
|
def hg2git(self, hg_sha):
|
|
503
510
|
"""Convert a Mercurial hex SHA to its counterpart SHA in Git repo.
|
|
@@ -42,6 +42,15 @@ class RHGitalyServer:
|
|
|
42
42
|
@contextmanager
|
|
43
43
|
def running(self):
|
|
44
44
|
env = dict(os.environ)
|
|
45
|
+
# As side effect of mercurial_testhelpers.ui.make_ui() (part of
|
|
46
|
+
# RepoWrapper init), HGRCPATH can have been set to the empty string
|
|
47
|
+
# by previous test modules, but this makes RHGitaly run without
|
|
48
|
+
# evolve and topic, leading to surprises in the hg processes it
|
|
49
|
+
# spawns, so we need to prevent that.
|
|
50
|
+
# TODO try and fix mercurial_testhelpers, it should be possible
|
|
51
|
+
# for it to set HGRCPATH in `repo.ui.environ` only
|
|
52
|
+
if env.get('HGRCPATH') == '':
|
|
53
|
+
del env['HGRCPATH']
|
|
45
54
|
env['GITALY_TESTING_NO_GIT_HOOKS'] = "1" # will be eventually useful
|
|
46
55
|
timeout = int(env.pop('RHGITALY_STARTUP_TIMEOUT', '30').strip())
|
|
47
56
|
|
|
@@ -531,6 +531,8 @@ def test_compare_count_find_commits(gitaly_rhgitaly_comparison, hg_server):
|
|
|
531
531
|
normalizer=normalizer,
|
|
532
532
|
)
|
|
533
533
|
rpc_helper.sorted = False
|
|
534
|
+
# if with RHGitaly, ensure that the sidecar is ready:
|
|
535
|
+
rpc_helper.wait_health_check('hg')
|
|
534
536
|
|
|
535
537
|
@contextmanager
|
|
536
538
|
def sorted_comparison():
|
|
@@ -581,6 +583,11 @@ def test_compare_count_find_commits(gitaly_rhgitaly_comparison, hg_server):
|
|
|
581
583
|
for r2 in all_revs:
|
|
582
584
|
assert_compare(revision=r1 + range_str + r2)
|
|
583
585
|
|
|
586
|
+
# with message_regex
|
|
587
|
+
rx = 'FOO.*zoO' # tests case insensitivity
|
|
588
|
+
assert_compare(revision=ctx4.hex(), message_regex=rx)
|
|
589
|
+
assert_compare(all=True, message_regex=rx)
|
|
590
|
+
|
|
584
591
|
# when `revision` is provided as a ref to a single commit
|
|
585
592
|
refs = [b'', ctx0.hex(), b'topic/default/sampletop', ctx2.hex(),
|
|
586
593
|
b'branch/stable', b'branch/default', b'HEAD']
|