hgitaly 18.0.0a0__tar.gz → 18.0.0a1__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.
Files changed (316) hide show
  1. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/.hgtags +1 -0
  2. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/PKG-INFO +1 -1
  3. hgitaly-18.0.0a1/hgitaly/VERSION +1 -0
  4. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/repository.py +11 -4
  5. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_repository_service.py +22 -0
  6. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/servicer.py +7 -1
  7. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_servicer.py +18 -0
  8. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly.egg-info/PKG-INFO +1 -1
  9. hgitaly-18.0.0a1/rust/rhgitaly/src/bundle.rs +300 -0
  10. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/repository/spawner.rs +13 -3
  11. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/repository.rs +47 -4
  12. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/mercurial_aux_git.rs +3 -9
  13. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/repository.rs +78 -123
  14. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_repository_service.py +28 -5
  15. hgitaly-18.0.0a0/hgitaly/VERSION +0 -1
  16. hgitaly-18.0.0a0/rust/rhgitaly/src/bundle.rs +0 -160
  17. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/.coveragerc +0 -0
  18. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/.gitlab-ci.yml +0 -0
  19. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/.hgignore +0 -0
  20. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/LICENSE +0 -0
  21. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/MANIFEST.in +0 -0
  22. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/README.md +0 -0
  23. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ci/heptapod-sftp-push +0 -0
  24. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ci/heptapod-sign-package +0 -0
  25. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ci/heptapod_known_hosts.ssh +0 -0
  26. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ci/upload-rhgitaly +0 -0
  27. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/conftest.py +0 -0
  28. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/dev-requirements.txt +0 -0
  29. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/examples/client.py +0 -0
  30. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/examples/client_list_lcft.py +0 -0
  31. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/generate-stubs +0 -0
  32. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgext3rd/__init__.py +0 -0
  33. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgext3rd/hgitaly/__init__.py +0 -0
  34. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgext3rd/hgitaly/revset.py +0 -0
  35. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgext3rd/hgitaly/tests/__init__.py +0 -0
  36. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgext3rd/hgitaly/tests/test_revset.py +0 -0
  37. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgext3rd/hgitaly/tests/test_serve.py +0 -0
  38. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/__init__.py +0 -0
  39. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/branch.py +0 -0
  40. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/changelog.py +0 -0
  41. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/diff.py +0 -0
  42. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/errors.py +0 -0
  43. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/feature.py +0 -0
  44. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/file_content.py +0 -0
  45. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/file_context.py +0 -0
  46. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/git.py +0 -0
  47. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/gitlab_ref.py +0 -0
  48. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/identification.py +0 -0
  49. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/license_detector/GPL-2.sample +0 -0
  50. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/license_detector/__init__.py +0 -0
  51. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/license_detector/spdx-licenses.json +0 -0
  52. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/linguist/__init__.py +0 -0
  53. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/linguist/languages.json +0 -0
  54. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/logging.py +0 -0
  55. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/manifest.py +0 -0
  56. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/message.py +0 -0
  57. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/oid.py +0 -0
  58. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/pagination.py +0 -0
  59. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/path.py +0 -0
  60. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/peer.py +0 -0
  61. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/procutil.py +0 -0
  62. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/repository.py +0 -0
  63. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/revision.py +0 -0
  64. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/revset.py +0 -0
  65. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/scripts.py +0 -0
  66. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/__init__.py +0 -0
  67. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/address.py +0 -0
  68. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/mono.py +0 -0
  69. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/prefork.py +0 -0
  70. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/tests/__init__.py +0 -0
  71. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/tests/test_address.py +0 -0
  72. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/tests/test_mono.py +0 -0
  73. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/tests/test_prefork.py +0 -0
  74. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/tests/test_worker.py +0 -0
  75. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/server/worker.py +0 -0
  76. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/__init__.py +0 -0
  77. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/analysis.py +0 -0
  78. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/blob.py +0 -0
  79. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/commit.py +0 -0
  80. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/diff.py +0 -0
  81. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/interceptors.py +0 -0
  82. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/mercurial_changeset.py +0 -0
  83. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/mercurial_operations.py +0 -0
  84. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/mercurial_repository.py +0 -0
  85. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/operations.py +0 -0
  86. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/ref.py +0 -0
  87. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/server.py +0 -0
  88. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/__init__.py +0 -0
  89. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/fixture.py +0 -0
  90. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_analysis.py +0 -0
  91. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_blob.py +0 -0
  92. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_commit.py +0 -0
  93. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_default_branch.py +0 -0
  94. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_diff.py +0 -0
  95. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_mercurial_changeset.py +0 -0
  96. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_mercurial_operations.py +0 -0
  97. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_mercurial_repository.py +0 -0
  98. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_operations.py +0 -0
  99. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_ref.py +0 -0
  100. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/service/tests/test_server.py +0 -0
  101. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/ssh.py +0 -0
  102. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stream.py +0 -0
  103. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/__init__.py +0 -0
  104. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/analysis_pb2.py +0 -0
  105. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/analysis_pb2_grpc.py +0 -0
  106. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/blob_pb2.py +0 -0
  107. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/blob_pb2_grpc.py +0 -0
  108. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/commit_pb2.py +0 -0
  109. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/commit_pb2_grpc.py +0 -0
  110. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/diff_pb2.py +0 -0
  111. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/diff_pb2_grpc.py +0 -0
  112. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/errors_pb2.py +0 -0
  113. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/errors_pb2_grpc.py +0 -0
  114. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/lint_pb2.py +0 -0
  115. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/lint_pb2_grpc.py +0 -0
  116. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_aux_git_pb2.py +0 -0
  117. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_aux_git_pb2_grpc.py +0 -0
  118. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_changeset_pb2.py +0 -0
  119. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_changeset_pb2_grpc.py +0 -0
  120. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_operations_pb2.py +0 -0
  121. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_operations_pb2_grpc.py +0 -0
  122. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_repository_pb2.py +0 -0
  123. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/mercurial_repository_pb2_grpc.py +0 -0
  124. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/operations_pb2.py +0 -0
  125. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/operations_pb2_grpc.py +0 -0
  126. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/ref_pb2.py +0 -0
  127. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/ref_pb2_grpc.py +0 -0
  128. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/remote_pb2.py +0 -0
  129. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/remote_pb2_grpc.py +0 -0
  130. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/repository_pb2.py +0 -0
  131. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/repository_pb2_grpc.py +0 -0
  132. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/server_pb2.py +0 -0
  133. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/server_pb2_grpc.py +0 -0
  134. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/shared_pb2.py +0 -0
  135. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/stub/shared_pb2_grpc.py +0 -0
  136. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tag.py +0 -0
  137. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/__init__.py +0 -0
  138. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/bundle.py +0 -0
  139. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/context.py +0 -0
  140. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/authorized_keys +0 -0
  141. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/backup_additional_no_git.tar +0 -0
  142. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/id_ecdsa_user +0 -0
  143. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/known_hosts +0 -0
  144. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/ssh_host_ecdsa_key +0 -0
  145. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/ssh_host_ecdsa_key.pub +0 -0
  146. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/ssh_host_ed25519 +0 -0
  147. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/ssh_host_ed25519.pub +0 -0
  148. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/data/sshd_config +0 -0
  149. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/grpc.py +0 -0
  150. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/multiprocessing.py +0 -0
  151. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/ssh.py +0 -0
  152. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/sshd.py +0 -0
  153. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/storage.py +0 -0
  154. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/tests/__init__.py +0 -0
  155. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/testing/tests/test_sshd.py +0 -0
  156. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/__init__.py +0 -0
  157. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/common.py +0 -0
  158. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_branch.py +0 -0
  159. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_diff.py +0 -0
  160. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_errors.py +0 -0
  161. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_feature.py +0 -0
  162. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_file_context.py +0 -0
  163. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_gitlab_ref.py +0 -0
  164. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_identification.py +0 -0
  165. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_license_detector.py +0 -0
  166. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_linguist.py +0 -0
  167. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_manifest.py +0 -0
  168. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_messages.py +0 -0
  169. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_oid.py +0 -0
  170. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_peer.py +0 -0
  171. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_repository.py +0 -0
  172. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_revision.py +0 -0
  173. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_revset.py +0 -0
  174. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_stream.py +0 -0
  175. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_tag.py +0 -0
  176. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/tests/test_workdir.py +0 -0
  177. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/util.py +0 -0
  178. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly/workdir.py +0 -0
  179. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly.egg-info/SOURCES.txt +0 -0
  180. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly.egg-info/dependency_links.txt +0 -0
  181. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly.egg-info/entry_points.txt +0 -0
  182. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly.egg-info/requires.txt +0 -0
  183. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/hgitaly.egg-info/top_level.txt +0 -0
  184. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/install-requirements.txt +0 -0
  185. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/lint +0 -0
  186. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/analysis.proto +0 -0
  187. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/blob.proto +0 -0
  188. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/cleanup.proto +0 -0
  189. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/cluster.proto +0 -0
  190. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/commit.proto +0 -0
  191. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/conflicts.proto +0 -0
  192. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/diff.proto +0 -0
  193. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/errors.proto +0 -0
  194. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/hook.proto +0 -0
  195. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/internal.proto +0 -0
  196. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/lint.proto +0 -0
  197. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/log.proto +0 -0
  198. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/mercurial-aux-git.proto +0 -0
  199. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/mercurial-changeset.proto +0 -0
  200. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/mercurial-operations.proto +0 -0
  201. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/mercurial-repository.proto +0 -0
  202. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/namespace.proto +0 -0
  203. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/objectpool.proto +0 -0
  204. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/operations.proto +0 -0
  205. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/packfile.proto +0 -0
  206. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/partition.proto +0 -0
  207. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/praefect.proto +0 -0
  208. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/ref.proto +0 -0
  209. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/remote.proto +0 -0
  210. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/repository.proto +0 -0
  211. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/server.proto +0 -0
  212. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/service_config.proto +0 -0
  213. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/shared.proto +0 -0
  214. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/smarthttp.proto +0 -0
  215. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/ssh.proto +0 -0
  216. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/transaction.proto +0 -0
  217. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/protos/wiki.proto +0 -0
  218. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/.ruby-version +0 -0
  219. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/Gemfile +0 -0
  220. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/README.md +0 -0
  221. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/generate-grpc-lib +0 -0
  222. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/hgitaly.gemspec +0 -0
  223. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-aux-git_pb.rb +0 -0
  224. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-aux-git_services_pb.rb +0 -0
  225. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-changeset_pb.rb +0 -0
  226. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-changeset_services_pb.rb +0 -0
  227. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-operations_pb.rb +0 -0
  228. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-operations_services_pb.rb +0 -0
  229. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-repository_pb.rb +0 -0
  230. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/mercurial-repository_services_pb.rb +0 -0
  231. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly/version.rb +0 -0
  232. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/lib/hgitaly.rb +0 -0
  233. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/ruby/run.rb +0 -0
  234. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/run-all-tests +0 -0
  235. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/Cargo.lock +0 -0
  236. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/Cargo.toml +0 -0
  237. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/Makefile +0 -0
  238. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/build-from-tarball.sh +0 -0
  239. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/check-line-width +0 -0
  240. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/README.md +0 -0
  241. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/mercurial.patch +0 -0
  242. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/any.proto +0 -0
  243. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/api.proto +0 -0
  244. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/compiler/plugin.proto +0 -0
  245. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/descriptor.proto +0 -0
  246. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/duration.proto +0 -0
  247. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/empty.proto +0 -0
  248. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/field_mask.proto +0 -0
  249. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/source_context.proto +0 -0
  250. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/struct.proto +0 -0
  251. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/timestamp.proto +0 -0
  252. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/type.proto +0 -0
  253. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/dependencies/proto/google/protobuf/wrappers.proto +0 -0
  254. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/go-enry.rev +0 -0
  255. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/lint +0 -0
  256. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/mercurial.rev +0 -0
  257. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/Cargo.toml +0 -0
  258. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/build.rs +0 -0
  259. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/clippy.toml +0 -0
  260. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/config.rs +0 -0
  261. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/errors.rs +0 -0
  262. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/generated/README.md +0 -0
  263. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/git.rs +0 -0
  264. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/gitlab/mod.rs +0 -0
  265. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/gitlab/reference.rs +0 -0
  266. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/gitlab/revision.rs +0 -0
  267. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/gitlab/state.rs +0 -0
  268. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/glob.rs +0 -0
  269. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/lib.rs +0 -0
  270. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/main.rs +0 -0
  271. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/mercurial.rs +0 -0
  272. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/message.rs +0 -0
  273. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/metadata.rs +0 -0
  274. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/oid.rs +0 -0
  275. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/process.rs +0 -0
  276. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/analysis.rs +0 -0
  277. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/blob.rs +0 -0
  278. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/commit/find_commits.rs +0 -0
  279. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/commit/get_tree_entries.rs +0 -0
  280. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/commit/last_commits.rs +0 -0
  281. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/commit/tree_entry.rs +0 -0
  282. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/commit.rs +0 -0
  283. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/diff.rs +0 -0
  284. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/mercurial_repository.rs +0 -0
  285. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/mod.rs +0 -0
  286. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/ref.rs +0 -0
  287. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/remote.rs +0 -0
  288. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/service/server.rs +0 -0
  289. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/sidecar.rs +0 -0
  290. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/ssh.rs +0 -0
  291. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/streaming.rs +0 -0
  292. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rhgitaly/src/util.rs +0 -0
  293. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/rs-enry.rev +0 -0
  294. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/rust/src-tarball.sh +0 -0
  295. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/setup.cfg +0 -0
  296. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/setup.py +0 -0
  297. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/test-requirements.txt +0 -0
  298. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/__init__.py +0 -0
  299. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/comparison.py +0 -0
  300. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/conftest.py +0 -0
  301. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/gitaly.py +0 -0
  302. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +0 -0
  303. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/rhgitaly.py +0 -0
  304. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_blob_tree.py +0 -0
  305. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_commit.py +0 -0
  306. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_comparison.py +0 -0
  307. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_diff.py +0 -0
  308. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_gitaly_server.py +0 -0
  309. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_mercurial_aux_git.py +0 -0
  310. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_mercurial_operations.py +0 -0
  311. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_mercurial_repository.py +0 -0
  312. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_operations.py +0 -0
  313. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_ref.py +0 -0
  314. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_remote.py +0 -0
  315. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_rhgitaly_server.py +0 -0
  316. {hgitaly-18.0.0a0 → hgitaly-18.0.0a1}/tests_with_gitaly/test_server.py +0 -0
@@ -143,3 +143,4 @@ c964e44bbddc2d8fd41fd72a685535dc7c793150 17.9.2
143
143
  fdf0201ab1df3afbb372f4dd1005009ca37be713 17.11.0a0
144
144
  035b7b7e03a1c34fea4bc7995d54d2c8d088c3f7 17.11.0
145
145
  82eb6e9f12cb5a63bcd6a1f5e9c5ff26fb17b0f6 17.11.1
146
+ c719859a655c7de4b357d1c2ff0046fe55f78e2a 18.0.0a0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hgitaly
3
- Version: 18.0.0a0
3
+ Version: 18.0.0a1
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
@@ -0,0 +1 @@
1
+ 18.0.0a1
@@ -501,13 +501,20 @@ class RepositoryServicer(RepositoryServiceServicer, HGitalyServicer):
501
501
  match_data.seek(0)
502
502
 
503
503
  def set_custom_hooks(self, request, context):
504
- def load_repo(req, context):
505
- return self.load_repo(req.repository, context)
504
+ logger = LoggerAdapter(base_logger, context)
506
505
 
507
506
  with streaming_request_tempfile_extract(
508
507
  request, context,
509
- first_request_handler=load_repo
510
- ) as (repo, tmpf):
508
+ first_request_handler=lambda req, _context: req.repository
509
+ ) as (grpc_repo, tmpf):
510
+ if self.is_repo_aux_git(grpc_repo):
511
+ logger.warning(
512
+ "Heptapod does not currently use custom hooks "
513
+ "on auxiliary Git repositories. Nothing to do"
514
+ )
515
+ return
516
+
517
+ repo = self.load_repo(grpc_repo, context)
511
518
  tmpf.flush()
