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.
Files changed (171) hide show
  1. {hgitaly-18.3.0a1/hgitaly.egg-info → hgitaly-18.3.2}/PKG-INFO +1 -1
  2. hgitaly-18.3.2/hgitaly/VERSION +1 -0
  3. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/diff.py +36 -1
  4. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/errors.py +3 -2
  5. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_mono.py +5 -1
  6. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/commit.py +5 -0
  7. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/diff.py +2 -1
  8. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/operations.py +8 -3
  9. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_commit.py +2 -0
  10. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_diff.py +82 -31
  11. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_operations.py +47 -0
  12. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/bundle.py +10 -1
  13. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/grpc.py +22 -0
  14. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_errors.py +4 -1
  15. {hgitaly-18.3.0a1 → hgitaly-18.3.2/hgitaly.egg-info}/PKG-INFO +1 -1
  16. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/SOURCES.txt +0 -1
  17. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/comparison.py +13 -6
  18. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/rhgitaly.py +9 -0
  19. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_commit.py +7 -0
  20. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_diff.py +24 -8
  21. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_repository_service.py +2 -0
  22. hgitaly-18.3.0a1/hgitaly/VERSION +0 -1
  23. hgitaly-18.3.0a1/hgitaly/linguist/languages.json +0 -1
  24. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/LICENSE +0 -0
  25. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/MANIFEST.in +0 -0
  26. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/README.md +0 -0
  27. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/__init__.py +0 -0
  28. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/__init__.py +0 -0
  29. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/revset.py +0 -0
  30. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/tests/__init__.py +0 -0
  31. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/tests/test_revset.py +0 -0
  32. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgext3rd/hgitaly/tests/test_serve.py +0 -0
  33. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/__init__.py +0 -0
  34. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/branch.py +0 -0
  35. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/changelog.py +0 -0
  36. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/feature.py +0 -0
  37. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/file_content.py +0 -0
  38. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/file_context.py +0 -0
  39. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/git.py +0 -0
  40. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/gitlab_ref.py +0 -0
  41. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/identification.py +0 -0
  42. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/logging.py +0 -0
  43. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/manifest.py +0 -0
  44. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/message.py +0 -0
  45. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/oid.py +0 -0
  46. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/pagination.py +0 -0
  47. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/path.py +0 -0
  48. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/peer.py +0 -0
  49. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/procutil.py +0 -0
  50. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/repository.py +0 -0
  51. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/revision.py +0 -0
  52. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/revset.py +0 -0
  53. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/scripts.py +0 -0
  54. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/__init__.py +0 -0
  55. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/address.py +0 -0
  56. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/mono.py +0 -0
  57. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/prefork.py +0 -0
  58. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/__init__.py +0 -0
  59. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_address.py +0 -0
  60. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_prefork.py +0 -0
  61. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/tests/test_worker.py +0 -0
  62. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/server/worker.py +0 -0
  63. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/__init__.py +0 -0
  64. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/analysis.py +0 -0
  65. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/blob.py +0 -0
  66. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/interceptors.py +0 -0
  67. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/mercurial_changeset.py +0 -0
  68. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/mercurial_operations.py +0 -0
  69. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/mercurial_repository.py +0 -0
  70. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/ref.py +0 -0
  71. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/repository.py +0 -0
  72. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/server.py +0 -0
  73. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/__init__.py +0 -0
  74. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/fixture.py +0 -0
  75. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_analysis.py +0 -0
  76. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_blob.py +0 -0
  77. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_default_branch.py +0 -0
  78. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_mercurial_changeset.py +0 -0
  79. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_mercurial_operations.py +0 -0
  80. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_mercurial_repository.py +0 -0
  81. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_ref.py +0 -0
  82. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_repository_service.py +0 -0
  83. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/service/tests/test_server.py +0 -0
  84. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/servicer.py +0 -0
  85. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/ssh.py +0 -0
  86. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stream.py +0 -0
  87. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/__init__.py +0 -0
  88. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/analysis_pb2.py +0 -0
  89. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/analysis_pb2_grpc.py +0 -0
  90. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/blob_pb2.py +0 -0
  91. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/blob_pb2_grpc.py +0 -0
  92. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/commit_pb2.py +0 -0
  93. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/commit_pb2_grpc.py +0 -0
  94. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/diff_pb2.py +0 -0
  95. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/diff_pb2_grpc.py +0 -0
  96. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/errors_pb2.py +0 -0
  97. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/errors_pb2_grpc.py +0 -0
  98. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/lint_pb2.py +0 -0
  99. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/lint_pb2_grpc.py +0 -0
  100. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_aux_git_pb2.py +0 -0
  101. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_aux_git_pb2_grpc.py +0 -0
  102. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_changeset_pb2.py +0 -0
  103. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_changeset_pb2_grpc.py +0 -0
  104. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_operations_pb2.py +0 -0
  105. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_operations_pb2_grpc.py +0 -0
  106. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_repository_pb2.py +0 -0
  107. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/mercurial_repository_pb2_grpc.py +0 -0
  108. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/operations_pb2.py +0 -0
  109. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/operations_pb2_grpc.py +0 -0
  110. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/ref_pb2.py +0 -0
  111. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/ref_pb2_grpc.py +0 -0
  112. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/remote_pb2.py +0 -0
  113. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/remote_pb2_grpc.py +0 -0
  114. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/repository_pb2.py +0 -0
  115. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/repository_pb2_grpc.py +0 -0
  116. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/server_pb2.py +0 -0
  117. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/server_pb2_grpc.py +0 -0
  118. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/shared_pb2.py +0 -0
  119. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/stub/shared_pb2_grpc.py +0 -0
  120. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tag.py +0 -0
  121. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/__init__.py +0 -0
  122. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/context.py +0 -0
  123. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/multiprocessing.py +0 -0
  124. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/ssh.py +0 -0
  125. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/sshd.py +0 -0
  126. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/storage.py +0 -0
  127. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/tests/__init__.py +0 -0
  128. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/testing/tests/test_sshd.py +0 -0
  129. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/__init__.py +0 -0
  130. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/common.py +0 -0
  131. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_branch.py +0 -0
  132. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_diff.py +0 -0
  133. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_feature.py +0 -0
  134. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_file_context.py +0 -0
  135. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_gitlab_ref.py +0 -0
  136. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_identification.py +0 -0
  137. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_manifest.py +0 -0
  138. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_messages.py +0 -0
  139. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_oid.py +0 -0
  140. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_peer.py +0 -0
  141. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_repository.py +0 -0
  142. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_revision.py +0 -0
  143. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_revset.py +0 -0
  144. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_servicer.py +0 -0
  145. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_stream.py +0 -0
  146. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_tag.py +0 -0
  147. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/tests/test_workdir.py +0 -0
  148. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/util.py +0 -0
  149. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly/workdir.py +0 -0
  150. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/dependency_links.txt +0 -0
  151. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/entry_points.txt +0 -0
  152. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/requires.txt +0 -0
  153. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/hgitaly.egg-info/top_level.txt +0 -0
  154. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/install-requirements.txt +0 -0
  155. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/setup.cfg +0 -0
  156. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/setup.py +0 -0
  157. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/__init__.py +0 -0
  158. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/conftest.py +0 -0
  159. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/gitaly.py +0 -0
  160. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +0 -0
  161. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_blob_tree.py +0 -0
  162. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_comparison.py +0 -0
  163. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_gitaly_server.py +0 -0
  164. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_mercurial_aux_git.py +0 -0
  165. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_mercurial_operations.py +0 -0
  166. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_mercurial_repository.py +0 -0
  167. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_operations.py +0 -0
  168. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_ref.py +0 -0
  169. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_remote.py +0 -0
  170. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_rhgitaly_server.py +0 -0
  171. {hgitaly-18.3.0a1 → hgitaly-18.3.2}/tests_with_gitaly/test_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hgitaly
