Commit 58724265 authored by Robert Speicher's avatar Robert Speicher

Merge branch 'feature/migrate-rebase-to-gitaly' into 'master'

Migrate Gitlab::Git::Repository#rebase to Gitaly

Closes gitaly#863

See merge request gitlab-org/gitlab-ce!16259
parents b384d478 42265d44
...@@ -1236,28 +1236,20 @@ module Gitlab ...@@ -1236,28 +1236,20 @@ module Gitlab
end end
def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:) def rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:)
rebase_path = worktree_path(REBASE_WORKTREE_PREFIX, rebase_id) gitaly_migrate(:rebase) do |is_enabled|
env = git_env_for_user(user) if is_enabled
gitaly_rebase(user, rebase_id,
if remote_repository.is_a?(RemoteRepository) branch: branch,
env.merge!(remote_repository.fetch_env) branch_sha: branch_sha,
remote_repo_path = GITALY_INTERNAL_URL remote_repository: remote_repository,
remote_branch: remote_branch)
else else
remote_repo_path = remote_repository.path git_rebase(user, rebase_id,
branch: branch,
branch_sha: branch_sha,
remote_repository: remote_repository,
remote_branch: remote_branch)
end end
with_worktree(rebase_path, branch, env: env) do
run_git!(
%W(pull --rebase #{remote_repo_path} #{remote_branch}),
chdir: rebase_path, env: env
)
rebase_sha = run_git!(%w(rev-parse HEAD), chdir: rebase_path, env: env).strip
Gitlab::Git::OperationService.new(user, self)
.update_branch(branch, rebase_sha, branch_sha)
rebase_sha
end end
end end
...@@ -2039,6 +2031,40 @@ module Gitlab ...@@ -2039,6 +2031,40 @@ module Gitlab
tree_id tree_id
end end
def gitaly_rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:)
gitaly_operation_client.user_rebase(user, rebase_id,
branch: branch,
branch_sha: branch_sha,
remote_repository: remote_repository,
remote_branch: remote_branch)
end
def git_rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:)
rebase_path = worktree_path(REBASE_WORKTREE_PREFIX, rebase_id)
env = git_env_for_user(user)
if remote_repository.is_a?(RemoteRepository)
env.merge!(remote_repository.fetch_env)
remote_repo_path = GITALY_INTERNAL_URL
else
remote_repo_path = remote_repository.path
end
with_worktree(rebase_path, branch, env: env) do
run_git!(
%W(pull --rebase #{remote_repo_path} #{remote_branch}),
chdir: rebase_path, env: env
)
rebase_sha = run_git!(%w(rev-parse HEAD), chdir: rebase_path, env: env).strip
Gitlab::Git::OperationService.new(user, self)
.update_branch(branch, rebase_sha, branch_sha)
rebase_sha
end
end
def local_fetch_ref(source_path, source_ref:, target_ref:) def local_fetch_ref(source_path, source_ref:, target_ref:)
args = %W(fetch --no-tags -f #{source_path} #{source_ref}:#{target_ref}) args = %W(fetch --no-tags -f #{source_path} #{source_ref}:#{target_ref})
run_git(args) run_git(args)
......
...@@ -147,6 +147,34 @@ module Gitlab ...@@ -147,6 +147,34 @@ module Gitlab
start_repository: start_repository) start_repository: start_repository)
end end
def user_rebase(user, rebase_id, branch:, branch_sha:, remote_repository:, remote_branch:)
request = Gitaly::UserRebaseRequest.new(
repository: @gitaly_repo,
user: Gitlab::Git::User.from_gitlab(user).to_gitaly,
rebase_id: rebase_id.to_s,
branch: encode_binary(branch),
branch_sha: branch_sha,
remote_repository: remote_repository.gitaly_repository,
remote_branch: encode_binary(remote_branch)
)
response = GitalyClient.call(
@repository.storage,
:operation_service,
:user_rebase,
request,
remote_storage: remote_repository.storage
)
if response.pre_receive_error.presence
raise Gitlab::Git::HooksService::PreReceiveError, response.pre_receive_error
elsif response.git_error.presence
raise Gitlab::Git::Repository::GitError, response.git_error
else
response.rebase_sha
end
end
private private
def call_cherry_pick_or_revert(rpc, user:, commit:, branch_name:, message:, start_branch_name:, start_repository:) def call_cherry_pick_or_revert(rpc, user:, commit:, branch_name:, message:, start_branch_name:, start_repository:)
......
...@@ -36,7 +36,7 @@ describe MergeRequests::RebaseService do ...@@ -36,7 +36,7 @@ describe MergeRequests::RebaseService do
end end
end end
context 'when unexpected error occurs' do context 'when unexpected error occurs', :disable_gitaly do
before do before do
allow(repository).to receive(:run_git!).and_raise('Something went wrong') allow(repository).to receive(:run_git!).and_raise('Something went wrong')
end end
...@@ -53,7 +53,7 @@ describe MergeRequests::RebaseService do ...@@ -53,7 +53,7 @@ describe MergeRequests::RebaseService do
end end
end end
context 'with git command failure' do context 'with git command failure', :disable_gitaly do
before do before do
allow(repository).to receive(:run_git!).and_raise(Gitlab::Git::Repository::GitError, 'Something went wrong') allow(repository).to receive(:run_git!).and_raise(Gitlab::Git::Repository::GitError, 'Something went wrong')
end end
...@@ -71,6 +71,7 @@ describe MergeRequests::RebaseService do ...@@ -71,6 +71,7 @@ describe MergeRequests::RebaseService do
end end
context 'valid params' do context 'valid params' do
shared_examples 'successful rebase' do
before do before do
service.execute(merge_request) service.execute(merge_request)
end end
...@@ -94,8 +95,17 @@ describe MergeRequests::RebaseService do ...@@ -94,8 +95,17 @@ describe MergeRequests::RebaseService do
expect(head_commit.committer_email).to eq(user.email) expect(head_commit.committer_email).to eq(user.email)
expect(head_commit.committer_name).to eq(user.name) expect(head_commit.committer_name).to eq(user.name)
end end
end
context 'when Gitaly rebase feature is enabled' do
it_behaves_like 'successful rebase'
end
context 'when Gitaly rebase feature is disabled', :disable_gitaly do
it_behaves_like 'successful rebase'
end
context 'git commands' do context 'git commands', :disable_gitaly do
it 'sets GL_REPOSITORY env variable when calling git commands' do it 'sets GL_REPOSITORY env variable when calling git commands' do
expect(repository).to receive(:popen).exactly(3) expect(repository).to receive(:popen).exactly(3)
.with(anything, anything, hash_including('GL_REPOSITORY')) .with(anything, anything, hash_including('GL_REPOSITORY'))
...@@ -106,6 +116,7 @@ describe MergeRequests::RebaseService do ...@@ -106,6 +116,7 @@ describe MergeRequests::RebaseService do
end end
context 'fork' do context 'fork' do
shared_examples 'successful fork rebase' do
let(:forked_project) do let(:forked_project) do
fork_project(project, user, repository: true) fork_project(project, user, repository: true)
end end
...@@ -129,6 +140,15 @@ describe MergeRequests::RebaseService do ...@@ -129,6 +140,15 @@ describe MergeRequests::RebaseService do
expect(parent_sha).to eq(target_branch_sha) expect(parent_sha).to eq(target_branch_sha)
end end
end end
context 'when Gitaly rebase feature is enabled' do
it_behaves_like 'successful fork rebase'
end
context 'when Gitaly rebase feature is disabled', :disable_gitaly do
it_behaves_like 'successful fork rebase'
end
end
end end
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