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 @@ def fsck
end
def 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
gitaly_migrate(:rebase) do |is_enabled|
if is_enabled
gitaly_rebase(user, rebase_id,
branch: branch,
branch_sha: branch_sha,
remote_repository: remote_repository,
remote_branch: remote_branch)
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
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
......@@ -2039,6 +2031,40 @@ def check_cherry_pick_content(target_commit, source_sha)
tree_id
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:)
args = %W(fetch --no-tags -f #{source_path} #{source_ref}:#{target_ref})
run_git(args)
......
......@@ -147,6 +147,34 @@ def user_revert(user:, commit:, branch_name:, message:, start_branch_name:, star
start_repository: start_repository)
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
def call_cherry_pick_or_revert(rpc, user:, commit:, branch_name:, message:, start_branch_name:, start_repository:)
......
......@@ -36,7 +36,7 @@
end
end
context 'when unexpected error occurs' do
context 'when unexpected error occurs', :disable_gitaly do
before do
allow(repository).to receive(:run_git!).and_raise('Something went wrong')
end
......@@ -53,7 +53,7 @@
end
end
context 'with git command failure' do
context 'with git command failure', :disable_gitaly do
before do
allow(repository).to receive(:run_git!).and_raise(Gitlab::Git::Repository::GitError, 'Something went wrong')
end
......@@ -71,6 +71,7 @@
end
context 'valid params' do
shared_examples 'successful rebase' do
before do
service.execute(merge_request)
end
......@@ -94,8 +95,17 @@
expect(head_commit.committer_email).to eq(user.email)
expect(head_commit.committer_name).to eq(user.name)
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
expect(repository).to receive(:popen).exactly(3)
.with(anything, anything, hash_including('GL_REPOSITORY'))
......@@ -106,6 +116,7 @@
end
context 'fork' do
shared_examples 'successful fork rebase' do
let(:forked_project) do
fork_project(project, user, repository: true)
end
......@@ -129,6 +140,15 @@
expect(parent_sha).to eq(target_branch_sha)
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
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