512
519
  try:
513
520
  restore_additional(repo.ui, repo,
@@ -38,6 +38,7 @@ from hgitaly.revision import ZERO_SHA
38
38
  from hgitaly.stream import WRITE_BUFFER_SIZE
39
39
  from hgitaly.testing import TEST_DATA_DIR
40
40
  from hgitaly.testing.bundle import list_bundle_contents
41
+ from hgitaly.testing.storage import GIT_REPOS_STOWED_AWAY_PATH
41
42
  from hgitaly.workdir import (
42
43
  ROSTER_FILE_NAME as WDS_ROSTER_FILE_NAME,
43
44
  working_directory,
@@ -349,6 +350,19 @@ def test_repository_exists(fixture_with_repo):
349
350
  assert exc_info.value.code() == INVALID_ARGUMENT
350
351
 
351
352
 
353
+ def test_vcs_qualified_storage(fixture_with_repo):
354
+ fixture = fixture_with_repo
355
+
356
+ fixture.grpc_repo.storage_name = 'hg:default'
357
+ assert fixture.exists()
358
+
359
+ fixture.grpc_repo.storage_name = 'rhg:default'
360
+ assert fixture.exists()
361
+
362
+ fixture.grpc_repo.relative_path = 'no/such/path'
363
+ assert not fixture.exists()
364
+
365
+
352
366
  def test_repository_size(fixture_with_repo):
353
367
  fixture = fixture_with_repo
354
368
  size = fixture.size()
@@ -854,6 +868,14 @@ def test_set_custom_hooks(fixture_with_repo, tmpdir, rpc_name):
854
868
  meth(invalid_tarball_path)
855
869
  assert exc_info.value.code() == INTERNAL
856
870
 
871
+ # case of Aux Git repository (nothing to be done, no error even if
872
+ # repository does not exist)
873
+ meth(tarball_path,
874
+ Repository(
875
+ storage_name=fixture.grpc_repo.storage_name,
876
+ relative_path=str(GIT_REPOS_STOWED_AWAY_PATH / 'some.git'),
877
+ ))
878
+
857
879
 
858
880
  @parametrize('rpc_name', ['backup', 'get'])
859
881
  def test_backup_custom_hooks(fixture_with_repo, tmpdir, rpc_name):
@@ -32,6 +32,7 @@ from .stub.shared_pb2 import (
32
32
 
33
33
  GARBAGE_COLLECTING_RATE_GEN2 = 250
34
34
  GARBAGE_COLLECTING_RATE_GEN1 = 20
35
+ AUX_GIT_REPOS_RELATIVE_DIR = "+hgitaly/hg-git"
35
36
  HG_GIT_MIRRORING_MD_KEY = 'x-heptapod-hg-git-mirroring'
36
37
  NATIVE_PROJECT_MD_KEY = 'x-heptapod-hg-native'
37
38
  # TODO check if there is a GitLab MD for this, it should:
@@ -129,6 +130,11 @@ class HGitalyServicer:
129
130
  # (typically ignoring some settings that can be critical to
130
131
  # operation)
131
132
 
133
+ def is_repo_aux_git(self, repository: Repository):
134
+ if repository is None:
135
+ return False
136
+ return repository.relative_path.startswith(AUX_GIT_REPOS_RELATIVE_DIR)
137
+
132
138
  def load_repo(self, repository: Repository, context,
133
139
  for_mutation_by=None,
134
140
  ):
@@ -288,7 +294,7 @@ class HGitalyServicer:
288
294
  # in request, without having the request object itself
289
295
  raise ValueError('repository not set')
290
296
 
291
- root_dir = self.storages.get(storage_name)
297
+ root_dir = self.storages.get(storage_name.rsplit(':', 1)[-1])
292
298
  if root_dir is None:
293
299
  raise KeyError('storage', storage_name)
294
300
  return root_dir
@@ -28,6 +28,7 @@ from ..testing.context import (
28
28
  FakeServicerContext,
29
29
  metadatum,
30
30
  )
31
+ from ..testing.storage import GIT_REPOS_STOWED_AWAY_PATH
31
32
  from ..servicer import (
32
33
  HG_GIT_MIRRORING_MD_KEY,
33
34
  NATIVE_PROJECT_MD_KEY,
@@ -107,6 +108,23 @@ def test_load_repo(tmpdir):
107
108
  assert context.code == grpc.StatusCode.NOT_FOUND
108
109
 
109
110
 
111
+ def test_is_repo_aux_git(tmpdir):
112
+ storage_root = tmpdir.join('repos')
113
+ storage_root_bytes = pycompat.sysbytes(str(storage_root))
114
+ servicer = HGitalyServicer(dict(storname=storage_root_bytes))
115
+
116
+ assert not servicer.is_repo_aux_git(None)
117
+ assert not servicer.is_repo_aux_git(
118
+ Repository(storage_name='storname',
119
+ relative_path='some/repo.git')
120
+ )
121
+ assert servicer.is_repo_aux_git(
122
+ Repository(
123
+ storage_name='storname',
124
+ relative_path=str(GIT_REPOS_STOWED_AWAY_PATH / 'repo.git'))
125
+ )
126
+
127
+
110
128
  def test_load_repo_for_mutation(tmpdir):
111
129
  storage_root = tmpdir.join('repos')
112
130
  storage_root_bytes = pycompat.sysbytes(str(storage_root))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hgitaly
3
- Version: 18.0.0a0
3
+ Version: 18.0.0a1
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
@@ -0,0 +1,300 @@
1
+ // Copyright 2025 Georges Racinet <georges.racinet@octobus.net>
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
+ // SPDX-License-Identifier: GPL-2.0-or-later
6
+
7
+ use std::ffi::OsString;
8
+ use std::fmt::{Debug, Formatter};
9
+ use std::path::PathBuf;
10
+ use std::sync::Arc;
11
+ use tokio::sync::mpsc;
12
+ use tokio_stream::wrappers::ReceiverStream;
13
+ use tokio_util::sync::CancellationToken;
14
+ use tonic::{metadata::MetadataMap, Response, Status};
15
+ use tracing::{debug, info, warn};
16
+
17
+ use crate::config::Config;
18
+ use crate::gitaly::{
19
+ CreateBundleRequest, CreateBundleResponse, CreateRepositoryFromBundleRequest,
20
+ FetchBundleRequest, Repository, User,
21
+ };
22
+ use crate::repository::spawner::{BytesChunking, RepoProcessSpawnerTemplate, RequestHgSpawnable};
23
+ use crate::repository::{
24
+ checked_git_repo_path_for_creation, checked_repo_path_for_creation,
25
+ default_repo_spec_error_status, RequestWithBytesChunk, RequestWithRepo,
26
+ };
27
+ use crate::streaming::{ResultResponseStream, WRITE_BUFFER_SIZE};
28
+
29
+ /// In this function, the Repository is assumed to be a Git repository,
30
+ /// sitting exacly at the given relative path (no switch to hg, no diversion to +hgitaly area)
31
+ pub async fn create_git_bundle(
32
+ config: Arc<Config>,
33
+ repo_path: PathBuf,
34
+ shutdown_token: CancellationToken,
35
+ metadata: &MetadataMap,
36
+ ) -> ResultResponseStream<CreateBundleResponse> {
37
+ let git_config = Vec::new();
38
+ let spawner_tmpl = RepoProcessSpawnerTemplate::new_git_at_path(
39
+ config.clone(),
40
+ repo_path,
41
+ metadata,
42
+ git_config,
43
+ )
44
+ .await?;
45
+ let mut spawner = spawner_tmpl.git_spawner();
46
+ // TODO evaluate needs for buffers? One can expect RHGitaly to read it fast
47
+ // unless all threads are busy.
48
+ let (stdout_tx, mut stdout_rx) = mpsc::channel(3);
49
+ spawner.capture_stdout(stdout_tx, BytesChunking::Binary(*WRITE_BUFFER_SIZE));
50
+ let args: Vec<OsString> = vec!["bundle".into(), "create".into(), "-".into(), "--all".into()];
51
+ spawner.args(&args);
52
+
53
+ let (tx, rx) = mpsc::channel(1);
54
+ let spawned = spawner.spawn(shutdown_token);
55
+ let tx2 = tx.clone();
56
+
57
+ let read_stdout = async move {
58
+ while let Some(data) = stdout_rx.recv().await {
59
+ debug!("Received {} bytes", data.len());
60
+ tx.send(Ok(CreateBundleResponse { data }))
61
+ .await
62
+ .unwrap_or_else(|e| {
63
+ warn!(
64
+ "Request cancelled by client before all results \
65
+ could be streamed back: {e}"
66
+ )
67
+ })
68
+ }
69
+ info!("Finished listening on internal channel for bundle data");
70
+ };
71
+
72
+ tokio::task::spawn(async move {
73
+ let spawn_result = tokio::join!(spawned, read_stdout).0;
74
+ let err = match spawn_result {
75
+ Ok(0) => return,
76
+ Ok(git_exit_code) => {
77
+ Status::internal(format!("Git subprocess exited with code {}", git_exit_code))
78
+ }
79
+ Err(e) => e,
80
+ };
81
+
82
+ if tx2.send(Err(err.clone())).await.is_err() {
83
+ warn!("Request cancelled by client before error {err:?} could be streamed back");
84
+ }
85
+ });
86
+
87
+ Ok(Response::new(Box::pin(ReceiverStream::new(rx))))
88
+ }
89
+
90
+ pub async fn create_repo_from_git_bundle(
91
+ config: Arc<Config>,
92
+ opt_repo: Option<&Repository>,
93
+ divert_aux_git_repo: bool,
94
+ bundle_path: PathBuf,
95
+ shutdown_token: CancellationToken,
96
+ metadata: &MetadataMap,
97
+ ) -> Result<(), Status> {
98
+ let (_gl_repo, repo_path) =
99
+ checked_git_repo_path_for_creation(&config, opt_repo, divert_aux_git_repo)
100
+ .await
101
+ .map_err(default_repo_spec_error_status)?;
102
+
103
+ let git_config = vec![
104
+ // See comment in FetchBundle
105
+ ("transfer.fsckObjects".into(), "false".into()),
106
+ ];
107
+
108
+ let cwd = config.repositories_root.clone();
109
+
110
+ let mut spawner =
111
+ RepoProcessSpawnerTemplate::new_git_at_path(config, cwd, metadata, git_config)
112
+ .await?
113
+ .git_spawner();
114
+
115
+ let args: Vec<OsString> = vec![
116
+ "clone".into(),
117
+ "--bare".into(),
118
+ "--quiet".into(),
119
+ bundle_path.into(),
120
+ repo_path.into(),
121
+ ];
122
+ spawner.args(&args);
123
+ info!("Git args: {:?}", &args);
124
+ let git_exit_code = spawner.spawn(shutdown_token).await?;
125
+ if git_exit_code != 0 {
126
+ warn!("Git subprocess exited with code {git_exit_code}");
127
+ return Err(Status::internal(format!(
128
+ "Git subprocess exited with code {git_exit_code}"
129
+ )));
130
+ }
131
+ Ok(())
132
+ }
133
+
134
+ pub async fn git_fetch_bundle<Req: RequestWithRepo>(
135
+ config: Arc<Config>,
136
+ req: Req,
137
+ bundle_path: PathBuf,
138
+ shutdown_token: CancellationToken,
139
+ metadata: &MetadataMap,
140
+ ) -> Result<(), Status> {
141
+ // call git fetch on the bundle, using the in-memory remote trick
142
+ let git_config = vec![
143
+ ("remote.inmemory.url".into(), bundle_path.into()),
144
+ // Comment from Gitaly 17.8:
145
+ //
146
+ // Starting in Git version 2.46.0, executing git-fetch(1) on a bundle
147
+ // performs fsck checks when `transfer.fsckObjects` is enabled.
148
+ // Prior to this, this configuration was always ignored and fsck checks
149
+ // were not run.
150
+ // Unfortunately, fsck message severity configuration is ignored by
151
+ // Git only for bundle fetches. Until this is supported by
152
+ // Git, disable `transfer.fsckObjects` so bundles containing fsck
153
+ // errors can continue to be fetched.
154
+ // This matches behavior prior to Git version 2.46.0.
155
+ ("transfer.fsckObjects".into(), "false".into()),
156
+ // Comment from Gitaly 17.8:
157
+ //
158
+ // Git is so kind to point out that we asked it to not show forced updates
159
+ // by default, so we need to ask it not to do that.
160
+ ("advice.fetchShowForcedUpdates".into(), "false".into()),
161
+ ];
162
+ let mut spawner = RepoProcessSpawnerTemplate::new_git(
163
+ config,
164
+ req,
165
+ metadata,
166
+ git_config,
167
+ default_repo_spec_error_status,
168
+ )
169
+ .await?
170
+ .git_spawner();
171
+ // TODO support `update_head`.
172
+ //
173
+ // Gitaly uses the `MirroRefSpec`: "+refs/*:refs/*", but it look like
174
+ // our simpler refspec below always includes HEAD (and any other symref, to be
175
+ // fair, so they have to update HEAD separately, and it is a pain to
176
+ // find in the bundle etc.
177
+ // For the current purposes (backup/restore of auxiliary Git repositories),
178
+ // we do not care, but otherwise playing
179
+ // with a negative refspec for HEAD when we do not want to update it would
180
+ // probably be the way to go.
181
+ let args: Vec<OsString> = vec![
182
+ "fetch".into(),
183
+ "--quiet".into(),
184
+ "--atomic".into(),
185
+ "--force".into(),
186
+ "inmemory".into(), // name of Git remote
187
+ "+*:*".into(), // refspec to update all refs from the remote (the bundle)
188
+ ];
189
+ spawner.args(&args);
190
+
191
+ let git_exit_code = spawner.spawn(shutdown_token).await?;
192
+ if git_exit_code != 0 {
193
+ warn!("Git subprocess exited with code {git_exit_code}");
194
+ return Err(Status::internal(format!(
195
+ "Git subprocess exited with code {git_exit_code}"
196
+ )));
197
+ }
198
+ Ok(())
199
+ }
200
+
201
+ pub async fn create_repo_from_hg_bundle(
202
+ config: Arc<Config>,
203
+ opt_repo: Option<&Repository>,
204
+ bundle_path: PathBuf,
205
+ shutdown_token: CancellationToken,
206
+ metadata: &MetadataMap,
207
+ ) -> Result<(), Status> {
208
+ let (gl_repo, repo_path) = checked_repo_path_for_creation(&config, opt_repo)
209
+ .await
210
+ .map_err(default_repo_spec_error_status)?;
211
+
212
+ let cwd = config.repositories_root.clone();
213
+ let mut spawner =
214
+ RepoProcessSpawnerTemplate::new_hg_at_path(config, cwd, gl_repo, None, metadata)
215
+ .await?
216
+ .hg_spawner();
217
+
218
+ let args: Vec<OsString> = vec!["clone".into(), bundle_path.into(), repo_path.into()];
219
+ spawner.args(&args);
220
+ info!("Mercurial args: {:?}", &args);
221
+ let hg_exit_code = spawner.spawn(shutdown_token).await?;
222
+ if hg_exit_code != 0 {
223
+ let msg = format!("Mercurial subprocess exited with code {hg_exit_code}");
224
+ warn!(msg);
225
+ return Err(Status::internal(msg));
226
+ }
227
+ Ok(())
228
+ }
229
+
230
+ pub async fn hg_unbundle<Req: RequestHgSpawnable>(
231
+ config: Arc<Config>,
232
+ req: Req,
233
+ bundle_path: PathBuf,
234
+ shutdown_token: CancellationToken,
235
+ metadata: &MetadataMap,
236
+ ) -> Result<(), Status> {
237
+ let mut spawner =
238
+ RepoProcessSpawnerTemplate::new_hg(config, req, metadata, default_repo_spec_error_status)
239
+ .await?
240
+ .hg_spawner();
241
+
242
+ let args: Vec<OsString> = vec!["unbundle".into(), bundle_path.into()];
243
+ spawner.args(&args);
244
+ info!("Mercurial args: {:?}", &args);
245
+ let hg_exit_code = spawner.spawn(shutdown_token).await?;
246
+ if hg_exit_code != 0 {
247
+ let msg = format!("Mercurial subprocess exited with code {hg_exit_code}");
248
+ warn!(msg);
249
+ return Err(Status::internal(msg));
250
+ }
251
+ Ok(())
252
+ }
253
+
254
+ pub struct CreateBundleTracingRequest<'a>(pub &'a CreateBundleRequest);
255
+
256
+ impl Debug for CreateBundleTracingRequest<'_> {
257
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
258
+ f.debug_struct("CreateBundle")
259
+ .field("repository", &self.0.repository)
260
+ .finish()
261
+ }
262
+ }
263
+
264
+ impl RequestWithRepo for CreateBundleRequest {
265
+ fn repository_ref(&self) -> Option<&Repository> {
266
+ self.repository.as_ref()
267
+ }
268
+ }
269
+
270
+ pub struct CreateRepositoryFromBundleTracingRequest<'a>(pub &'a CreateRepositoryFromBundleRequest);
271
+
272
+ impl Debug for CreateRepositoryFromBundleTracingRequest<'_> {
273
+ fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
274
+ f.debug_struct("CreateRepositoryFromBundle")
275
+ .field("repository", &self.0.repository)
276
+ .finish()
277
+ }
278
+ }
279
+
280
+ impl RequestWithRepo for CreateRepositoryFromBundleRequest {
281
+ fn repository_ref(&self) -> Option<&Repository> {
282
+ self.repository.as_ref()
283
+ }
284
+ }
285
+
286
+ impl RequestWithBytesChunk for CreateRepositoryFromBundleRequest {
287
+ fn bytes_chunk(&self) -> &[u8] {
288
+ &self.data
289
+ }
290
+ }
291
+ impl RequestWithRepo for FetchBundleRequest {
292
+ fn repository_ref(&self) -> Option<&Repository> {
293
+ self.repository.as_ref()
294
+ }
295
+ }
296
+ impl RequestHgSpawnable for FetchBundleRequest {
297
+ fn user_ref(&self) -> Option<&User> {
298
+ None
299
+ }
300
+ }
@@ -28,7 +28,7 @@ use super::{
28
28
  checked_git_repo_path, checked_repo_path, load_repo_at_and_then, RepoSpecError, RequestWithRepo,
29
29
  };
