From 2943c1dc071460c3bf8fe6ef023a78bea01b6a12 Mon Sep 17 00:00:00 2001 From: David Aguilar Date: Mon, 29 Jul 2013 15:48:48 -0700 Subject: [PATCH] satellites: fix checkout sequence when merging requests "git checkout -b" will fail when the target branch already exists in the satellite repository, which makes gitlab unable to process merge requests. Use "git update-ref" plumbing command to update the branch pointer and "git symbolic-ref" to change branches. This avoids using the "git checkout" porcelain and is robust to the case where the branch already exists. Use "git reset --hard" and "git clean" to ensure that the state is known before attempting the merge. A previously failed merge may leave behind untracked files, for example, when the .gitignore rules change. Use "--" to separate revspec from pathspec to avoid problems when users have paths in their worktree which are identical to the name of the remote branch. Closes #3697 --- lib/gitlab/satellite/merge_action.rb | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb index 832db6621c4..0876c5d7836 100644 --- a/lib/gitlab/satellite/merge_action.rb +++ b/lib/gitlab/satellite/merge_action.rb @@ -56,10 +56,20 @@ module Gitlab def merge_in_satellite!(repo) prepare_satellite!(repo) - # create target branch in satellite at the corresponding commit from Gitolite - repo.git.checkout({raise: true, timeout: true, b: true}, merge_request.target_branch, "origin/#{merge_request.target_branch}") + # create target branch in satellite at the corresponding commit from Git + repo.git.update_ref({raise: true, timeout: true}, + "refs/heads/#{merge_request.target_branch}", + "origin/#{merge_request.target_branch}") + # switch to the target branch + repo.git.symbolic_ref({raise: true, timeout: true}, + "HEAD", "refs/heads/#{merge_request.target_branch}") + # make the worktree match the git commit + repo.git.reset({raise: true, timeout: true, hard: true}, + "origin/#{merge_request.target_branch}", "--") + # cleanup cruft that may have been left behind + repo.git.clean({raise: true, timeout: true, force: true, x:true, d:true}) - # merge the source branch from Gitolite into the satellite + # merge the source branch from Git into the satellite # will raise CommandFailed when merge fails repo.git.pull({raise: true, timeout: true, no_ff: true}, :origin, merge_request.source_branch) rescue Grit::Git::CommandFailed => ex -- GitLab