From 74d435c6b7e771c5e03b8f3cd603ffd262055363 Mon Sep 17 00:00:00 2001 From: Valery Sizov Date: Tue, 19 Sep 2017 20:37:56 +0300 Subject: [PATCH] Using worktrees and git operations service to update ref after rebasing --- app/services/merge_requests/rebase_service.rb | 22 +++++++++---------- .../rebase_using_custom_worktree.yml | 5 +++++ lib/gitlab/git/operation_service.rb | 5 +++++ .../merge_requests/rebase_service_spec.rb | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) create mode 100644 changelogs/unreleased-ee/rebase_using_custom_worktree.yml diff --git a/app/services/merge_requests/rebase_service.rb b/app/services/merge_requests/rebase_service.rb index 4a69ed5876cf2f..1bd7253bdf501b 100644 --- a/app/services/merge_requests/rebase_service.rb +++ b/app/services/merge_requests/rebase_service.rb @@ -17,14 +17,14 @@ def rebase end run_git_command( - %W(clone -b #{merge_request.source_branch} -- #{source_project.repository.path_to_repo} #{tree_path}), - nil, + %W(worktree add --detach #{tree_path} #{merge_request.source_branch}), + repository.path_to_repo, git_env, - 'clone repository for rebase' + 'add worktree for rebase' ) run_git_command( - %W(pull --rebase #{target_project.repository.path_to_repo} #{merge_request.target_branch}), + %W(rebase #{merge_request.target_branch}), tree_path, git_env.merge('GIT_COMMITTER_NAME' => current_user.name, 'GIT_COMMITTER_EMAIL' => current_user.email), @@ -32,20 +32,16 @@ def rebase ) rebase_sha = run_git_command( - %W(rev-parse #{merge_request.source_branch}), + %w(rev-parse HEAD), tree_path, git_env, 'get SHA of rebased branch' ) - merge_request.update_attributes(rebase_commit_sha: rebase_sha) + Gitlab::Git::OperationService.new(current_user, project.repository.raw_repository) + .update_branch(merge_request.source_branch, rebase_sha, merge_request.source_branch_sha) - run_git_command( - %W(push -f origin #{merge_request.source_branch}), - tree_path, - git_env, - 'push rebased branch' - ) + merge_request.update_attributes(rebase_commit_sha: rebase_sha) true rescue GitCommandError @@ -58,6 +54,8 @@ def rebase clean_dir end + private + def tree_path @tree_path ||= merge_request.rebase_dir_path end diff --git a/changelogs/unreleased-ee/rebase_using_custom_worktree.yml b/changelogs/unreleased-ee/rebase_using_custom_worktree.yml new file mode 100644 index 00000000000000..5be1ea3c047f72 --- /dev/null +++ b/changelogs/unreleased-ee/rebase_using_custom_worktree.yml @@ -0,0 +1,5 @@ +--- +title: Improve performance of rebasing by using worktree +merge_request: +author: +type: changed diff --git a/lib/gitlab/git/operation_service.rb b/lib/gitlab/git/operation_service.rb index d835dcca8ba786..38c275d1e7f622 100644 --- a/lib/gitlab/git/operation_service.rb +++ b/lib/gitlab/git/operation_service.rb @@ -91,6 +91,11 @@ def with_branch( end end + def update_branch(branch_name, newrev, oldrev) + ref = Gitlab::Git::BRANCH_REF_PREFIX + branch_name + update_ref_in_hooks(ref, newrev, oldrev) + end + private # Returns [newrev, should_run_after_create, should_run_after_create_branch] diff --git a/spec/services/merge_requests/rebase_service_spec.rb b/spec/services/merge_requests/rebase_service_spec.rb index 6fd8c07abceeaf..ed475ffc95b6f7 100644 --- a/spec/services/merge_requests/rebase_service_spec.rb +++ b/spec/services/merge_requests/rebase_service_spec.rb @@ -95,7 +95,7 @@ context 'git commands' do it 'sets GL_REPOSITORY env variable when calling git commands' do expect_any_instance_of(described_class) - .to receive(:run_git_command).exactly(4).with( + .to receive(:run_git_command).exactly(3).with( anything, anything, hash_including('GL_REPOSITORY'), -- GitLab