30
30
  use crate::config::Config;
31
- use crate::gitaly::User;
31
+ use crate::gitaly::{Repository, User};
32
32
  use crate::metadata::{
33
33
  get_boolean_md_value, ACCEPT_MR_IID_KEY, HG_GIT_MIRRORING_MD_KEY, NATIVE_PROJECT_MD_KEY,
34
34
  SKIP_HOOKS_MD_KEY,
@@ -110,6 +110,16 @@ impl RepoProcessSpawnerTemplate {
110
110
  let (gitaly_repo, repo_path) = checked_repo_path(&config, request.repository_ref())
111
111
  .await
112
112
  .map_err(repo_spec_error_status)?;
113
+ Self::new_hg_at_path(config, repo_path, gitaly_repo, request.user_ref(), metadata).await
114
+ }
115
+
116
+ pub async fn new_hg_at_path(
117
+ config: Arc<Config>,
118
+ cwd: PathBuf,
119
+ gitaly_repo: &Repository,
120
+ opt_user: Option<&User>,
121
+ metadata: &MetadataMap,
122
+ ) -> Result<Self, Status> {
113
123
  let mut common_args = Vec::new();
114
124
  let mut common_env: Vec<(OsString, OsString)> = vec![
115
125
  (
@@ -134,7 +144,7 @@ impl RepoProcessSpawnerTemplate {
134
144
  common_env.push(("'HEPTAPOD_SKIP_ALL_GITLAB_HOOKS'".into(), "yes".into()));
135
145
  }
136
146
 
137
- if let Some(user) = request.user_ref() {
147
+ if let Some(user) = opt_user {
138
148
  common_env.push(("HEPTAPOD_USERINFO_GL_ID".into(), user.gl_id.clone().into()));
139
149
  common_env.push((
140
150
  "HEPTAPOD_USERINFO_USERNAME".into(),
@@ -160,7 +170,7 @@ impl RepoProcessSpawnerTemplate {
160
170
  common_args,
161
171
  common_env,
162
172
  config,
163
- repo_path,
173
+ repo_path: cwd,
164
174
  })
165
175
  }
166
176
 
@@ -42,6 +42,7 @@ pub enum RepoSpecError {
42
42
  MissingSpecification,
43
43
  UnknownStorage(String),
44
44
  RepoNotFound(PathBuf),
45
+ AlreadyExists(PathBuf),
45
46
  }
46
47
 
47
48
  /// Represent errors loading a repository (bad specification or internal errors)
@@ -78,6 +79,9 @@ pub fn default_repo_spec_error_status(err: RepoSpecError) -> Status {
78
79
  RepoSpecError::RepoNotFound(at) => {
79
80
  Status::not_found(format!("repository at \"{}\" not found", at.display()))
80
81
  }
82
+ RepoSpecError::AlreadyExists(_) => {
83
+ Status::already_exists("creating repository: repository exists already")
84
+ }
81
85
  }
82
86
  }
83
87
 
@@ -102,8 +106,18 @@ pub fn aux_git_to_main_hg<Req: RequestWithRepo>(req: &Req) -> Option<&str> {
102
106
  }
103
107
  }
104
108
 
109
+ fn check_storage(repo: &Repository) -> Result<(), RepoSpecError> {
110
+ if repo.storage_name.rsplit(':').next() == Some("default") {
111
+ Ok(())
112
+ } else {
113
+ Err(RepoSpecError::UnknownStorage(repo.storage_name.clone()))
114
+ }
115
+ }
116
+
105
117
  pub fn repo_path(config: &Config, repo: &Repository) -> Result<PathBuf, RepoSpecError> {
106
- if repo.storage_name != "default" {
118
+ check_storage(repo)?;
119
+
120
+ if repo.storage_name.rsplit(':').next() != Some("default") {
107
121
  return Err(RepoSpecError::UnknownStorage(repo.storage_name.clone()));
108
122
  }
109
123
  let root = &config.repositories_root;
@@ -123,9 +137,8 @@ pub fn git_repo_path(
123
137
  repo: &Repository,
124
138
  divert_aux_area: bool,
125
139
  ) -> Result<PathBuf, RepoSpecError> {
126
- if repo.storage_name != "default" {
127
- return Err(RepoSpecError::UnknownStorage(repo.storage_name.clone()));
128
- }
140
+ check_storage(repo)?;
141
+
129
142
  let mut path = if divert_aux_area {
130
143
  config.repositories_root.join(AUX_GIT_REPOS_RELATIVE_DIR)
131
144
  } else {
@@ -196,6 +209,21 @@ pub async fn checked_repo_path<'a>(
196
209
  Err(RepoSpecError::RepoNotFound(path))
197
210
  }
198
211
 
212
+ /// Checks that repo is specified, and that there is nothing at its path
213
+ pub async fn checked_repo_path_for_creation<'a>(
214
+ config: &Config,
215
+ gl_repo: Option<&'a Repository>,
216
+ ) -> Result<(&'a Repository, PathBuf), RepoSpecError> {
217
+ let repo = gl_repo
218
+ .as_ref()
219
+ .ok_or(RepoSpecError::MissingSpecification)?;
220
+ let path = repo_path(config, repo)?;
221
+ if fs::metadata(&path).await.is_ok() {
222
+ return Err(RepoSpecError::AlreadyExists(path));
223
+ }
224
+ Ok((repo, path))
225
+ }
226
+
199
227
  pub async fn checked_git_repo_path<'a>(
200
228
  config: &Config,
201
229
  gl_repo: Option<&'a Repository>,
@@ -214,6 +242,21 @@ pub async fn checked_git_repo_path<'a>(
214
242
  Err(RepoSpecError::RepoNotFound(path))
215
243
  }
216
244
 
245
+ pub async fn checked_git_repo_path_for_creation<'a>(
246
+ config: &Config,
247
+ gl_repo: Option<&'a Repository>,
248
+ divert_aux_area: bool,
249
+ ) -> Result<(&'a Repository, PathBuf), RepoSpecError> {
250
+ let repo = gl_repo
251
+ .as_ref()
252
+ .ok_or(RepoSpecError::MissingSpecification)?;
253
+ let path = git_repo_path(config, repo, divert_aux_area)?;
254
+ if fs::metadata(&path).await.is_ok() {
255
+ return Err(RepoSpecError::AlreadyExists(path));
256
+ }
257
+ Ok((repo, path))
258
+ }
259
+
217
260
  /// Return a path to virtual filesystem for the repository store.
218
261
  ///
219
262
  /// As of this writing, this is nothing but a [`Path`], but it could become something
@@ -30,7 +30,7 @@ use crate::hgitaly::mercurial_aux_git_service_server::{
30
30
  use crate::metadata::correlation_id;
31
31
  use crate::repository::{
32
32
  blocking_join_error_status, checked_git_repo_path, default_repo_spec_error_status,
33
- git_repo_path, RepoSpecError, RequestWithRepo,
33
+ RequestWithRepo,
34
34
  };
35
35
  use crate::streaming::{with_streaming_request_data_as_file, ResultResponseStream};
36
36
  use crate::util::tracing_span_id;
@@ -122,16 +122,10 @@ impl MercurialAuxGitServiceImpl {
122
122
  First request chunk={:?}",
123
123
  CreateRepositoryFromBundleTracingRequest(&first_req)
124
124
  );
125
- let gl_repo = first_req
126
- .repository_ref()
127
- .ok_or(RepoSpecError::MissingSpecification)
128
- .map_err(default_repo_spec_error_status)?;
129
-
130
- let repo_path = git_repo_path(&config, gl_repo, true)
131
- .map_err(default_repo_spec_error_status)?;
132
125
  create_repo_from_git_bundle(
133
126
  config,
134
- repo_path,
127
+ first_req.repository_ref(),
128
+ true,
135
129
  bundle_path,
136
130
  shutdown_token,
137
131
  metadata,