hgitaly 18.4.0a0__tar.gz → 18.5.0.dev0__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 (309) hide show
  1. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/PKG-INFO +4 -4
  2. hgitaly-18.5.0.dev0/hgitaly/VERSION +1 -0
  3. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/message.py +5 -0
  4. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/mercurial_operations.py +156 -7
  5. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/operations.py +2 -2
  6. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/fixture.py +23 -2
  7. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_mercurial_operations.py +132 -0
  8. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_repository_service.py +2 -3
  9. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/servicer.py +3 -1
  10. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_aux_git_pb2.py +12 -3
  11. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_aux_git_pb2_grpc.py +45 -0
  12. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_operations_pb2.py +29 -19
  13. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_operations_pb2_grpc.py +45 -1
  14. hgitaly-18.5.0.dev0/hgitaly/testing/repo.py +26 -0
  15. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/storage.py +17 -1
  16. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/common.py +1 -0
  17. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly.egg-info/PKG-INFO +4 -4
  18. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly.egg-info/SOURCES.txt +1 -138
  19. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly.egg-info/requires.txt +3 -3
  20. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/install-requirements.txt +3 -3
  21. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_mercurial_aux_git.py +45 -3
  22. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_repository_service.py +11 -4
  23. hgitaly-18.4.0a0/.coveragerc +0 -5
  24. hgitaly-18.4.0a0/.gitlab-ci.yml +0 -154
  25. hgitaly-18.4.0a0/.hgignore +0 -36
  26. hgitaly-18.4.0a0/.hgtags +0 -168
  27. hgitaly-18.4.0a0/ci/heptapod-sftp-push +0 -31
  28. hgitaly-18.4.0a0/ci/heptapod-sign-package +0 -34
  29. hgitaly-18.4.0a0/ci/heptapod_known_hosts.ssh +0 -4
  30. hgitaly-18.4.0a0/ci/upload-rhgitaly +0 -43
  31. hgitaly-18.4.0a0/conftest.py +0 -100
  32. hgitaly-18.4.0a0/dev-requirements.txt +0 -2
  33. hgitaly-18.4.0a0/examples/client.py +0 -48
  34. hgitaly-18.4.0a0/examples/client_list_lcft.py +0 -55
  35. hgitaly-18.4.0a0/generate-stubs +0 -34
  36. hgitaly-18.4.0a0/hgitaly/VERSION +0 -1
  37. hgitaly-18.4.0a0/hgitaly/testing/data/authorized_keys +0 -1
  38. hgitaly-18.4.0a0/hgitaly/testing/data/backup_additional_no_git.tar +0 -0
  39. hgitaly-18.4.0a0/hgitaly/testing/data/id_ecdsa_user +0 -38
  40. hgitaly-18.4.0a0/hgitaly/testing/data/known_hosts +0 -2
  41. hgitaly-18.4.0a0/hgitaly/testing/data/ssh_host_ecdsa_key +0 -9
  42. hgitaly-18.4.0a0/hgitaly/testing/data/ssh_host_ecdsa_key.pub +0 -1
  43. hgitaly-18.4.0a0/hgitaly/testing/data/ssh_host_ed25519 +0 -8
  44. hgitaly-18.4.0a0/hgitaly/testing/data/ssh_host_ed25519.pub +0 -1
  45. hgitaly-18.4.0a0/hgitaly/testing/data/sshd_config +0 -17
  46. hgitaly-18.4.0a0/lint +0 -7
  47. hgitaly-18.4.0a0/protos/analysis.proto +0 -62
  48. hgitaly-18.4.0a0/protos/blob.proto +0 -299
  49. hgitaly-18.4.0a0/protos/cleanup.proto +0 -88
  50. hgitaly-18.4.0a0/protos/cluster.proto +0 -134
  51. hgitaly-18.4.0a0/protos/commit.proto +0 -996
  52. hgitaly-18.4.0a0/protos/conflicts.proto +0 -137
  53. hgitaly-18.4.0a0/protos/diff.proto +0 -644
  54. hgitaly-18.4.0a0/protos/errors.proto +0 -234
  55. hgitaly-18.4.0a0/protos/hook.proto +0 -205
  56. hgitaly-18.4.0a0/protos/internal.proto +0 -37
  57. hgitaly-18.4.0a0/protos/lint.proto +0 -75
  58. hgitaly-18.4.0a0/protos/log.proto +0 -137
  59. hgitaly-18.4.0a0/protos/mercurial-aux-git.proto +0 -32
  60. hgitaly-18.4.0a0/protos/mercurial-changeset.proto +0 -96
  61. hgitaly-18.4.0a0/protos/mercurial-operations.proto +0 -230
  62. hgitaly-18.4.0a0/protos/mercurial-repository.proto +0 -364
  63. hgitaly-18.4.0a0/protos/namespace.proto +0 -98
  64. hgitaly-18.4.0a0/protos/objectpool.proto +0 -173
  65. hgitaly-18.4.0a0/protos/operations.proto +0 -1161
  66. hgitaly-18.4.0a0/protos/packfile.proto +0 -26
  67. hgitaly-18.4.0a0/protos/partition.proto +0 -70
  68. hgitaly-18.4.0a0/protos/praefect.proto +0 -222
  69. hgitaly-18.4.0a0/protos/ref.proto +0 -600
  70. hgitaly-18.4.0a0/protos/remote.proto +0 -153
  71. hgitaly-18.4.0a0/protos/repository.proto +0 -1458
  72. hgitaly-18.4.0a0/protos/server.proto +0 -123
  73. hgitaly-18.4.0a0/protos/service_config.proto +0 -86
  74. hgitaly-18.4.0a0/protos/shared.proto +0 -248
  75. hgitaly-18.4.0a0/protos/smarthttp.proto +0 -121
  76. hgitaly-18.4.0a0/protos/ssh.proto +0 -109
  77. hgitaly-18.4.0a0/protos/transaction.proto +0 -104
  78. hgitaly-18.4.0a0/protos/wiki.proto +0 -211
  79. hgitaly-18.4.0a0/ruby/.ruby-version +0 -1
  80. hgitaly-18.4.0a0/ruby/Gemfile +0 -5
  81. hgitaly-18.4.0a0/ruby/README.md +0 -48
  82. hgitaly-18.4.0a0/ruby/generate-grpc-lib +0 -63
  83. hgitaly-18.4.0a0/ruby/hgitaly.gemspec +0 -25
  84. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-aux-git_pb.rb +0 -14
  85. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-aux-git_services_pb.rb +0 -29
  86. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-changeset_pb.rb +0 -69
  87. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-changeset_services_pb.rb +0 -25
  88. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-operations_pb.rb +0 -133
  89. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-operations_services_pb.rb +0 -53
  90. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-repository_pb.rb +0 -163
  91. hgitaly-18.4.0a0/ruby/lib/hgitaly/mercurial-repository_services_pb.rb +0 -79
  92. hgitaly-18.4.0a0/ruby/lib/hgitaly/version.rb +0 -4
  93. hgitaly-18.4.0a0/ruby/lib/hgitaly.rb +0 -13
  94. hgitaly-18.4.0a0/ruby/run.rb +0 -39
  95. hgitaly-18.4.0a0/run-all-tests +0 -24
  96. hgitaly-18.4.0a0/rust/Cargo.lock +0 -3898
  97. hgitaly-18.4.0a0/rust/Cargo.toml +0 -4
  98. hgitaly-18.4.0a0/rust/Makefile +0 -77
  99. hgitaly-18.4.0a0/rust/build-from-tarball.sh +0 -30
  100. hgitaly-18.4.0a0/rust/check-line-width +0 -48
  101. hgitaly-18.4.0a0/rust/dependencies/README.md +0 -19
  102. hgitaly-18.4.0a0/rust/dependencies/mercurial.patch +0 -51
  103. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/any.proto +0 -158
  104. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/api.proto +0 -208
  105. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/compiler/plugin.proto +0 -183
  106. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/descriptor.proto +0 -911
  107. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/duration.proto +0 -116
  108. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/empty.proto +0 -52
  109. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/field_mask.proto +0 -245
  110. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/source_context.proto +0 -48
  111. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/struct.proto +0 -95
  112. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/timestamp.proto +0 -147
  113. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/type.proto +0 -187
  114. hgitaly-18.4.0a0/rust/dependencies/proto/google/protobuf/wrappers.proto +0 -123
  115. hgitaly-18.4.0a0/rust/go-enry.rev +0 -1
  116. hgitaly-18.4.0a0/rust/lint +0 -14
  117. hgitaly-18.4.0a0/rust/mercurial.rev +0 -1
  118. hgitaly-18.4.0a0/rust/rhgitaly/Cargo.toml +0 -56
  119. hgitaly-18.4.0a0/rust/rhgitaly/build.rs +0 -92
  120. hgitaly-18.4.0a0/rust/rhgitaly/clippy.toml +0 -6
  121. hgitaly-18.4.0a0/rust/rhgitaly/src/bundle.rs +0 -282
  122. hgitaly-18.4.0a0/rust/rhgitaly/src/config.rs +0 -172
  123. hgitaly-18.4.0a0/rust/rhgitaly/src/errors.rs +0 -141
  124. hgitaly-18.4.0a0/rust/rhgitaly/src/generated/README.md +0 -7
  125. hgitaly-18.4.0a0/rust/rhgitaly/src/git.rs +0 -293
  126. hgitaly-18.4.0a0/rust/rhgitaly/src/gitlab/mod.rs +0 -50
  127. hgitaly-18.4.0a0/rust/rhgitaly/src/gitlab/reference.rs +0 -83
  128. hgitaly-18.4.0a0/rust/rhgitaly/src/gitlab/revision.rs +0 -320
  129. hgitaly-18.4.0a0/rust/rhgitaly/src/gitlab/state.rs +0 -508
  130. hgitaly-18.4.0a0/rust/rhgitaly/src/glob.rs +0 -233
  131. hgitaly-18.4.0a0/rust/rhgitaly/src/lib.rs +0 -45
  132. hgitaly-18.4.0a0/rust/rhgitaly/src/main.rs +0 -147
  133. hgitaly-18.4.0a0/rust/rhgitaly/src/mercurial.rs +0 -1389
  134. hgitaly-18.4.0a0/rust/rhgitaly/src/message.rs +0 -468
  135. hgitaly-18.4.0a0/rust/rhgitaly/src/metadata.rs +0 -61
  136. hgitaly-18.4.0a0/rust/rhgitaly/src/oid.rs +0 -86
  137. hgitaly-18.4.0a0/rust/rhgitaly/src/process.rs +0 -39
  138. hgitaly-18.4.0a0/rust/rhgitaly/src/repository/spawner.rs +0 -576
  139. hgitaly-18.4.0a0/rust/rhgitaly/src/repository.rs +0 -605
  140. hgitaly-18.4.0a0/rust/rhgitaly/src/service/analysis.rs +0 -183
  141. hgitaly-18.4.0a0/rust/rhgitaly/src/service/blob.rs +0 -260
  142. hgitaly-18.4.0a0/rust/rhgitaly/src/service/commit/find_commits.rs +0 -206
  143. hgitaly-18.4.0a0/rust/rhgitaly/src/service/commit/get_tree_entries.rs +0 -291
  144. hgitaly-18.4.0a0/rust/rhgitaly/src/service/commit/last_commits.rs +0 -569
  145. hgitaly-18.4.0a0/rust/rhgitaly/src/service/commit/tree_entry.rs +0 -154
  146. hgitaly-18.4.0a0/rust/rhgitaly/src/service/commit.rs +0 -654
  147. hgitaly-18.4.0a0/rust/rhgitaly/src/service/diff.rs +0 -137
  148. hgitaly-18.4.0a0/rust/rhgitaly/src/service/mercurial_aux_git.rs +0 -180
  149. hgitaly-18.4.0a0/rust/rhgitaly/src/service/mercurial_repository.rs +0 -496
  150. hgitaly-18.4.0a0/rust/rhgitaly/src/service/mod.rs +0 -19
  151. hgitaly-18.4.0a0/rust/rhgitaly/src/service/ref.rs +0 -515
  152. hgitaly-18.4.0a0/rust/rhgitaly/src/service/remote.rs +0 -793
  153. hgitaly-18.4.0a0/rust/rhgitaly/src/service/repository.rs +0 -983
  154. hgitaly-18.4.0a0/rust/rhgitaly/src/service/server.rs +0 -60
  155. hgitaly-18.4.0a0/rust/rhgitaly/src/sidecar.rs +0 -234
  156. hgitaly-18.4.0a0/rust/rhgitaly/src/ssh.rs +0 -102
  157. hgitaly-18.4.0a0/rust/rhgitaly/src/streaming.rs +0 -402
  158. hgitaly-18.4.0a0/rust/rhgitaly/src/util.rs +0 -132
  159. hgitaly-18.4.0a0/rust/rs-enry.rev +0 -1
  160. hgitaly-18.4.0a0/rust/src-tarball.sh +0 -70
  161. hgitaly-18.4.0a0/test-requirements.txt +0 -8
  162. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/LICENSE +0 -0
  163. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/MANIFEST.in +0 -0
  164. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/README.md +0 -0
  165. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgext3rd/__init__.py +0 -0
  166. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgext3rd/hgitaly/__init__.py +0 -0
  167. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgext3rd/hgitaly/revset.py +0 -0
  168. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgext3rd/hgitaly/tests/__init__.py +0 -0
  169. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgext3rd/hgitaly/tests/test_revset.py +0 -0
  170. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgext3rd/hgitaly/tests/test_serve.py +0 -0
  171. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/__init__.py +0 -0
  172. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/branch.py +0 -0
  173. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/changelog.py +0 -0
  174. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/diff.py +0 -0
  175. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/errors.py +0 -0
  176. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/feature.py +0 -0
  177. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/file_content.py +0 -0
  178. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/file_context.py +0 -0
  179. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/git.py +0 -0
  180. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/gitlab_ref.py +0 -0
  181. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/identification.py +0 -0
  182. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/logging.py +0 -0
  183. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/manifest.py +0 -0
  184. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/oid.py +0 -0
  185. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/pagination.py +0 -0
  186. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/path.py +0 -0
  187. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/peer.py +0 -0
  188. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/procutil.py +0 -0
  189. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/repository.py +0 -0
  190. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/revision.py +0 -0
  191. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/revset.py +0 -0
  192. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/scripts.py +0 -0
  193. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/__init__.py +0 -0
  194. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/address.py +0 -0
  195. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/mono.py +0 -0
  196. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/prefork.py +0 -0
  197. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/tests/__init__.py +0 -0
  198. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/tests/test_address.py +0 -0
  199. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/tests/test_mono.py +0 -0
  200. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/tests/test_prefork.py +0 -0
  201. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/tests/test_worker.py +0 -0
  202. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/server/worker.py +0 -0
  203. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/__init__.py +0 -0
  204. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/analysis.py +0 -0
  205. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/blob.py +0 -0
  206. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/commit.py +0 -0
  207. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/diff.py +0 -0
  208. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/interceptors.py +0 -0
  209. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/mercurial_changeset.py +0 -0
  210. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/mercurial_repository.py +0 -0
  211. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/ref.py +0 -0
  212. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/repository.py +0 -0
  213. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/server.py +0 -0
  214. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/__init__.py +0 -0
  215. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_analysis.py +0 -0
  216. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_blob.py +0 -0
  217. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_commit.py +0 -0
  218. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_default_branch.py +0 -0
  219. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_diff.py +0 -0
  220. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_mercurial_changeset.py +0 -0
  221. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_mercurial_repository.py +0 -0
  222. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_operations.py +0 -0
  223. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_ref.py +0 -0
  224. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/service/tests/test_server.py +0 -0
  225. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/ssh.py +0 -0
  226. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stream.py +0 -0
  227. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/__init__.py +0 -0
  228. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/analysis_pb2.py +0 -0
  229. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/analysis_pb2_grpc.py +0 -0
  230. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/blob_pb2.py +0 -0
  231. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/blob_pb2_grpc.py +0 -0
  232. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/commit_pb2.py +0 -0
  233. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/commit_pb2_grpc.py +0 -0
  234. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/diff_pb2.py +0 -0
  235. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/diff_pb2_grpc.py +0 -0
  236. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/errors_pb2.py +0 -0
  237. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/errors_pb2_grpc.py +0 -0
  238. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/lint_pb2.py +0 -0
  239. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/lint_pb2_grpc.py +0 -0
  240. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_changeset_pb2.py +0 -0
  241. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_changeset_pb2_grpc.py +0 -0
  242. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_repository_pb2.py +0 -0
  243. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/mercurial_repository_pb2_grpc.py +0 -0
  244. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/operations_pb2.py +0 -0
  245. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/operations_pb2_grpc.py +0 -0
  246. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/ref_pb2.py +0 -0
  247. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/ref_pb2_grpc.py +0 -0
  248. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/remote_pb2.py +0 -0
  249. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/remote_pb2_grpc.py +0 -0
  250. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/repository_pb2.py +0 -0
  251. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/repository_pb2_grpc.py +0 -0
  252. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/server_pb2.py +0 -0
  253. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/server_pb2_grpc.py +0 -0
  254. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/shared_pb2.py +0 -0
  255. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/stub/shared_pb2_grpc.py +0 -0
  256. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tag.py +0 -0
  257. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/__init__.py +0 -0
  258. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/bundle.py +0 -0
  259. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/context.py +0 -0
  260. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/grpc.py +0 -0
  261. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/multiprocessing.py +0 -0
  262. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/ssh.py +0 -0
  263. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/sshd.py +0 -0
  264. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/tests/__init__.py +0 -0
  265. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/testing/tests/test_sshd.py +0 -0
  266. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/__init__.py +0 -0
  267. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_branch.py +0 -0
  268. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_diff.py +0 -0
  269. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_errors.py +0 -0
  270. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_feature.py +0 -0
  271. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_file_context.py +0 -0
  272. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_gitlab_ref.py +0 -0
  273. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_identification.py +0 -0
  274. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_manifest.py +0 -0
  275. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_messages.py +0 -0
  276. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_oid.py +0 -0
  277. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_peer.py +0 -0
  278. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_repository.py +0 -0
  279. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_revision.py +0 -0
  280. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_revset.py +0 -0
  281. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_servicer.py +0 -0
  282. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_stream.py +0 -0
  283. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_tag.py +0 -0
  284. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/tests/test_workdir.py +0 -0
  285. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/util.py +0 -0
  286. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly/workdir.py +0 -0
  287. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly.egg-info/dependency_links.txt +0 -0
  288. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly.egg-info/entry_points.txt +0 -0
  289. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/hgitaly.egg-info/top_level.txt +0 -0
  290. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/setup.cfg +0 -0
  291. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/setup.py +0 -0
  292. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/__init__.py +0 -0
  293. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/comparison.py +0 -0
  294. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/conftest.py +0 -0
  295. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/gitaly.py +0 -0
  296. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/hgitaly_rhgitaly_comparison.py +0 -0
  297. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/rhgitaly.py +0 -0
  298. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_blob_tree.py +0 -0
  299. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_commit.py +0 -0
  300. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_comparison.py +0 -0
  301. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_diff.py +0 -0
  302. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_gitaly_server.py +0 -0
  303. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_mercurial_operations.py +0 -0
  304. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_mercurial_repository.py +0 -0
  305. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_operations.py +0 -0
  306. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_ref.py +0 -0
  307. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_remote.py +0 -0
  308. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/tests_with_gitaly/test_rhgitaly_server.py +0 -0
  309. {hgitaly-18.4.0a0 → hgitaly-18.5.0.dev0}/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.4.0a0
