diff options
author | Douwe Maan <douwe@gitlab.com> | 2016-08-30 18:59:10 +0300 |
---|---|---|
committer | Douwe Maan <douwe@gitlab.com> | 2016-08-30 18:59:10 +0300 |
commit | b2e23e33b3205321a7a95b3042313b2438d8b3fc (patch) | |
tree | f4076cebe6fe2d11819818f787ab5af14443a770 /app | |
parent | 924fdf4a841731e9ff74eb3da15290b7745da029 (diff) | |
parent | 59dd9e576bd62f9311316ca31ecaba8ddde50b00 (diff) |
Merge branch '21459-resolving-merge-conflicts-from-a-forked-repo-through-ui' into 'master'
Fix resolving conflicts on forks
## What does this MR do?
When we resolve conflicts, we create a merge commit in the source branch with parents `[source_branch_head, target_branch_head]`. But when the MR is from a fork, `target_branch_head` might not exist in the source repo at all, so we need to fetch it if it isn't there. We can do this locally so it should be fast.
## Are there points in the code the reviewer needs to double check?
The `TestEnv` changes are needed to reset the branch refs if we're reusing a git directory locally - otherwise, there might not be conflicts!
## Why was this MR needed?
It's a bug in a new feature!
## Does this MR meet the acceptance criteria?
- [x] [CHANGELOG](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CHANGELOG) entry added
- Tests
- [x] Added for this feature/bug
- [x] All builds are passing
- [x] Conform by the [style guides](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md#style-guides)
- [x] Branch has no merge conflicts with `master` (if you do - rebase it please)
- [x] [Squashed related commits together](https://git-scm.com/book/en/Git-Tools-Rewriting-History#Squashing-Commits)
## What are the relevant issue numbers?
Closes #21459.
See merge request !6082
Diffstat (limited to 'app')
-rw-r--r-- | app/services/merge_requests/resolve_service.rb | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/app/services/merge_requests/resolve_service.rb b/app/services/merge_requests/resolve_service.rb index adc71b0c2bc..19caa038c44 100644 --- a/app/services/merge_requests/resolve_service.rb +++ b/app/services/merge_requests/resolve_service.rb @@ -1,11 +1,14 @@ module MergeRequests class ResolveService < MergeRequests::BaseService - attr_accessor :conflicts, :rugged, :merge_index + attr_accessor :conflicts, :rugged, :merge_index, :merge_request def execute(merge_request) @conflicts = merge_request.conflicts @rugged = project.repository.rugged @merge_index = conflicts.merge_index + @merge_request = merge_request + + fetch_their_commit! conflicts.files.each do |file| write_resolved_file_to_index(file, params[:sections]) @@ -27,5 +30,21 @@ module MergeRequests merge_index.add(path: our_path, oid: rugged.write(new_file, :blob), mode: file.our_mode) merge_index.conflict_remove(our_path) end + + # If their commit (in the target project) doesn't exist in the source project, it + # can't be a parent for the merge commit we're about to create. If that's the case, + # fetch the target branch ref into the source project so the commit exists in both. + # + def fetch_their_commit! + return if rugged.include?(conflicts.their_commit.oid) + + random_string = SecureRandom.hex + + project.repository.fetch_ref( + merge_request.target_project.repository.path_to_repo, + "refs/heads/#{merge_request.target_branch}", + "refs/tmp/#{random_string}/head" + ) + end end end |