Commit e299d595 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'feature/migrate-last-commit-for-path-to-gitaly' into 'master'

Migrate Repository#last_commit_for_path to Gitaly

Closes gitaly#433

See merge request !13200
parents 7e45159f f81c07ea
...@@ -613,17 +613,26 @@ class Repository ...@@ -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 ...@@ -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
......
...@@ -1006,6 +1006,11 @@ module Gitlab ...@@ -1006,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
......
...@@ -97,6 +97,20 @@ module Gitlab ...@@ -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,12 +139,23 @@ describe Repository do ...@@ -139,12 +139,23 @@ describe Repository do
end end
describe '#last_commit_for_path' do describe '#last_commit_for_path' do
shared_examples 'getting last commit for path' do
subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id } subject { repository.last_commit_for_path(sample_commit.id, '.gitignore').id }
it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') } it { is_expected.to eq('c1acaa58bbcbc3eafe538cb8274ba387047b69f8') }
end 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
describe '#last_commit_id_for_path' do describe '#last_commit_id_for_path' do
shared_examples 'getting last commit ID for path' do
subject { repository.last_commit_id_for_path(sample_commit.id, '.gitignore') } 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
...@@ -160,6 +171,15 @@ describe Repository do ...@@ -160,6 +171,15 @@ describe Repository do
end end
end end
context 'when Gitaly feature last_commit_for_path is enabled' do
it_behaves_like 'getting last commit ID for path'
end
context 'when Gitaly feature last_commit_for_path is disabled', skip_gitaly_mock: true do
it_behaves_like 'getting last commit ID for path'
end
end
describe '#commits' do describe '#commits' do
it 'sets follow when path is a single path' do it 'sets follow when path is a single path' do
expect(Gitlab::Git::Commit).to receive(:where).with(a_hash_including(follow: true)).and_call_original.twice expect(Gitlab::Git::Commit).to receive(:where).with(a_hash_including(follow: true)).and_call_original.twice
......
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