3
+ Version: 18.5.0.dev0
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,10 +10,10 @@ 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.2.0dev0
13
+ Requires-Dist: heptapod>=5.3.0dev0
14
14
  Requires-Dist: protobuf~=6.31.1
15
- Requires-Dist: grpcio~=1.74.0
16
- Requires-Dist: grpcio-status~=1.74.0
15
+ Requires-Dist: grpcio~=1.75.0
16
+ Requires-Dist: grpcio-status~=1.75.0
17
17
  Requires-Dist: grpc-interceptor
18
18
  Requires-Dist: grpcio-health-checking
19
19
  Requires-Dist: hg-loggingmod>=0.4.1
@@ -0,0 +1 @@
1
+ 18.5.0dev0
@@ -19,6 +19,7 @@ from .stub.shared_pb2 import (
19
19
  GitCommit,
20
20
  SignatureType,
21
21
  Tag,
22
+ User,
22
23
  )
23
24
  from .stub.commit_pb2 import (
24
25
  ListLastCommitsForTreeResponse,
@@ -138,6 +139,10 @@ def commit_author(ctx):
138
139
  )
139
140
 
140
141
 
142
+ def user_for_hg(user: User) -> bytes:
143
+ return b'%s <%s>' % (user.name, user.email)
144
+
145
+
141
146
  def commit_stats(ctx):
