Commit 37cc50f8 authored by Alejandro Rodríguez's avatar Alejandro Rodríguez

Incorporate Gitaly's OperationService.UserFFBranch RPC

parent 74a0e855
...@@ -73,7 +73,7 @@ module Gitlab ...@@ -73,7 +73,7 @@ module Gitlab
decorate(repo, commit) if commit decorate(repo, commit) if commit
rescue Rugged::ReferenceError, Rugged::InvalidError, Rugged::ObjectError, rescue Rugged::ReferenceError, Rugged::InvalidError, Rugged::ObjectError,
Gitlab::Git::CommandError, Gitlab::Git::Repository::NoRepository, Gitlab::Git::CommandError, Gitlab::Git::Repository::NoRepository,
Rugged::OdbError, Rugged::TreeError Rugged::OdbError, Rugged::TreeError, ArgumentError
nil nil
end end
......
...@@ -750,13 +750,13 @@ module Gitlab ...@@ -750,13 +750,13 @@ module Gitlab
end end
def ff_merge(user, source_sha, target_branch) def ff_merge(user, source_sha, target_branch)
OperationService.new(user, self).with_branch(target_branch) do |our_commit| gitaly_migrate(:operation_user_ff_branch) do |is_enabled|
raise ArgumentError, 'Invalid merge target' unless our_commit if is_enabled
gitaly_ff_merge(user, source_sha, target_branch)
source_sha else
rugged_ff_merge(user, source_sha, target_branch)
end
end end
rescue Rugged::ReferenceError
raise ArgumentError, 'Invalid merge source'
end end
def revert(user:, commit:, branch_name:, message:, start_branch_name:, start_repository:) def revert(user:, commit:, branch_name:, message:, start_branch_name:, start_repository:)
...@@ -1169,10 +1169,10 @@ module Gitlab ...@@ -1169,10 +1169,10 @@ module Gitlab
Gitlab::GitalyClient.migrate(method, status: status, &block) Gitlab::GitalyClient.migrate(method, status: status, &block)
rescue GRPC::NotFound => e rescue GRPC::NotFound => e
raise NoRepository.new(e) raise NoRepository.new(e)
rescue GRPC::BadStatus => e
raise CommandError.new(e)
rescue GRPC::InvalidArgument => e rescue GRPC::InvalidArgument => e
raise ArgumentError.new(e) raise ArgumentError.new(e)
rescue GRPC::BadStatus => e
raise CommandError.new(e)
end end
private private
...@@ -1614,6 +1614,22 @@ module Gitlab ...@@ -1614,6 +1614,22 @@ module Gitlab
run_git(args, env: env) run_git(args, env: env)
end end
def gitaly_ff_merge(user, source_sha, target_branch)
gitaly_operations_client.user_ff_branch(user, source_sha, target_branch)
rescue GRPC::FailedPrecondition => e
raise CommitError, e
end
def rugged_ff_merge(user, source_sha, target_branch)
OperationService.new(user, self).with_branch(target_branch) do |our_commit|
raise ArgumentError, 'Invalid merge target' unless our_commit
source_sha
end
rescue Rugged::ReferenceError
raise ArgumentError, 'Invalid merge source'
end
end end
end end
end end
...@@ -105,6 +105,23 @@ module Gitlab ...@@ -105,6 +105,23 @@ module Gitlab
ensure ensure
request_enum.close request_enum.close
end end
def user_ff_branch(user, source_sha, target_branch)
request = Gitaly::UserFFBranchRequest.new(
repository: @gitaly_repo,
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
commit_id: source_sha,
branch: GitalyClient.encode(target_branch)
)
branch_update = GitalyClient.call(
@repository.storage,
:operation_service,
:user_ff_branch,
request
).branch_update
Gitlab::Git::OperationService::BranchUpdate.from_gitaly(branch_update)
end
end end
end end
end end
...@@ -1609,38 +1609,56 @@ describe Gitlab::Git::Repository, seed_helper: true do ...@@ -1609,38 +1609,56 @@ describe Gitlab::Git::Repository, seed_helper: true do
subject { repository.ff_merge(user, source_sha, target_branch) } subject { repository.ff_merge(user, source_sha, target_branch) }
it 'performs a ff_merge' do shared_examples '#ff_merge' do
expect(subject.newrev).to eq(source_sha) it 'performs a ff_merge' do
expect(subject.repo_created).to be(false) expect(subject.newrev).to eq(source_sha)
expect(subject.branch_created).to be(false) expect(subject.repo_created).to be(false)
expect(subject.branch_created).to be(false)
expect(repository.commit(target_branch).id).to eq(source_sha) expect(repository.commit(target_branch).id).to eq(source_sha)
end end
context 'with a non-existing target branch' do context 'with a non-existing target branch' do
subject { repository.ff_merge(user, source_sha, 'this-isnt-real') } subject { repository.ff_merge(user, source_sha, 'this-isnt-real') }
it 'throws an ArgumentError' do it 'throws an ArgumentError' do
expect { subject }.to raise_error(ArgumentError) expect { subject }.to raise_error(ArgumentError)
end
end end
end
context 'with a non-existing source commit' do context 'with a non-existing source commit' do
let(:source_sha) { 'f001' } let(:source_sha) { 'f001' }
it 'throws an ArgumentError' do it 'throws an ArgumentError' do
expect { subject }.to raise_error(ArgumentError) expect { subject }.to raise_error(ArgumentError)
end
end end
end
context 'when the source sha is not a descendant of the branch head' do context 'when the source sha is not a descendant of the branch head' do
let(:source_sha) { '1a0b36b3cdad1d2ee32457c102a8c0b7056fa863' } let(:source_sha) { '1a0b36b3cdad1d2ee32457c102a8c0b7056fa863' }
it "doesn't perform the ff_merge" do
expect { subject }.to raise_error(Gitlab::Git::CommitError)
expect(repository.commit(target_branch).id).to eq(branch_head)
end
end
end
it "doesn't perform the ff_merge" do context 'with gitaly' do
expect { subject }.to raise_error(Gitlab::Git::CommitError) it "calls Gitaly's OperationService" do
expect_any_instance_of(Gitlab::GitalyClient::OperationService)
.to receive(:user_ff_branch).with(user, source_sha, target_branch)
.and_return(nil)
expect(repository.commit(target_branch).id).to eq(branch_head) subject
end end
it_behaves_like '#ff_merge'
end
context 'without gitaly', :skip_gitaly_mock do
it_behaves_like '#ff_merge'
end end
end end
......
...@@ -89,4 +89,38 @@ describe Gitlab::GitalyClient::OperationService do ...@@ -89,4 +89,38 @@ describe Gitlab::GitalyClient::OperationService do
end end
end end
end end
describe '#user_ff_branch' do
let(:target_branch) { 'my-branch' }
let(:source_sha) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
let(:request) do
Gitaly::UserFFBranchRequest.new(
repository: repository.gitaly_repository,
branch: target_branch,
commit_id: source_sha,
user: gitaly_user
)
end
let(:branch_update) do
Gitaly::OperationBranchUpdate.new(
commit_id: source_sha,
repo_created: false,
branch_created: false
)
end
let(:response) { Gitaly::UserFFBranchResponse.new(branch_update: branch_update) }
subject { client.user_ff_branch(user, source_sha, target_branch) }
it 'sends a user_ff_branch message and returns a BranchUpdate object' do
expect_any_instance_of(Gitaly::OperationService::Stub)
.to receive(:user_ff_branch).with(request, kind_of(Hash))
.and_return(response)
expect(subject).to be_a(Gitlab::Git::OperationService::BranchUpdate)
expect(subject.newrev).to eq(source_sha)
expect(subject.repo_created).to be(false)
expect(subject.branch_created).to be(false)
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