Commit 1924ad9f authored by Georges Racinet's avatar Georges Racinet 🦑
Browse files

gitaly_client: plugging in HGitaly in CommitService

This is more complicated than what we've done earlier for
`RefService`:

- Upstream passes down storage to `GitalyClient.call` as
  `@repository.storage`. We don't want to change all methods
  of CommitService because it wouldn't apply readily to new
  methods from upstream.
  Hence we actually re-instantiate `@repository`,
  with the VCS-qualified storage, with the new `vcs_storage_clone`
  method. On the side, this also requires a small change
  in HgGitRepository to make the value admissible.
- only a subset of Commit service methods are actually involved
  in our first round of HGitaly implementation (getting rid of
  Git SHAs, see HGitaly1 milestone). We're deciding here that
  the other methods will use directly the original storage name,
  that we store as a new instance variable, `@git_storage`.
  In particular, we're trying to avoid the implementation of the
  various methods for Commit content (files, trees, diffs…) for
  the HGitaly1 milestone. This part is WIP (we'll need to
  convert back to Git revisions to complete it).
- Finally, this hack also requires to make sure that the resulting
  Commit instances refer to the original Repository, so that further
  (H)Gitaly calls done from these Commits don't reuse a VCS-qualified
  storage, which would defeat the very purpose of separation.

This is all very hacky. The only thing that makes it admissible is
that it is temporary scaffolding. For the HGitaly2 milestone, all
methods will go to HGitaly, and perhaps we can convince upstream to
use a `@storage` instance variable here for the sake of uniformity.