142
147
  if len(ctx.parents()) > 1:
143
148
  # Gitaly does not provide the stats for merge commits
@@ -15,11 +15,25 @@ from mercurial.node import nullhex as NULL_NODE_HEX
15
15
  from mercurial.phases import (
16
16
  public as PUBLIC,
17
17
  )
18
- from mercurial import util as hgutil
18
+ from mercurial import (
19
+ cmdutil,
20
+ commands,
21
+ error as hgerror,
22
+ util as hgutil,
23
+ )
24
+ from hgext.rebase import (
25
+ rebaseruntime,
26
+ sortsource as rebase_sort_source
27
+ )
19
28
 
20
29
  from heptapod.gitlab.branch import (
21
- NAMED_BRANCH_PREFIX,
30
+ branch_is_named_branch,
22
31
  gitlab_branch_ref,
32
+ parse_gitlab_branch,
33
+ )
34
+ from hgext3rd.heptapod.branch import (
35
+ gitlab_branches,
36
+ invalidate_gitlab_branches,
23
37
  )
24
38
 
25
39
  from .. import message
@@ -48,6 +62,8 @@ from ..workdir import (
48
62
  from ..stub.errors_pb2 import (
49
63
  MergeConflictError,
50
64
  ReferenceUpdateError,
65
+ ReferenceStateMismatchError,
66
+ ResolveRevisionError,
51
67
  )
52
68
  from ..stub.mercurial_operations_pb2 import (
53
69
  CensorRequest,
@@ -62,6 +78,9 @@ from ..stub.mercurial_operations_pb2 import (
62
78
  PublishChangesetError,
63
79
  PublishChangesetRequest,
64
80
  PublishChangesetResponse,
81
+ RebaseError,
82
+ RebaseRequest,
83
+ RebaseResponse,
65
84
  ReleaseWorkingDirectoryRequest,
66
85
  ReleaseWorkingDirectoryResponse,
67
86
  GetWorkingDirectoryRequest,
@@ -266,7 +285,7 @@ class MercurialOperationsServicer(MercurialOperationsServiceServicer,
266
285
  target_branch = request.branch
267
286
  if not target_branch:
268
287
  context.abort(StatusCode.INVALID_ARGUMENT, "empty branch name")
269
- if not target_branch.startswith(NAMED_BRANCH_PREFIX):
288
+ if not branch_is_named_branch(target_branch):
270
289
  context.abort(StatusCode.FAILED_PRECONDITION,
271
290
  "Heptapod merges are currently targeting "
272
291
  "named branches only (no topics nor bookmarks)")
@@ -384,7 +403,7 @@ class MercurialOperationsServicer(MercurialOperationsServiceServicer,
384
403
  new_changeset = self.merge(working_dir=wd,
385
404
  source_changeset=to_merge,
386
405
  user=request.user,
387
- message=request.message,
406
+ commit_message=request.message,
388
407
  unix_timestamp=unix_ts,
389
408
  context=context)
390
409
  except ConflictError as exc:
@@ -411,7 +430,7 @@ class MercurialOperationsServicer(MercurialOperationsServiceServicer,
411
430
  ))
412
431
 
413
432
  def merge(self, working_dir, context, source_changeset,
414
- user: User, message, unix_timestamp):
433
+ user: User, commit_message, unix_timestamp):
415
434
  """Merge changeset with given revno in working repository.
416
435
 
417
436
  The working repositoy is assumed to be already updated in a
@@ -424,11 +443,141 @@ class MercurialOperationsServicer(MercurialOperationsServiceServicer,
424
443
  raise ConflictError(unresolved)
425
444
  # TODO user timezone (symbolic or UTC offset?)
426
445
  self.repo_command(working_repo, context, 'commit',
427
- user=b'%s <%s>' % (user.name, user.email),
446
+ user=message.user_for_hg(user),
428
447
  date=b'%d 0' % unix_timestamp,
429
- message=message)
448
+ message=commit_message)
430
449
  return working_repo[b'.']
431
450
 
451
+ def Rebase(self, request: RebaseRequest, context) -> RebaseResponse:
452
+ logger = LoggerAdapter(base_logger, context)
453
+
454
+ repo = self.load_repo(request.repository, context,
455
+ for_mutation_by=request.user)
456
+
457
+ source = request.source
458
+ if not source:
459
+ context.abort(StatusCode.INVALID_ARGUMENT,
460
+ "empty source branch name")
461
+ dest = request.destination
462
+ if not dest:
463
+ context.abort(StatusCode.INVALID_ARGUMENT,
464
+ "empty destination branch name")
465
+
466
+ branch, topic = parse_gitlab_branch(source)
467
+ if topic is None:
468
+ structured_abort(
469
+ context,
470
+ StatusCode.INVALID_ARGUMENT,
471
+ "Not a topic",
472
+ RebaseError(pre_check=PreCheckUpdateError.NOT_A_TOPIC)
473
+ )
474
+ # todo check sha if given
475
+
476
+ dest_cs = gitlab_revision_changeset(repo, dest)
477
+ if dest_cs is None:
478
+ structured_abort(
479
+ context,
480
+ StatusCode.FAILED_PRECONDITION,
481
+ "Failed to resolve destination",
482
+ RebaseError(resolve_rev=ResolveRevisionError(revision=dest))
483
+ )
484
+ source_cs = gitlab_revision_changeset(repo, source)
485
+ if source_cs is None:
486
+ structured_abort(
487
+ context,
488
+ StatusCode.FAILED_PRECONDITION,
489
+ "Failed to resolve source",
490
+ RebaseError(resolve_rev=ResolveRevisionError(revision=source))
491
+ )
492
+ expected_sha = request.source_head_sha.encode('utf-8')
493
+ actual_sha = source_cs.hex()
494
+ if expected_sha and expected_sha != actual_sha:
495
+ structured_abort(
496
+ context,
497
+ StatusCode.FAILED_PRECONDITION,
498
+ "Source head sha mismatch",
499
+ RebaseError(ref_mismatch=ReferenceStateMismatchError(
500
+ reference_name=source,
501
+ expected_object_id=expected_sha,
502
+ actual_object_id=actual_sha))
503
+ )
504
+
505
+ # branch and topic naming rules make sure that we need no escaping
506
+ # using the head sha for reassurance
507
+ revset = b"branch('%s//%s') and ::%s" % (
508
+ branch, topic, source_cs.hex()
509
+ )
510
+ username = message.user_for_hg(request.user)
511
+ logger.info("Performing rebase, revset=%r, destination=%r",
512
+ revset, dest_cs.hex())
513
+ with self.working_dir(gl_repo=request.repository,
514
+ repo=repo,
515
+ changeset=source_cs,
516
+ context=context) as wd:
517
+ did_rebase = wd_rebase(wd, username, revset, dest_cs, context)
518
+
519
+ if not did_rebase:
520
+ return RebaseResponse()
521
+
522
+ invalidate_gitlab_branches(repo)
523
+ # do not use gitlab_revisions_changeset, as building the
524
+ # changectx would fail (`repo[new_head]` would end up in LookupError)
525
+ # we'd need to reload the repo, which is quite useless because we
526
+ # are happy with just the new Node ID
527
+ new_head = gitlab_branches(repo)[source]
528
+ return RebaseResponse(
529
+ branch_update=OperationBranchUpdate(
530
+ commit_id=new_head.decode('ascii')))
531
+
532
+
533
+ def wd_rebase(working_dir, username, revset, dest_cs, context):
534
+ """Perform the rebase in the working directory, handling errors
535
+
536
+ :returns: ``True`` if rebase actually happened
537
+ """
538
+ repo = working_dir.repo
539
+
540
+ # TODO would be nice to experiment with in-memory rebase (wouldn't
541
+ # need a working dir) but not sure what the good use cases are.
542
+ # For instance, is a small rebase on a big repo much more efficient
543
+ # in memory or should that precisely be avoided?
544
+ overrides = {
545
+ (b'experimental', b'evolution.allowunstable'): False,
546
+ (b'rebase', b'singletransaction'): True,
547
+ }
548
+ # overriding ui.username does not work, this does:
549
+ repo.ui.environ[b'HGUSER'] = username
550
+ with repo.ui.configoverride(overrides, b'rebase'):
551
+ rebase = cmdutil.findcmd(b'rebase', commands.table)[1][0]
552
+ try:
553
+ retcode = rebase(repo.ui, repo, rev=[revset], dest=dest_cs.hex())
554
+ except hgerror.ConflictResolutionRequired:
555
+ conflicts = list(mergestate.read(repo).unresolved())
556
+ runtime = rebaseruntime(repo, repo.ui)
557
+ runtime.restorestatus()
558
+ # rebase_sort_source is the generator used by rebase to
559
+ # know what to do in order. Not sure why each yielded element
560
+ # is a list though (it's a singleton in simple tested cases)
561
+ failed_rev = next(rebase_sort_source(runtime.destmap))[0]
562
+ failed_sha = repo[failed_rev].hex().decode('ascii')
563
+ current_sha = repo[None].p1().hex().decode('ascii')
564
+
565
+ # next use of this workdir should be able to recover. Still it
566
+ # is best to do it right away
567
+ rebase(repo.ui, repo, abort=True)
568
+ working_dir.purge()
569
+
570
+ structured_abort(
571
+ context,
572
+ StatusCode.FAILED_PRECONDITION,
573
+ "Rebase conflict",
574
+ RebaseError(conflict=MergeConflictError(
575
+ conflicting_files=conflicts,
576
+ conflicting_commit_ids=[current_sha, failed_sha]
577
+ ))
578
+ )
579
+ return retcode is None or retcode == 0
580
+
432
581
 
433
582
  def wd_merge(working_dir, source_cs):
434
583
  """Merge source_cs in the given a working directory (repo share).
@@ -23,7 +23,7 @@ from heptapod import (
23
23
  )
24
24
 
25
25
  from heptapod.gitlab.branch import (
26
- NAMED_BRANCH_PREFIX,
26
+ branch_is_named_branch,
27
27
  parse_gitlab_branch,
28
28
  )
29
29
 
@@ -252,7 +252,7 @@ class OperationServicer(OperationServiceServicer, HGitalyServicer):
252
252
  if not request.branch:
253
253
  context.abort(StatusCode.INVALID_ARGUMENT, "empty branch name")
254
254
 
255
- if not request.branch.startswith(NAMED_BRANCH_PREFIX):
255
+ if not branch_is_named_branch(request.branch):
256
256
  context.abort(StatusCode.FAILED_PRECONDITION,
257
257
  "Heptapod fast forwards are currently "
258
258
  "for named branches only (no topics nor bookmarks)")
@@ -17,6 +17,7 @@ from hgitaly.servicer import (
17
17
  SKIP_HOOKS_MD_KEY,
18
18
  )
19
19
  from hgitaly.stub.shared_pb2 import Repository
20
+ from hgitaly.workdir import wd_path
20
21
 
21
22
  from heptapod.testhelpers import (
22
23
  LocalRepoWrapper,
@@ -37,6 +38,9 @@ from hgitaly.stub.shared_pb2 import (
37
38
  User,
38
39
  )
39
40
  from hgitaly.testing.storage import (
41
+ repo_workdirs_root,
42
+ storage_path,
43
+ storage_workdirs,
40
44
  stowed_away_git_repo_path,
41
45
  )
42
46
 
@@ -143,12 +147,12 @@ class ServiceFixture:
143
147
  self.repos_to_cleanup.append(repo_path)
144
148
  return repo_path, repo_msg
145
149
 
146
- def storage_path(self, storage_name='default'):
150
+ def storage_path(self, **storage_kw):
147
151
  """Utility method to avoid depending too much on actual disk layout.
148
152
 
149
153
  This repeats the actual implementation just once.
150
154
  """
151
- return self.server_repos_root / storage_name
155
+ return storage_path(self.server_repos_root, **storage_kw)
152
156
 
153
157
  def repo_path(self, rel_path, **kw):
154
158
  """Utility method to avoid depending too much on actual disk layout.
@@ -172,6 +176,23 @@ class ServiceFixture:
172
176
  """
173
177
  return LocalRepoWrapper.load(self.repo_path(rel_path, **kw))
174
178
 
179
+ def storage_workdirs(self, **storage_kw):
180
+ return storage_workdirs(self.server_repos_root, **storage_kw)
181
+
182
+ def repo_workdirs_root(self, grpc_repo=None):
183
+ if grpc_repo is None:
184
+ grpc_repo = self.grpc_repo
185
+ return repo_workdirs_root(self.server_repos_root, grpc_repo)
186
+
187
+ def workdir_repo_wrapper(self, wd_id, grpc_repo=None):
188
+ """Direct low level access to a workdir repo.
189
+
190
+ This doesn't go through the normal initialization procedure, hence
191
+ is suitable to check state after error recovery.
192
+ """
193
+ return LocalRepoWrapper.load(
194
+ wd_path(self.repo_workdirs_root(grpc_repo=grpc_repo), wd_id))
195
+
175
196
  def rpc(self, method_name, request):
176
197
  """Call a method, taking care of metadata."""
177
198
  return getattr(self.stub, method_name)(
@@ -15,6 +15,8 @@ from mercurial import (
15
15
  error as hg_error,
16
16
  phases,
17
17
  )
18
+ from mercurial.mergestate import mergestate
19
+ from mercurial.node import nullid as NULL_NODE
18
20
  from mercurial_testhelpers import RepoWrapper
19
21
 
20
22
  from google.protobuf.timestamp_pb2 import Timestamp
@@ -38,6 +40,9 @@ from hgitaly.stub.mercurial_operations_pb2 import (
38
40
  CensorRequest,
39
41
  MergeBranchError,
40
42
  MergeBranchRequest,
43
+ RebaseError,
44
+ RebaseRequest,
45
+ RebaseResponse,
41
46
  MercurialPermissions,
42
47
  PreCheckUpdateError,
43
48
  PublishChangesetRequest,
@@ -50,6 +55,7 @@ from hgitaly.stub.mercurial_operations_pb2_grpc import (
50
55
  MercurialOperationsServiceStub,
51
56
  )
52
57
  from hgitaly.tests.common import make_empty_repo_with_gitlab_state_maintainer
58
+ from hgitaly.testing.repo import assert_empty_repo_status
53
59
  from .fixture import MutationServiceFixture
54
60
 
55
61
  parametrize = pytest.mark.parametrize
@@ -86,6 +92,12 @@ class OperationsFixture(MutationServiceFixture):
86
92
  return self.stub.MergeBranch(MergeBranchRequest(**kw),
87
93
  metadata=self.grpc_metadata())
88
94
 
95
+ def rebase(self, **kw):
96
+ kw.setdefault('repository', self.grpc_repo)
97
+ kw.setdefault('user', self.user)
98
+ return self.stub.Rebase(RebaseRequest(**kw),
99
+ metadata=self.grpc_metadata())
100
+
89
101
  def get_workdir(self, **kw):
90
102
  kw.setdefault('client_id', self.client_id)
91
103
  kw.setdefault('incarnation_id', INCARNATION_ID)
@@ -596,6 +608,126 @@ def test_merge_branch_troubled_changesets(operations_fixture):
596
608
  assert merge_error.pre_check == PreCheckUpdateError.UNSTABLE_CHANGESET
597
609
 
598
610
 
611
+ @parametrize('project_mode', ('hg-git-project', 'native-project'))
612
+ def test_rebase_basic(operations_fixture, project_mode):
613
+ fixture = operations_fixture
614
+ rebase = fixture.rebase
615
+
616
+ fixture.hg_native = project_mode != 'hg-git-project'
617
+ wrapper = fixture.repo_wrapper
618
+
619
+ gl_branch = b'branch/default'
620
+ gl_topic = b'topic/default/zetop'
621
+
622
+ # because of the config set by fixture, this leads in all cases to
623
+ # creation of a Git repo and its `branch/default` Git branch
624
+ ctx0 = wrapper.commit_file('foo')
625
+ sha0 = ctx0.hex().decode()
626
+ default_head = wrapper.commit_file('foo')
627
+ ctx2 = wrapper.commit_file('bar', topic='zetop', parent=ctx0)
628
+ sha2 = ctx2.hex().decode()
629
+ # avoid keeping the rebased changesets visible
630
+ wrapper.update_bin(NULL_NODE)
631
+
632
+ # simple error cases
633
+ with pytest.raises(RpcError) as exc_info:
634
+ rebase(source=gl_topic)
635
+ assert exc_info.value.code() == StatusCode.INVALID_ARGUMENT
636
+ with pytest.raises(RpcError) as exc_info:
637
+ rebase(destination=gl_branch)
638
+ assert exc_info.value.code() == StatusCode.INVALID_ARGUMENT
639
+
640
+ # not a topic
641
+ with pytest.raises(RpcError) as exc_info:
642
+ rebase(source=gl_branch, destination=gl_branch)
643
+ details, rebase_error = parse_assert_structured_error(
644
+ exc_info.value, RebaseError, StatusCode.INVALID_ARGUMENT)
645
+ assert rebase_error.pre_check == PreCheckUpdateError.NOT_A_TOPIC
646
+
647
+ # unresolvable source or dest
648
+ with pytest.raises(RpcError) as exc_info:
649
+ rebase(destination=gl_branch, source=b'topic/default/unknown')
650
+ details, rebase_error = parse_assert_structured_error(
651
+ exc_info.value, RebaseError, StatusCode.FAILED_PRECONDITION)
652
+ assert rebase_error.resolve_rev.revision == b'topic/default/unknown'
653
+ with pytest.raises(RpcError) as exc_info:
654
+ rebase(source=gl_topic, destination=b'branch/unknown')
655
+ details, rebase_error = parse_assert_structured_error(
656
+ exc_info.value, RebaseError, StatusCode.FAILED_PRECONDITION)
657
+ assert rebase_error.resolve_rev.revision == b'branch/unknown'
658
+
659
+ # source_sha check failed
660
+ with pytest.raises(RpcError) as exc_info:
661
+ rebase(destination=gl_branch, source=gl_topic, source_head_sha=sha0)
662
+ details, rebase_error = parse_assert_structured_error(
663
+ exc_info.value, RebaseError, StatusCode.FAILED_PRECONDITION)
664
+ mismatch = rebase_error.ref_mismatch
665
+ assert mismatch.expected_object_id == ctx0.hex()
666
+ assert mismatch.actual_object_id == ctx2.hex()
667
+ assert mismatch.reference_name == gl_topic
668
+
669
+ # working simple case
670
+ resp = rebase(source=gl_topic, source_head_sha=sha2,
671
+ destination=gl_branch)
672
+ wrapper.reload()
673
+ new_hex = resp.branch_update.commit_id.encode('ascii')
674
+ assert new_hex
675
+ assert new_hex != ctx2.hex()
676
+ rebased = wrapper.repo[new_hex]
677
+ assert rebased.p1() == default_head
678
+ assert rebased.topic() == b'zetop'
679
+
680
+ # no-op gives empty response
681
+ wrapper.commit_file('fast-fwd', topic='ff', parent=default_head)
682
+ assert rebase(source=b'topic/default/ff',
683
+ destination=gl_branch) == RebaseResponse()
684
+
685
+
686
+ @parametrize('project_mode', ('hg-git-project', 'native-project'))
687
+ def test_rebase_conflict(operations_fixture, project_mode):
688
+ fixture = operations_fixture
689
+ rebase = fixture.rebase
690
+
691
+ fixture.hg_native = project_mode != 'hg-git-project'
692
+ wrapper = fixture.repo_wrapper
693
+
694
+ gl_branch = b'branch/default'
695
+ gl_topic = b'topic/default/zetop'
696
+
697
+ # because of the config set by fixture, this leads in all cases to
698
+ # creation of a Git repo and its `branch/default` Git branch
699
+ ctx0 = wrapper.commit_file('foo')
700
+ default_head = wrapper.commit_file('foo', content='foo')
701
+ default_sha = default_head.hex().decode()
702
+ ctx2 = wrapper.commit_file('foo', topic='zetop', parent=ctx0,
703
+ content='bar')
704
+ sha2 = ctx2.hex().decode()
705
+ # avoid keeping the rebased changesets visible
706
+ wrapper.update_bin(NULL_NODE)
707
+
708
+ initial_branches = gitlab_branches(wrapper.repo)
709
+
710
+ with pytest.raises(RpcError) as exc_info:
711
+ rebase(source=gl_topic, destination=gl_branch)
712
+ details, rebase_error = parse_assert_structured_error(
713
+ exc_info.value, RebaseError, StatusCode.FAILED_PRECONDITION)
714
+ conflict = rebase_error.conflict
715
+ assert conflict.conflicting_files == [b"foo"]
716
+ assert set(conflict.conflicting_commit_ids) == {default_sha, sha2}
717
+
718
+ # nothing changed and working dir is clean
719
+ wrapper.reload()
720
+ assert gitlab_branches(wrapper.repo) == initial_branches
721
+
722
+ wd_wrapper = fixture.workdir_repo_wrapper(0)
723
+ wd_repo = wd_wrapper.repo
724
+ ms = mergestate.read(wd_repo)
725
+ assert not list(ms.unresolved())
726
+ wctx = wd_repo[None]
727
+ assert wctx.p1() == ctx2
728
+ assert_empty_repo_status(wd_wrapper)
729
+
730
+
599
731
  @parametrize('project_mode', ('hg-git-project', 'native-project'))
600
732
  def test_censor(operations_fixture, project_mode):
601
733
  fixture = operations_fixture
@@ -896,8 +896,7 @@ def test_remove_repository(fixture_with_repo, wds_success):
896
896
  os.makedirs(aux_git_dir, exist_ok=True)
897
897
  (aux_git_dir / 'anyfile').write_bytes(b'anything')
898
898
 
899
- tmp_dir = wrapper.path.parent / '+hgitaly/tmp'
900
- wds_root = tmp_dir / 'workdirs' / grpc_repo.relative_path
899
+ wds_root = fixture.repo_workdirs_root()
901
900
 
902
901
  if wds_success == 'error':
903
902
  # let's sabotage the roster file to trigger an inner exception
@@ -920,7 +919,7 @@ def test_remove_repository(fixture_with_repo, wds_success):
920
919
  assert not aux_git_dir.exists()
921
920
 
922
921
  # no leftover in the temporary directory either
923
- assert not os.listdir(tmp_dir / 'workdirs')
922
+ assert not os.listdir(fixture.storage_workdirs())
924
923
 
925
924
  # unknown storage and repo
926
925
  with pytest.raises(grpc.RpcError) as exc_info:
@@ -33,6 +33,8 @@ from .stub.shared_pb2 import (
33
33
  GARBAGE_COLLECTING_RATE_GEN2 = 250
34
34
  GARBAGE_COLLECTING_RATE_GEN1 = 20
35
35
  AUX_GIT_REPOS_RELATIVE_DIR = "+hgitaly/hg-git"
36
+ TMP_RELATIVE_DIR = "+hgitaly/tmp"
37
+ REPOS_WORKDIRS_RELATIVE_DIR = TMP_RELATIVE_DIR + '/workdirs'
36
38
  HG_GIT_MIRRORING_MD_KEY = 'x-heptapod-hg-git-mirroring'
37
39
  NATIVE_PROJECT_MD_KEY = 'x-heptapod-hg-native'
38
40
  # TODO check if there is a GitLab MD for this, it should:
@@ -357,7 +359,7 @@ class HGitalyServicer:
357
359
  :raises OSError: if creation fails.
358
360
  """
359
361
  temp_dir = os.path.join(self.storage_root_dir(storage_name, context),
360
- b'+hgitaly', b'tmp')
362
+ TMP_RELATIVE_DIR.encode('ascii'))
361
363
  if not ensure:
362
364
  return temp_dir
363
365
 
@@ -24,21 +24,30 @@ _sym_db = _symbol_database.Default()
24
24
 
25
25
  from . import lint_pb2 as lint__pb2
26
26
  from . import repository_pb2 as repository__pb2
27
+ from . import shared_pb2 as shared__pb2
27
28
 
28
29
 
29
- DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17mercurial-aux-git.proto\x12\x07hgitaly\x1a\nlint.proto\x1a\x10repository.proto2\xcd\x02\n\x16MercurialAuxGitService\x12Y\n\x12\x41uxGitCreateBundle\x12\x1b.gitaly.CreateBundleRequest\x1a\x1c.gitaly.CreateBundleResponse\"\x06\xfa\x97(\x02\x08\x02\x30\x01\x12y\n\x16\x41uxGitCreateFromBundle\x12).gitaly.CreateRepositoryFromBundleRequest\x1a*.gitaly.CreateRepositoryFromBundleResponse\"\x06\xfa\x97(\x02\x08\x01(\x01\x12]\n\x14\x41uxGitRepositorySize\x12\x1d.gitaly.RepositorySizeRequest\x1a\x1e.gitaly.RepositorySizeResponse\"\x06\xfa\x97(\x02\x08\x01\x62\x06proto3')
30
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17mercurial-aux-git.proto\x12\x07hgitaly\x1a\nlint.proto\x1a\x10repository.proto\x1a\x0cshared.proto\"h\n\x1a\x41uxGitCommitMappingRequest\x12,\n\nrepository\x18\x01 \x01(\x0b\x32\x12.gitaly.RepositoryB\x04\x98\xc6,\x01\x12\x0b\n\x03ids\x18\x02 \x03(\t\x12\x0f\n\x07reverse\x18\x03 \x01(\x08\"*\n\x1b\x41uxGitCommitMappingResponse\x12\x0b\n\x03ids\x18\x02 \x03(\t2\xb7\x03\n\x16MercurialAuxGitService\x12Y\n\x12\x41uxGitCreateBundle\x12\x1b.gitaly.CreateBundleRequest\x1a\x1c.gitaly.CreateBundleResponse\"\x06\xfa\x97(\x02\x08\x02\x30\x01\x12y\n\x16\x41uxGitCreateFromBundle\x12).gitaly.CreateRepositoryFromBundleRequest\x1a*.gitaly.CreateRepositoryFromBundleResponse\"\x06\xfa\x97(\x02\x08\x01(\x01\x12]\n\x14\x41uxGitRepositorySize\x12\x1d.gitaly.RepositorySizeRequest\x1a\x1e.gitaly.RepositorySizeResponse\"\x06\xfa\x97(\x02\x08\x01\x12h\n\x13\x41uxGitCommitMapping\x12#.hgitaly.AuxGitCommitMappingRequest\x1a$.hgitaly.AuxGitCommitMappingResponse\"\x06\xfa\x97(\x02\x08\x02\x62\x06proto3')
30
31
 
31
32
  _globals = globals()
32
33
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
33
34
  _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'mercurial_aux_git_pb2', _globals)
34
35
  if not _descriptor._USE_C_DESCRIPTORS:
35
36
  DESCRIPTOR._loaded_options = None
37
+ _globals['_AUXGITCOMMITMAPPINGREQUEST'].fields_by_name['repository']._loaded_options = None
38
+ _globals['_AUXGITCOMMITMAPPINGREQUEST'].fields_by_name['repository']._serialized_options = b'\230\306,\001'
36
39
  _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitCreateBundle']._loaded_options = None
37
40
  _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitCreateBundle']._serialized_options = b'\372\227(\002\010\002'
38
41
  _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitCreateFromBundle']._loaded_options = None
39
42
  _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitCreateFromBundle']._serialized_options = b'\372\227(\002\010\001'
40
43
  _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitRepositorySize']._loaded_options = None
41
44
  _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitRepositorySize']._serialized_options = b'\372\227(\002\010\001'
42
- _globals['_MERCURIALAUXGITSERVICE']._serialized_start=67
43
- _globals['_MERCURIALAUXGITSERVICE']._serialized_end=400
45
+ _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitCommitMapping']._loaded_options = None
46
+ _globals['_MERCURIALAUXGITSERVICE'].methods_by_name['AuxGitCommitMapping']._serialized_options = b'\372\227(\002\010\002'
47
+ _globals['_AUXGITCOMMITMAPPINGREQUEST']._serialized_start=80
48
+ _globals['_AUXGITCOMMITMAPPINGREQUEST']._serialized_end=184
49
+ _globals['_AUXGITCOMMITMAPPINGRESPONSE']._serialized_start=186
50
+ _globals['_AUXGITCOMMITMAPPINGRESPONSE']._serialized_end=228
51
+ _globals['_MERCURIALAUXGITSERVICE']._serialized_start=231
52
+ _globals['_MERCURIALAUXGITSERVICE']._serialized_end=670
44
53
  # @@protoc_insertion_point(module_scope)
@@ -3,6 +3,7 @@
3
3
  import grpc
4
4
  import warnings
5
5
 
6
+ from . import mercurial_aux_git_pb2 as mercurial__aux__git__pb2
6
7
  from . import repository_pb2 as repository__pb2
7
8
 
8
9
  GRPC_GENERATED_VERSION = '1.74.0'
@@ -54,6 +55,11 @@ class MercurialAuxGitServiceStub(object):
54
55
  request_serializer=repository__pb2.RepositorySizeRequest.SerializeToString,
55
56
  response_deserializer=repository__pb2.RepositorySizeResponse.FromString,
56
57
  _registered_method=True)
58
+ self.AuxGitCommitMapping = channel.unary_unary(
59
+ '/hgitaly.MercurialAuxGitService/AuxGitCommitMapping',
60
+ request_serializer=mercurial__aux__git__pb2.AuxGitCommitMappingRequest.SerializeToString,
61
+ response_deserializer=mercurial__aux__git__pb2.AuxGitCommitMappingResponse.FromString,
62
+ _registered_method=True)
57
63
 
58
64
 
59
65
  class MercurialAuxGitServiceServicer(object):
@@ -82,6 +88,13 @@ class MercurialAuxGitServiceServicer(object):
82
88
  context.set_details('Method not implemented!')
83
89
  raise NotImplementedError('Method not implemented!')
84
90
 
91
+ def AuxGitCommitMapping(self, request, context):
92
+ """/ Resolve Mercurial commit ID from Git commit ID and conversely
93
+ """
94
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
95
+ context.set_details('Method not implemented!')
96
+ raise NotImplementedError('Method not implemented!')
97
+
85
98
 
86
99
  def add_MercurialAuxGitServiceServicer_to_server(servicer, server):
87
100
  rpc_method_handlers = {
@@ -100,6 +113,11 @@ def add_MercurialAuxGitServiceServicer_to_server(servicer, server):
100
113
  request_deserializer=repository__pb2.RepositorySizeRequest.FromString,
101
114
  response_serializer=repository__pb2.RepositorySizeResponse.SerializeToString,
102
115
  ),
116
+ 'AuxGitCommitMapping': grpc.unary_unary_rpc_method_handler(
117
+ servicer.AuxGitCommitMapping,
118
+ request_deserializer=mercurial__aux__git__pb2.AuxGitCommitMappingRequest.FromString,
119
+ response_serializer=mercurial__aux__git__pb2.AuxGitCommitMappingResponse.SerializeToString,
120
+ ),
103
121
  }
104
122
  generic_handler = grpc.method_handlers_generic_handler(
105
123
  'hgitaly.MercurialAuxGitService', rpc_method_handlers)
@@ -196,3 +214,30 @@ class MercurialAuxGitService(object):
196
214
  timeout,
197
215
  metadata,
198
216
  _registered_method=True)
217
+
218
+ @staticmethod
219
+ def AuxGitCommitMapping(request,
220
+ target,
221
+ options=(),
222
+ channel_credentials=None,
223
+ call_credentials=None,
224
+ insecure=False,
225
+ compression=None,
226
+ wait_for_ready=None,
227
+ timeout=None,
228
+ metadata=None):
229
+ return grpc.experimental.unary_unary(
230
+ request,
231
+ target,
232
+ '/hgitaly.MercurialAuxGitService/AuxGitCommitMapping',
233
+ mercurial__aux__git__pb2.AuxGitCommitMappingRequest.SerializeToString,
234
+ mercurial__aux__git__pb2.AuxGitCommitMappingResponse.FromString,
235
+ options,
236
+ channel_credentials,
237
+ insecure,
238
+ call_credentials,
239
+ compression,
240
+ wait_for_ready,
241
+ timeout,
242
+ metadata,
243
+ _registered_method=True)