Migrate Repository#last_commit_for_path to Gitaly
Closes gitaly#433
This commit is contained in:
parent
8f9b658e3a
commit
f81c07eacc
7 changed files with 90 additions and 27 deletions
|
@ -1 +1 @@
|
||||||
0.26.0
|
0.27.0
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -391,7 +391,7 @@ gem 'vmstat', '~> 2.3.0'
|
||||||
gem 'sys-filesystem', '~> 1.1.6'
|
gem 'sys-filesystem', '~> 1.1.6'
|
||||||
|
|
||||||
# Gitaly GRPC client
|
# Gitaly GRPC client
|
||||||
gem 'gitaly', '~> 0.23.0'
|
gem 'gitaly', '~> 0.24.0'
|
||||||
|
|
||||||
gem 'toml-rb', '~> 0.3.15', require: false
|
gem 'toml-rb', '~> 0.3.15', require: false
|
||||||
|
|
||||||
|
|
|
@ -269,7 +269,7 @@ GEM
|
||||||
po_to_json (>= 1.0.0)
|
po_to_json (>= 1.0.0)
|
||||||
rails (>= 3.2.0)
|
rails (>= 3.2.0)
|
||||||
gherkin-ruby (0.3.2)
|
gherkin-ruby (0.3.2)
|
||||||
gitaly (0.23.0)
|
gitaly (0.24.0)
|
||||||
google-protobuf (~> 3.1)
|
google-protobuf (~> 3.1)
|
||||||
grpc (~> 1.0)
|
grpc (~> 1.0)
|
||||||
github-linguist (4.7.6)
|
github-linguist (4.7.6)
|
||||||
|
@ -978,7 +978,7 @@ DEPENDENCIES
|
||||||
gettext (~> 3.2.2)
|
gettext (~> 3.2.2)
|
||||||
gettext_i18n_rails (~> 1.8.0)
|
gettext_i18n_rails (~> 1.8.0)
|
||||||
gettext_i18n_rails_js (~> 1.2.0)
|
gettext_i18n_rails_js (~> 1.2.0)
|
||||||
gitaly (~> 0.23.0)
|
gitaly (~> 0.24.0)
|
||||||
github-linguist (~> 4.7.0)
|
github-linguist (~> 4.7.0)
|
||||||
gitlab-flowdock-git-hook (~> 1.0.1)
|
gitlab-flowdock-git-hook (~> 1.0.1)
|
||||||
gitlab-markup (~> 1.5.1)
|
gitlab-markup (~> 1.5.1)
|
||||||
|
|
|
@ -613,17 +613,26 @@ class Repository
|
||||||
end
|
end
|
||||||
|
|
||||||
def last_commit_for_path(sha, path)
|
def last_commit_for_path(sha, path)
|
||||||
sha = last_commit_id_for_path(sha, path)
|
raw_repository.gitaly_migrate(:last_commit_for_path) do |is_enabled|
|
||||||
commit(sha)
|
if is_enabled
|
||||||
|
last_commit_for_path_by_gitaly(sha, path)
|
||||||
|
else
|
||||||
|
last_commit_for_path_by_rugged(sha, path)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/383
|
|
||||||
def last_commit_id_for_path(sha, path)
|
def last_commit_id_for_path(sha, path)
|
||||||
key = path.blank? ? "last_commit_id_for_path:#{sha}" : "last_commit_id_for_path:#{sha}:#{Digest::SHA1.hexdigest(path)}"
|
key = path.blank? ? "last_commit_id_for_path:#{sha}" : "last_commit_id_for_path:#{sha}:#{Digest::SHA1.hexdigest(path)}"
|
||||||
|
|
||||||
cache.fetch(key) do
|
cache.fetch(key) do
|
||||||
args = %W(#{Gitlab.config.git.bin_path} rev-list --max-count=1 #{sha} -- #{path})
|
raw_repository.gitaly_migrate(:last_commit_for_path) do |is_enabled|
|
||||||
Gitlab::Popen.popen(args, path_to_repo).first.strip
|
if is_enabled
|
||||||
|
last_commit_for_path_by_gitaly(sha, path).id
|
||||||
|
else
|
||||||
|
last_commit_id_for_path_by_shelling_out(sha, path)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1138,6 +1147,21 @@ class Repository
|
||||||
Rugged::Commit.create(rugged, params)
|
Rugged::Commit.create(rugged, params)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def last_commit_for_path_by_gitaly(sha, path)
|
||||||
|
c = raw_repository.gitaly_commit_client.last_commit_for_path(sha, path)
|
||||||
|
commit(c)
|
||||||
|
end
|
||||||
|
|
||||||
|
def last_commit_for_path_by_rugged(sha, path)
|
||||||
|
sha = last_commit_id_for_path_by_shelling_out(sha, path)
|
||||||
|
commit(sha)
|
||||||
|
end
|
||||||
|
|
||||||
|
def last_commit_id_for_path_by_shelling_out(sha, path)
|
||||||
|
args = %W(#{Gitlab.config.git.bin_path} rev-list --max-count=1 #{sha} -- #{path})
|
||||||
|
Gitlab::Popen.popen(args, path_to_repo).first.strip
|
||||||
|
end
|
||||||
|
|
||||||
def repository_storage_path
|
def repository_storage_path
|
||||||
@project.repository_storage_path
|
@project.repository_storage_path
|
||||||
end
|
end
|
||||||
|
|
|
@ -683,6 +683,14 @@ module Gitlab
|
||||||
@gitaly_repository_client ||= Gitlab::GitalyClient::RepositoryService.new(self)
|
@gitaly_repository_client ||= Gitlab::GitalyClient::RepositoryService.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def gitaly_migrate(method, &block)
|
||||||
|
Gitlab::GitalyClient.migrate(method, &block)
|
||||||
|
rescue GRPC::NotFound => e
|
||||||
|
raise NoRepository.new(e)
|
||||||
|
rescue GRPC::BadStatus => e
|
||||||
|
raise CommandError.new(e)
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Gitaly note: JV: Trying to get rid of the 'filter' option so we can implement this with 'git'.
|
# Gitaly note: JV: Trying to get rid of the 'filter' option so we can implement this with 'git'.
|
||||||
|
@ -998,6 +1006,11 @@ module Gitlab
|
||||||
end.sort_by(&:name)
|
end.sort_by(&:name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def last_commit_for_path_by_rugged(sha, path)
|
||||||
|
sha = last_commit_id_for_path(sha, path)
|
||||||
|
commit(sha)
|
||||||
|
end
|
||||||
|
|
||||||
def tags_from_gitaly
|
def tags_from_gitaly
|
||||||
gitaly_ref_client.tags
|
gitaly_ref_client.tags
|
||||||
end
|
end
|
||||||
|
@ -1017,14 +1030,6 @@ module Gitlab
|
||||||
|
|
||||||
raw_output.to_i
|
raw_output.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def gitaly_migrate(method, &block)
|
|
||||||
Gitlab::GitalyClient.migrate(method, &block)
|
|
||||||
rescue GRPC::NotFound => e
|
|
||||||
raise NoRepository.new(e)
|
|
||||||
rescue GRPC::BadStatus => e
|
|
||||||
raise CommandError.new(e)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -97,6 +97,20 @@ module Gitlab
|
||||||
GitalyClient.call(@repository.storage, :commit_service, :count_commits, request).count
|
GitalyClient.call(@repository.storage, :commit_service, :count_commits, request).count
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def last_commit_for_path(revision, path)
|
||||||
|
request = Gitaly::LastCommitForPathRequest.new(
|
||||||
|
repository: @gitaly_repo,
|
||||||
|
revision: revision.force_encoding(Encoding::ASCII_8BIT),
|
||||||
|
path: path.to_s.force_encoding(Encoding::ASCII_8BIT)
|
||||||
|
)
|
||||||
|
|
||||||
|
gitaly_commit = GitalyClient.call(@repository.storage, :commit_service, :last_commit_for_path, request).commit
|
||||||
|
return unless gitaly_commit
|
||||||
|
|
||||||
|
commit = GitalyClient::Commit.new(@repository, gitaly_commit)
|
||||||
|
Gitlab::Git::Commit.new(commit)
|
||||||
|
end
|
||||||
|
|
||||||
def between(from, to)
|
def between(from, to)
|
||||||
request = Gitaly::CommitsBetweenRequest.new(
|
request = Gitaly::CommitsBetweenRequest.new(
|
||||||
repository: @gitaly_repo,
|
repository: @gitaly_repo,
|
||||||
|
|
|
@ -139,24 +139,44 @@ describe Repository do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#last_commit_for_path' do
|
describe '#last_commit_for_path' do
|
||||||
subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id }
|
shared_examples 'getting last commit for path' do
|
||||||
|
subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id }
|
||||||
|
|
||||||
it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
|
it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Gitaly feature last_commit_for_path is enabled' do
|
||||||
|
it_behaves_like 'getting last commit for path'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when Gitaly feature last_commit_for_path is disabled', skip_gitaly_mock: true do
|
||||||
|
it_behaves_like 'getting last commit for path'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#last_commit_id_for_path' do
|
describe '#last_commit_id_for_path' do
|
||||||
subject { repository.last_commit_id_for_path(sample_commit.id, '.gitignore') }
|
shared_examples 'getting last commit ID for path' do
|
||||||
|
subject { repository.last_commit_id_for_path(sample_commit.id, '.gitignore') }
|
||||||
|
|
||||||
it "returns last commit id for a given path" do
|
it "returns last commit id for a given path" do
|
||||||
is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8')
|
is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "caches last commit id for a given path" do
|
||||||
|
cache = repository.send(:cache)
|
||||||
|
key = "last_commit_id_for_path:#{sample_commit.id}:#{Digest::SHA1.hexdigest('.gitignore')}"
|
||||||
|
|
||||||
|
expect(cache).to receive(:fetch).with(key).and_return('c1acaa5')
|
||||||
|
is_expected.to eq('c1acaa5')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "caches last commit id for a given path" do
|
context 'when Gitaly feature last_commit_for_path is enabled' do
|
||||||
cache = repository.send(:cache)
|
it_behaves_like 'getting last commit ID for path'
|
||||||
key = "last_commit_id_for_path:#{sample_commit.id}:#{Digest::SHA1.hexdigest('.gitignore')}"
|
end
|
||||||
|
|
||||||
expect(cache).to receive(:fetch).with(key).and_return('c1acaa5')
|
context 'when Gitaly feature last_commit_for_path is disabled', skip_gitaly_mock: true do
|
||||||
is_expected.to eq('c1acaa5')
|
it_behaves_like 'getting last commit ID for path'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue