hgitaly 1.3.2__tar.gz → 2.10.0__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-1.3.2/hgitaly.egg-info → hgitaly-2.10.0}/PKG-INFO +10 -1
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgext3rd/hgitaly/__init__.py +9 -0
- hgitaly-2.10.0/hgitaly/VERSION +1 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/diff.py +47 -20
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/errors.py +24 -0
- hgitaly-2.10.0/hgitaly/file_content.py +160 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/gitlab_ref.py +12 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/logging.py +10 -6
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/message.py +4 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/repository.py +0 -28
- hgitaly-2.10.0/hgitaly/scripts.py +264 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/mono.py +3 -0
- hgitaly-2.10.0/hgitaly/service/analysis.py +51 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/commit.py +64 -11
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/diff.py +5 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/interceptors.py +14 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/mercurial_operations.py +20 -12
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/operations.py +34 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/ref.py +106 -4
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/repository.py +5 -76
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/server.py +11 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/fixture.py +12 -6
- hgitaly-2.10.0/hgitaly/service/tests/test_analysis.py +111 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_commit.py +51 -22
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_diff.py +46 -1
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_mercurial_operations.py +56 -40
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_operations.py +22 -23
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_ref.py +113 -20
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_repository_service.py +4 -105
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_server.py +8 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/ssh.py +2 -0
- hgitaly-2.10.0/hgitaly/stub/analysis_pb2.py +41 -0
- hgitaly-2.10.0/hgitaly/stub/analysis_pb2_grpc.py +78 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/blob_pb2.py +16 -16
- hgitaly-2.10.0/hgitaly/stub/commit_pb2.py +255 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/commit_pb2_grpc.py +2 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/diff_pb2.py +62 -22
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/diff_pb2_grpc.py +106 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/errors_pb2.py +3 -1
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/lint_pb2.py +4 -3
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/mercurial_repository_pb2.py +16 -8
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/mercurial_repository_pb2_grpc.py +41 -0
- hgitaly-2.10.0/hgitaly/stub/operations_pb2.py +201 -0
- hgitaly-2.10.0/hgitaly/stub/remote_pb2.py +55 -0
- hgitaly-2.10.0/hgitaly/stub/remote_pb2_grpc.py +151 -0
- hgitaly-2.10.0/hgitaly/stub/repository_pb2.py +390 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/repository_pb2_grpc.py +73 -141
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/server_pb2.py +17 -17
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/server_pb2_grpc.py +25 -23
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/shared_pb2.py +11 -9
- hgitaly-2.10.0/hgitaly/testing/storage.py +27 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/common.py +8 -8
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_branch.py +4 -1
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_errors.py +6 -6
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_gitlab_ref.py +20 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_messages.py +5 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0/hgitaly.egg-info}/PKG-INFO +10 -1
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly.egg-info/SOURCES.txt +12 -0
- hgitaly-2.10.0/hgitaly.egg-info/entry_points.txt +2 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly.egg-info/requires.txt +2 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/install-requirements.txt +2 -2
- {hgitaly-1.3.2 → hgitaly-2.10.0}/setup.py +11 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/comparison.py +247 -101
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/conftest.py +53 -3
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/gitaly.py +8 -4
- hgitaly-2.10.0/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +169 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/rhgitaly.py +26 -3
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_blob_tree.py +174 -1
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_commit.py +221 -8
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_diff.py +48 -14
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_gitaly_server.py +7 -4
- hgitaly-2.10.0/tests_with_gitaly/test_mercurial_repository.py +232 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_operations.py +37 -30
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_ref.py +127 -1
- hgitaly-2.10.0/tests_with_gitaly/test_remote.py +125 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_repository_service.py +41 -75
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_server.py +15 -2
- hgitaly-1.3.2/hgitaly/VERSION +0 -1
- hgitaly-1.3.2/hgitaly/stub/commit_pb2.py +0 -251
- hgitaly-1.3.2/hgitaly/stub/operations_pb2.py +0 -197
- hgitaly-1.3.2/hgitaly/stub/repository_pb2.py +0 -401
- hgitaly-1.3.2/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +0 -50
- {hgitaly-1.3.2 → hgitaly-2.10.0}/LICENSE +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/MANIFEST.in +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/README.md +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgext3rd/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgext3rd/hgitaly/revset.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgext3rd/hgitaly/tests/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgext3rd/hgitaly/tests/test_revset.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgext3rd/hgitaly/tests/test_serve.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/branch.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/changelog.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/feature.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/file_context.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/git.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/license_detector/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/license_detector/spdx-licenses.json +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/linguist/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/linguist/languages.json +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/manifest.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/oid.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/pagination.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/path.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/peer.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/procutil.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/revision.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/revset.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/address.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/prefork.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/tests/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/tests/test_address.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/tests/test_mono.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/tests/test_prefork.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/tests/test_worker.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/server/worker.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/blob.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/mercurial_changeset.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/mercurial_repository.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_blob.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_default_branch.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_mercurial_changeset.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/service/tests/test_mercurial_repository.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/servicer.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stream.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/blob_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/errors_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/lint_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/mercurial_changeset_pb2.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/mercurial_changeset_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/mercurial_operations_pb2.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/mercurial_operations_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/operations_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/ref_pb2.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/ref_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/stub/shared_pb2_grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tag.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/bundle.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/context.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/grpc.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/ssh.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/sshd.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/tests/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/testing/tests/test_sshd.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_diff.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_feature.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_file_context.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_license_detector.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_linguist.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_manifest.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_oid.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_peer.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_repository.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_revision.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_revset.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_servicer.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_stream.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_tag.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/tests/test_workdir.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/util.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly/workdir.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly.egg-info/dependency_links.txt +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/hgitaly.egg-info/top_level.txt +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/setup.cfg +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/__init__.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_comparison.py +0 -0
- {hgitaly-1.3.2 → hgitaly-2.10.0}/tests_with_gitaly/test_rhgitaly_server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hgitaly
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.10.0
|
|
4
4
|
Summary: Server-side implementation of Gitaly protocol for Mercurial
|
|
5
5
|
Home-page: https://foss.heptapod.net/heptapod/hgitaly
|
|
6
6
|
Author: Georges Racinet
|
|
@@ -10,6 +10,15 @@ Keywords: hg mercurial heptapod gitlab
|
|
|
10
10
|
Requires-Python: >=3.8
|
|
11
11
|
Description-Content-Type: text/markdown
|
|
12
12
|
License-File: LICENSE
|
|
13
|
+
Requires-Dist: heptapod>=5.0.0dev0
|
|
14
|
+
Requires-Dist: protobuf~=4.21.0
|
|
15
|
+
Requires-Dist: grpcio~=1.58.0
|
|
16
|
+
Requires-Dist: grpcio-status~=1.58.0
|
|
17
|
+
Requires-Dist: grpc-interceptor
|
|
18
|
+
Requires-Dist: hg-loggingmod>=0.4.1
|
|
19
|
+
Requires-Dist: psutil
|
|
20
|
+
Requires-Dist: importlib_resources~=2.0.0
|
|
21
|
+
Requires-Dist: spdx-lookup
|
|
13
22
|
|
|
14
23
|
# HGitaly
|
|
15
24
|
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
7
7
|
|
|
8
8
|
# flake8: noqa E402
|
|
9
|
+
import os
|
|
10
|
+
import time
|
|
9
11
|
from mercurial.i18n import _
|
|
10
12
|
from mercurial import (
|
|
11
13
|
demandimport,
|
|
@@ -81,6 +83,13 @@ def serve(ui, **opts):
|
|
|
81
83
|
By default the root of repositories is read from the
|
|
82
84
|
`heptapod.repositories-root` configuration item if present.
|
|
83
85
|
"""
|
|
86
|
+
# local time does not make sense for a server-oriented process,
|
|
87
|
+
# so let's switch to UTC. Mercurial itself is transparent about that
|
|
88
|
+
# server-side commits will be recorded as been done UTC, which is fine
|
|
89
|
+
# (it does not change the recorded time, which is always UTC, just some
|
|
90
|
+
# ways of displaying it).
|
|
91
|
+
os.environ['TZ'] = 'UTC'
|
|
92
|
+
time.tzset()
|
|
84
93
|
listen_urls = [pycompat.sysstr(u) for u in opts['listen']]
|
|
85
94
|
if not listen_urls:
|
|
86
95
|
# Any default in the option declaration would be added to
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.10.0
|
|
@@ -46,17 +46,19 @@ Status_Type_Map = dict(
|
|
|
46
46
|
added=ChangedPaths.Status.ADDED,
|
|
47
47
|
modified=ChangedPaths.Status.MODIFIED,
|
|
48
48
|
removed=ChangedPaths.Status.DELETED,
|
|
49
|
+
renamed=ChangedPaths.Status.RENAMED,
|
|
49
50
|
# Note: Mercurial includes TYPE_CHANGE
|
|
50
51
|
# (symlink, regular file, submodule...etc) in MODIFIED status
|
|
51
52
|
)
|
|
52
53
|
"""Mapping status object attributes to ChangedPaths enum."""
|
|
53
54
|
|
|
54
55
|
COPIED = ChangedPaths.Status.COPIED
|
|
56
|
+
RENAMED = ChangedPaths.Status.RENAMED
|
|
55
57
|
DIFF_HUNKS_START_RX = re.compile(rb'^(--- )|^(Binary file)')
|
|
56
58
|
"""To match the header line right before hunks start getting dumped."""
|
|
57
59
|
|
|
58
60
|
|
|
59
|
-
def changed_paths(repo, from_ctx, to_ctx, base_path):
|
|
61
|
+
def changed_paths(repo, from_ctx, to_ctx, base_path, find_renames=False):
|
|
60
62
|
if base_path is None:
|
|
61
63
|
matcher = None
|
|
62
64
|
path_trim_at = 0
|
|
@@ -74,26 +76,33 @@ def changed_paths(repo, from_ctx, to_ctx, base_path):
|
|
|
74
76
|
patterns=[b'path:' + base_path])
|
|
75
77
|
path_trim_at = len(base_path) + 1
|
|
76
78
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
copies.pathcopies(from_ctx, to_ctx, match=matcher),
|
|
81
|
-
trim_at=path_trim_at))
|
|
82
|
-
copied_paths = set(cp.path for cp in copied)
|
|
79
|
+
copy_info = copies.pathcopies(from_ctx, to_ctx, match=matcher)
|
|
80
|
+
# copies do not distinguish actual copies from renames. The difference
|
|
81
|
+
# will be that a rename goes with deletion of the original.
|
|
83
82
|
|
|
84
83
|
status = from_ctx.status(to_ctx, match=matcher)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
84
|
+
# this will remove renames from copy_info, keeping only actual copies
|
|
85
|
+
yield from status_changed_paths(from_ctx, to_ctx, status, copy_info,
|
|
86
|
+
find_renames=find_renames,
|
|
87
|
+
trim_at=path_trim_at)
|
|
88
|
+
yield from copy_changed_paths(from_ctx,
|
|
89
|
+
to_ctx,
|
|
90
|
+
copy_info,
|
|
91
|
+
trim_at=path_trim_at)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def status_changed_paths(from_ctx, to_ctx, status, copy_info,
|
|
95
|
+
find_renames=False, trim_at=0):
|
|
96
|
+
rcopy_info = {v: k for k, v in copy_info.items()}
|
|
94
97
|
"""Return ChangedPaths from Mercurial status object"""
|
|
95
98
|
for stype in ['added', 'modified', 'removed']:
|
|
96
99
|
for path in status.__getattribute__(stype):
|
|
100
|
+
copied_from = copy_info.get(path)
|
|
101
|
+
if copied_from is not None:
|
|
102
|
+
if copied_from not in status.removed or find_renames:
|
|
103
|
+
continue
|
|
104
|
+
|
|
105
|
+
old_path = b''
|
|
97
106
|
if stype == 'added':
|
|
98
107
|
old_mode = OBJECT_MODE_DOES_NOT_EXIST
|
|
99
108
|
old_blob_id = NULL_BLOB_OID
|
|
@@ -102,8 +111,21 @@ def status_changed_paths(from_ctx, to_ctx, status, trim_at=0):
|
|
|
102
111
|
old_blob_id = ctx_blob_oid(from_ctx, path)
|
|
103
112
|
|
|
104
113
|
if stype == 'removed':
|
|
105
|
-
|
|
106
|
-
|
|
114
|
+
new_path = rcopy_info.get(path)
|
|
115
|
+
if new_path is None:
|
|
116
|
+
new_mode = OBJECT_MODE_DOES_NOT_EXIST
|
|
117
|
+
new_blob_id = NULL_BLOB_OID
|
|
118
|
+
else:
|
|
119
|
+
del copy_info[new_path]
|
|
120
|
+
if find_renames:
|
|
121
|
+
stype = 'renamed'
|
|
122
|
+
old_path = path
|
|
123
|
+
path = new_path
|
|
124
|
+
new_mode = git_perms(to_ctx.filectx(new_path))
|
|
125
|
+
new_blob_id = ctx_blob_oid(to_ctx, new_path)
|
|
126
|
+
else:
|
|
127
|
+
new_mode = OBJECT_MODE_DOES_NOT_EXIST
|
|
128
|
+
new_blob_id = NULL_BLOB_OID
|
|
107
129
|
else:
|
|
108
130
|
new_mode = git_perms(to_ctx.filectx(path))
|
|
109
131
|
new_blob_id = ctx_blob_oid(to_ctx, path)
|
|
@@ -114,11 +136,13 @@ def status_changed_paths(from_ctx, to_ctx, status, trim_at=0):
|
|
|
114
136
|
new_mode=new_mode,
|
|
115
137
|
old_blob_id=old_blob_id,
|
|
116
138
|
new_blob_id=new_blob_id,
|
|
139
|
+
old_path=old_path,
|
|
117
140
|
status=Status_Type_Map[stype]
|
|
118
141
|
)
|
|
119
142
|
|
|
120
143
|
|
|
121
|
-
def copy_changed_paths(from_ctx, to_ctx, path_copies,
|
|
144
|
+
def copy_changed_paths(from_ctx, to_ctx, path_copies,
|
|
145
|
+
trim_at=0, find_renames=False):
|
|
122
146
|
"""Return ChangedPaths for the given paths, relative to base_path.
|
|
123
147
|
|
|
124
148
|
Given that Gitaly currently (gitaly@c54d613d0) does not pass
|
|
@@ -129,8 +153,11 @@ def copy_changed_paths(from_ctx, to_ctx, path_copies, trim_at=0):
|
|
|
129
153
|
for target, source in path_copies.items():
|
|
130
154
|
yield ChangedPaths(path=target[trim_at:],
|
|
131
155
|
status=COPIED,
|
|
132
|
-
old_mode=git_perms(
|
|
156
|
+
old_mode=git_perms(from_ctx.filectx(source)),
|
|
157
|
+
old_blob_id=ctx_blob_oid(from_ctx, source),
|
|
133
158
|
new_mode=git_perms(to_ctx.filectx(target)),
|
|
159
|
+
new_blob_id=ctx_blob_oid(to_ctx, target),
|
|
160
|
+
old_path=source[trim_at:],
|
|
134
161
|
)
|
|
135
162
|
|
|
136
163
|
|
|
@@ -121,3 +121,27 @@ def operation_error_treatment(context, error_message_class, logger,
|
|
|
121
121
|
# // The post-receive hook runs after references have been updated
|
|
122
122
|
# // and any failures of it are ignored.
|
|
123
123
|
logger.error("Error in GitLab post-receive hook: %r", exc.message)
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
class MercurialNotFound(LookupError):
|
|
127
|
+
"""General class for all failed lookups.
|
|
128
|
+
|
|
129
|
+
Better for us that to use `hg.errors.LookupError` because the latter is
|
|
130
|
+
not systematically raised. Anyway, we need our own articulation point.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class MercurialPathNotFound(MercurialNotFound):
|
|
135
|
+
"""Express that some path could not be found.
|
|
136
|
+
|
|
137
|
+
This is generally in the context of some changeset that the caller is
|
|
138
|
+
aware of, but it could be in an entire revset, in the workdir…
|
|
139
|
+
"""
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
class MercurialChangesetNotFound(MercurialNotFound):
|
|
143
|
+
"""Express that one or serveral changesets could not be found.
|
|
144
|
+
|
|
145
|
+
In case the caller did a call possibly involving several changesets,
|
|
146
|
+
the failing, perhaps more specific, expression can be set as argument.
|
|
147
|
+
"""
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Copyright 2024 Georges Racinet <georges.racinet@cloudcrane.io>
|
|
2
|
+
#
|
|
3
|
+
# This software may be used and distributed according to the terms of the
|
|
4
|
+
# GNU General Public License version 2 or any later version.
|
|
5
|
+
#
|
|
6
|
+
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
7
|
+
import re
|
|
8
|
+
|
|
9
|
+
from mercurial import (
|
|
10
|
+
error as hgerror,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
from .errors import (
|
|
14
|
+
MercurialPathNotFound,
|
|
15
|
+
MercurialChangesetNotFound,
|
|
16
|
+
)
|
|
17
|
+
from .oid import extract_blob_oid
|
|
18
|
+
from .stub.analysis_pb2 import (
|
|
19
|
+
CheckBlobsGeneratedRequest,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def frozen_bytes_set(it):
|
|
24
|
+
return frozenset(s.encode('ascii') for s in it)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
# compare go-enry/data/generated.go
|
|
28
|
+
GENERATED_FILE_PATH_REGEXPS = [
|
|
29
|
+
re.compile(b'|'.join((
|
|
30
|
+
rb'(^Pods|/Pods)/', # Cocoa pods
|
|
31
|
+
rb'(^|/)Carthage/Build/', # Carthage build
|
|
32
|
+
rb'\.feature\.css$', # Generated NET specflow feature file
|
|
33
|
+
rb'node_modules/', # Node modules
|
|
34
|
+
# Go vendor
|
|
35
|
+
rb'vendor/([-0-9A-Za-z]+\.)+(com|edu|gov|in|me|net|org|fm|io)',
|
|
36
|
+
rb'(Gopkg|glide).lock$', # Go lock
|
|
37
|
+
rb'(^|/)(\w+\.)?esy.lock$`', # Esy lock
|
|
38
|
+
rb'npm-shrinkwrap.json$',
|
|
39
|
+
rb'package-lock.json$', # NPM package lock
|
|
40
|
+
rb'(^|/)\.pnp\.(c|m)?js$', # Yarn plugnplay
|
|
41
|
+
rb'Godeps/',
|
|
42
|
+
rb'composer.lock$',
|
|
43
|
+
rb'.\.zep\.(?:c|h|php)$', # Generated by zephir
|
|
44
|
+
rb'Cargo.lock$',
|
|
45
|
+
rb'Pipfile.lock$', # Pipenv lock
|
|
46
|
+
rb'__generated__/', # GraphQL relay
|
|
47
|
+
rb'\.(js|css)\.map$', # Source map
|
|
48
|
+
))),
|
|
49
|
+
re.compile(b'|'.join((
|
|
50
|
+
rb'\.designer\.(cs|vb)$', # NET designer file
|
|
51
|
+
)), re.IGNORECASE),
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
# compare go-enry/data/generated.go
|
|
55
|
+
GENERATED_FILE_EXTENSIONS = frozen_bytes_set((
|
|
56
|
+
# Xcode
|
|
57
|
+
'nib',
|
|
58
|
+
'xcworkspacedata',
|
|
59
|
+
'xcuserstate',
|
|
60
|
+
# TODO complete the list
|
|
61
|
+
))
|
|
62
|
+
|
|
63
|
+
GENERATED_LINE_RX = re.compile(
|
|
64
|
+
b'|'.join((
|
|
65
|
+
# Source Map
|
|
66
|
+
rb'\A{"version":\d+',
|
|
67
|
+
rb'\A/\*\*Begin line maps\. \*\*/{',
|
|
68
|
+
# Generated NetDoc TODO should be only for .xml files
|
|
69
|
+
rb'\A.*$.*<doc>.*(\r)?\n.*<assembly>(\r)?\n.*</doc>(\r)?\n.*\Z',
|
|
70
|
+
# PEG.js
|
|
71
|
+
rb'^(?:[^/]|/[^\*])*/\*(?:[^\*]|\*[^/])*Generated by PEG.js',
|
|
72
|
+
# Generated Go (actually our version is more general, but anything
|
|
73
|
+
# matching this regexp is looking for trouble!
|
|
74
|
+
rb'Code generated by',
|
|
75
|
+
# Protocol Buffers, general case
|
|
76
|
+
b"Generated by the protocol buffer compiler. DO NOT EDIT!",
|
|
77
|
+
# Protocol Buffers, JavaScript (should be only line 6 and crossed with
|
|
78
|
+
# extension, but given the content, matching this is acceptable
|
|
79
|
+
# TODO unless we are looking at a code generator!
|
|
80
|
+
b"GENERATED CODE -- DO NOT EDIT!",
|
|
81
|
+
# Apache Thrift
|
|
82
|
+
b"Autogenerated by Thrift Compiler",
|
|
83
|
+
# JNI header (again more general than go-enry, because we don't want
|
|
84
|
+
# to assert it to be JNI, just that it is generated)
|
|
85
|
+
rb"/\* DO NOT EDIT THIS FILE - it is machine generated \*/",
|
|
86
|
+
# VCR Cassette TODO should be for .yml files only
|
|
87
|
+
rb"\A.*(\r)?\n.*recorded_with: VCR",
|
|
88
|
+
# Compiled Cython TODO should be .c files only
|
|
89
|
+
rb"\A.*Generated by Cython",
|
|
90
|
+
# (Fortran) module
|
|
91
|
+
rb"\A.*(PCBNEW-LibModule-V|GFORTRAN module version ')",
|
|
92
|
+
# Racc
|
|
93
|
+
rb"# This file is automatically generated by Racc",
|
|
94
|
+
# JFlex
|
|
95
|
+
rb"/\* The following code was generated by JFlex ",
|
|
96
|
+
# Grammar Kit
|
|
97
|
+
rb"// This is a generated file. Not intended for manual editing\.",
|
|
98
|
+
# Roxygen 2
|
|
99
|
+
rb"% Generated by roxygen2: do not edit by hand",
|
|
100
|
+
# Jison
|
|
101
|
+
rb"/\* (parser generated by jison |generated by jison-lex )",
|
|
102
|
+
# gRPC C++
|
|
103
|
+
rb"// Generated by the gRPC",
|
|
104
|
+
# Dart
|
|
105
|
+
rb"generated code\W{2,3}do not modify",
|
|
106
|
+
# Perl's PPPort
|
|
107
|
+
rb"Automatically created by Devel::PPPort",
|
|
108
|
+
# GIMP
|
|
109
|
+
rb'/\* GIMP [a-zA-Z0-9\- ]+ C\-Source image dump \(.+?\.c\) \*/',
|
|
110
|
+
(rb'/\* GIMP header image file format '
|
|
111
|
+
rb'\([a-zA-Z0-9\- ]+\)\: .+?\.h \*/'),
|
|
112
|
+
# Visual Studio 6
|
|
113
|
+
rb'# Microsoft Developer Studio Generated Build File',
|
|
114
|
+
# Haxe
|
|
115
|
+
rb"Generated by Haxe",
|
|
116
|
+
# Jooq
|
|
117
|
+
rb"This file is generated by jOOQ\.",
|
|
118
|
+
)),
|
|
119
|
+
re.MULTILINE
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
# TODO isMinifiedFile, hasSourceMapReference, isCompiledCoffeeScript,
|
|
123
|
+
# isGeneratedPostScript,
|
|
124
|
+
# isGeneratedUnity3DMeta (extension restrictions should really apply)
|
|
125
|
+
# isGeneratedGameMakerStudio, isGeneratedHTML
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def is_blob_generated(repo, blob: CheckBlobsGeneratedRequest.Blob):
|
|
129
|
+
""""Detect if a blob is made of generated data."""
|
|
130
|
+
# For now the Rails application sends revisions in `commit_id:path`
|
|
131
|
+
# format, so close to HGitaly blob oids (!). Probably upstream does not
|
|
132
|
+
# want to use actual Git blob oids, but Gitaly does support them
|
|
133
|
+
colon_split = blob.revision.split(b':', 1)
|
|
134
|
+
if len(colon_split) == 2:
|
|
135
|
+
csid, rpath = colon_split
|
|
136
|
+
else: # direct oid
|
|
137
|
+
csid, rpath = extract_blob_oid(repo, blob.revision.decode('utf-8'))
|
|
138
|
+
|
|
139
|
+
if csid is None or rpath is None:
|
|
140
|
+
raise ValueError("Invalid blob oid")
|
|
141
|
+
|
|
142
|
+
extension = rpath.rsplit(b'.', 1)[-1]
|
|
143
|
+
if extension in GENERATED_FILE_EXTENSIONS:
|
|
144
|
+
return True
|
|
145
|
+
|
|
146
|
+
if any(rx.search(rpath) is not None
|
|
147
|
+
for rx in GENERATED_FILE_PATH_REGEXPS):
|
|
148
|
+
return True
|
|
149
|
+
|
|
150
|
+
try:
|
|
151
|
+
changeset = repo[csid]
|
|
152
|
+
except hgerror.RepoLookupError:
|
|
153
|
+
raise MercurialChangesetNotFound(csid)
|
|
154
|
+
|
|
155
|
+
try:
|
|
156
|
+
filectx = changeset.filectx(rpath)
|
|
157
|
+
except KeyError:
|
|
158
|
+
raise MercurialPathNotFound(rpath)
|
|
159
|
+
|
|
160
|
+
return GENERATED_LINE_RX.search(filectx.data()) is not None
|
|
@@ -28,7 +28,11 @@ from hgext3rd.heptapod.special_ref import (
|
|
|
28
28
|
parse_special_ref,
|
|
29
29
|
special_refs,
|
|
30
30
|
)
|
|
31
|
-
from hgext3rd.heptapod.keep_around import
|
|
31
|
+
from hgext3rd.heptapod.keep_around import (
|
|
32
|
+
iter_keep_arounds,
|
|
33
|
+
KEEP_AROUND_REF_PREFIX,
|
|
34
|
+
KEEP_AROUND_REF_PREFIX_LEN,
|
|
35
|
+
)
|
|
32
36
|
|
|
33
37
|
|
|
34
38
|
def gitlab_special_ref_target(repo, ref_path):
|
|
@@ -130,7 +134,13 @@ def has_keep_around(repo, sha):
|
|
|
130
134
|
|
|
131
135
|
def keep_around_ref_path(sha):
|
|
132
136
|
# TODO should move to py-heptapod
|
|
133
|
-
return
|
|
137
|
+
return KEEP_AROUND_REF_PREFIX + sha
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def parse_keep_around_ref_path(ref):
|
|
141
|
+
if not ref.startswith(KEEP_AROUND_REF_PREFIX):
|
|
142
|
+
return None
|
|
143
|
+
return ref[KEEP_AROUND_REF_PREFIX_LEN:]
|
|
134
144
|
|
|
135
145
|
|
|
136
146
|
def iter_keep_arounds_as_refs(repo, deref=True, patterns=None):
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
# GNU General Public License version 2 or any later version.
|
|
5
5
|
#
|
|
6
6
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
7
|
+
import attr
|
|
7
8
|
import logging
|
|
9
|
+
from typing import Any
|
|
8
10
|
|
|
9
11
|
|
|
10
12
|
_missing = object()
|
|
@@ -28,14 +30,16 @@ def extract_correlation(context):
|
|
|
28
30
|
return corr_id
|
|
29
31
|
|
|
30
32
|
|
|
33
|
+
@attr.define
|
|
31
34
|
class LoggerAdapter(logging.LoggerAdapter):
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
self.grpc_context = context
|
|
35
|
-
self.logger = logger
|
|
35
|
+
logger: Any
|
|
36
|
+
grpc_context: Any
|
|
36
37
|
|
|
37
38
|
def process(self, msg, kwargs):
|
|
39
|
+
extra = kwargs.get('extra')
|
|
40
|
+
if extra is None:
|
|
41
|
+
kwargs['extra'] = extra = {}
|
|
42
|
+
|
|
38
43
|
# set on context by interceptor
|
|
39
|
-
|
|
40
|
-
extract_correlation(self.grpc_context)}
|
|
44
|
+
extra['correlation_id'] = extract_correlation(self.grpc_context)
|
|
41
45
|
return msg, kwargs
|
|
@@ -39,34 +39,6 @@ AUTO_PUBLISH_MAPPING = {
|
|
|
39
39
|
AUTO_PUBLISH_REVERSE_MAPPING = {v: k for k, v in AUTO_PUBLISH_MAPPING.items()}
|
|
40
40
|
|
|
41
41
|
|
|
42
|
-
def set_gitlab_project_full_path(repo, full_path: bytes):
|
|
43
|
-
"""Store information about the full path of GitLab Project.
|
|
44
|
-
|
|
45
|
-
In GitLab terminology, ``full_path`` is the URI path, while ``path``
|
|
46
|
-
its the last segment of ``full_path``.
|
|
47
|
-
|
|
48
|
-
In Git repositories, this is stored in config. We could as well use
|
|
49
|
-
the repo-local hgrcs, but it is simpler to use a dedicated file, and
|
|
50
|
-
it makes sense to consider it not part of ``store`` (``svfs``), same
|
|
51
|
-
as ``hgrc``.
|
|
52
|
-
"""
|
|
53
|
-
with repo.wlock():
|
|
54
|
-
repo.vfs.write(GITLAB_PROJECT_FULL_PATH_FILENAME, full_path)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def get_gitlab_project_full_path(repo):
|
|
58
|
-
"""Get the full path of GitLab Project.
|
|
59
|
-
|
|
60
|
-
See also :func:`set_gitlab_project_full_path`.
|
|
61
|
-
|
|
62
|
-
:return: the full path, or ``None`` if not set.
|
|
63
|
-
"""
|
|
64
|
-
try:
|
|
65
|
-
return repo.vfs.read(GITLAB_PROJECT_FULL_PATH_FILENAME)
|
|
66
|
-
except FileNotFoundError:
|
|
67
|
-
return None
|
|
68
|
-
|
|
69
|
-
|
|
70
42
|
def unbundle(repo, bundle_path: str, rails_sync=False):
|
|
71
43
|
"""Call unbundle with proper options and conversions.
|
|
72
44
|
|