3
- Version: 18.3.0a1
3
+ Version: 18.3.2
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.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
- def changed_paths(repo, from_ctx, to_ctx, base_path, find_renames=False):
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
- # should not normally happen, but let's make sure it is not
107
- # a problem
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 wait_server_accepts_connection
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 and start_ctx.hex() != old_oid:
365
- context.abort(StatusCode.INVALID_ARGUMENT,
366
- "wrong old oid")
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(b'mv', wrapper.repo.root + b'/foo',
180
+ wrapper.command('mv', wrapper.repo.root + b'/foo',
174
181
  wrapper.repo.root + b'/zoo')
175
- wrapper.command(b'ci', message=b"rename foo to zoo")
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(b'mv', wrapper.repo.root + b'/bar',
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(b'mv', wrapper.repo.root + b'/bar',
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(b'mv', wrapper.repo.root + b'/bar',
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(b'cp', wrapper.repo.root + b'/zoo',
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(b'cp', wrapper.repo.root + b'/subdir/bar',
678
- wrapper.repo.root + b'/subdir/baz')
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(b'mv', wrapper.repo.root + b'/subdir/bar',
698
- wrapper.repo.root + b'/subdir/baz')
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
- repo = wrapper.repo
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
- sub0_oid, sub1_oid = [tree_oid(repo, ctx.hex().decode('ascii'), b'subdir')
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
- ret = diff_fixture.find_changed_paths_commits(
722
- [ctx1.hex()],
723
- compare_to=[ctx0.hex()],
724
- find_renames=True,
725
- )
726
- assert ret == {
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
- # TODO test the case of rename with duplication:
731
- # hg cp foo bar; hg mv foo bar2
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[0]) for delta in cg.deltaiter())
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
- raise GitLabPreReceiveError("again protected")
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()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: hgitaly
3
- Version: 18.3.0a1
3
+ Version: 18.3.2
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
@@ -45,7 +45,6 @@ hgitaly.egg-info/dependency_links.txt
45
45
  hgitaly.egg-info/entry_points.txt
46
46
  hgitaly.egg-info/requires.txt
47
47
  hgitaly.egg-info/top_level.txt
48
- hgitaly/linguist/languages.json
49
48
  hgitaly/server/__init__.py
50
49
  hgitaly/server/address.py
51
50
  hgitaly/server/mono.py
@@ -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 init_stubs(self):
493
- comparison, stub_cls = self.comparison, self.stub_cls
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
- hg_channel = comparison.rhgitaly_channel
498
+ return self.comparison.rhgitaly_channel
497
499
  else:
498
- hg_channel = comparison.hgitaly_channel
499
- self.stubs = dict(git=stub_cls(comparison.gitaly_channel),
500
- hg=stub_cls(hg_channel))
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']