--HG--
branch : heptapod
parent 3639ef277c7e
......@@ -193,7 +193,7 @@ def get_messages(repository, commit_ids)
def initialize(repository, raw_commit, head = nil, lazy_load_parents: false)
raise "Nil as raw commit passed" unless raw_commit
@repository = repository
@repository = repository.hpd_original
@head = head
@lazy_load_parents = lazy_load_parents
......
......@@ -64,6 +64,12 @@ def initialize(storage, relative_path, gl_repository, gl_project_path)
@name = @relative_path.split("/").last
end
# Subclassed by HGitaly as temporary scaffolding, waiting for
# HGitaly2 milestone to be reached
def hpd_original
self
end
def to_s
"<#{self.class.name}: #{self.gl_project_path}>"
end
......
......@@ -5,9 +5,13 @@ module GitalyClient
class CommitService
include Gitlab::EncodingHelper
def initialize(repository)
def initialize(repository, vcs: nil)
@gitaly_repo = repository.gitaly_repository
@repository = repository
# This client class doesn't have a separate `@storage` instance
# variable, so we're cloning the incoming `repository`, with
# an explicit `storage`.
@repository = vcs.nil? ? repository : repository.vcs_storage_clone(vcs)
@git_storage = repository.storage
end
def ls_files(revision)
......@@ -16,7 +20,7 @@ def ls_files(revision)
revision: encode_binary(revision)
)
response = GitalyClient.call(@repository.storage, :commit_service, :list_files, request, timeout: GitalyClient.medium_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :list_files, request, timeout: GitalyClient.medium_timeout)
response.flat_map do |msg|
msg.paths.map { |d| EncodingHelper.encode!(d.dup) }
end
......@@ -72,7 +76,7 @@ def diff_from_parent(commit, options = {})
def commit_deltas(commit)
request = Gitaly::CommitDeltaRequest.new(diff_from_parent_request_params(commit))
response = GitalyClient.call(@repository.storage, :diff_service, :commit_delta, request, timeout: GitalyClient.fast_timeout)
response = GitalyClient.call(@git_storage, :diff_service, :commit_delta, request, timeout: GitalyClient.fast_timeout)
response.flat_map { |msg| msg.deltas }
end
......@@ -90,8 +94,7 @@ def tree_entry(ref, path, limit = nil)
path: encode_binary(path),
limit: limit.to_i
)
response = GitalyClient.call(@repository.storage, :commit_service, :tree_entry, request, timeout: GitalyClient.medium_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :tree_entry, request, timeout: GitalyClient.medium_timeout)
entry = nil
data = []
......@@ -117,7 +120,7 @@ def tree_entries(repository, revision, path, recursive)
recursive: recursive
)
response = GitalyClient.call(@repository.storage, :commit_service, :get_tree_entries, request, timeout: GitalyClient.medium_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :get_tree_entries, request, timeout: GitalyClient.medium_timeout)
response.flat_map do |message|
message.entries.map do |gitaly_tree_entry|
......@@ -157,7 +160,7 @@ def diverging_commit_count(from, to, max_count:)
to: encode_binary(to),
max_count: max_count
)
response = GitalyClient.call(@repository.storage, :commit_service, :count_diverging_commits, request, timeout: GitalyClient.medium_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :count_diverging_commits, request, timeout: GitalyClient.medium_timeout)
[response.left_count, response.right_count]
end
......@@ -257,7 +260,7 @@ def commits_by_message(query, revision: '', path: '', limit: 1000, offset: 0, li
def languages(ref = nil)
request = Gitaly::CommitLanguagesRequest.new(repository: @gitaly_repo, revision: ref || '')
response = GitalyClient.call(@repository.storage, :commit_service, :commit_languages, request, timeout: GitalyClient.long_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :commit_languages, request, timeout: GitalyClient.long_timeout)
response.languages.map { |l| { value: l.share.round(2), label: l.name, color: l.color, highlight: l.color } }
end
......@@ -269,7 +272,7 @@ def raw_blame(revision, path)
path: encode_binary(path)
)
response = GitalyClient.call(@repository.storage, :commit_service, :raw_blame, request, timeout: GitalyClient.medium_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :raw_blame, request, timeout: GitalyClient.medium_timeout)
response.reduce([]) { |memo, msg| memo << msg.data }.join
end
......@@ -305,7 +308,7 @@ def commit_stats(revision)
repository: @gitaly_repo,
revision: encode_binary(revision)
)
GitalyClient.call(@repository.storage, :commit_service, :commit_stats, request, timeout: GitalyClient.medium_timeout)
GitalyClient.call(@git_storage, :commit_service, :commit_stats, request, timeout: GitalyClient.medium_timeout)
end
def find_commits(options)
......@@ -353,7 +356,7 @@ def filter_shas_with_signatures(shas)
def get_commit_signatures(commit_ids)
request = Gitaly::GetCommitSignaturesRequest.new(repository: @gitaly_repo, commit_ids: commit_ids)
response = GitalyClient.call(@repository.storage, :commit_service, :get_commit_signatures, request, timeout: GitalyClient.fast_timeout)
response = GitalyClient.call(@git_storage, :commit_service, :get_commit_signatures, request, timeout: GitalyClient.fast_timeout)
signatures = Hash.new { |h, k| h[k] = [+''.b, +''.b] }
current_commit_id = nil
......
......@@ -53,7 +53,11 @@ class HgGitRepository < Gitlab::Git::Repository
def initialize(*args)
super(*args)
@hg_relative_path = relative_path.sub(/\.git$/, '.hg')
@hg_storage_root = Gitlab.config.repositories.storages.fetch(storage).hg_disk_path
# storage can actually be in VCS-qualified form (see CommitService)
# so we need to handle that.
bare_storage = Gitlab::GitalyClient.vcs_storage_split(@storage)[0]
@hg_storage_root = Gitlab.config.repositories.storages.fetch(
bare_storage).hg_disk_path
@hgpath = File.join(@hg_storage_root, @hg_relative_path)
# `nil` is the language default for instance variables,
......
......@@ -5,6 +5,23 @@ module Mercurial
class HgitalyRepository < HgGitRepository
extend ::Gitlab::Utils::Override
def initialize(*args, hpd_original: nil)
super(*args)
@hpd_original = hpd_original
end
def hpd_original
@hpd_original.nil? ? self : @hpd_original
end
def hg_sha_map
@hpd_original.nil? ? super : @hpd_original.hg_sha_map
end
def git_sha_map
@hpd_original.nil? ? super : @hpd_original.git_sha_map
end
override :archive_sha
def archive_sha(sha)
sha
......@@ -36,9 +53,24 @@ def commit_id_from_display_id(display_id)
display_id
end
# Clone current repository with a VCS qualified value for `storage`
def vcs_storage_clone(vcs)
self.class.new(
Gitlab::GitalyClient.vcs_qualified_storage(@storage, vcs),
@relative_path,
@gl_repository,
@gl_project_path,
hpd_original: self
)
end
def gitaly_ref_client
@gitaly_ref_client ||= Gitlab::GitalyClient::RefService.new(self, vcs: 'hg')
end
def gitaly_commit_client
@gitaly_commit_client ||= Gitlab::GitalyClient::CommitService.new(self, vcs: 'hg')
end
end
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment