diff options
author | Sean McGivern <sean@gitlab.com> | 2016-07-27 19:54:04 +0300 |
---|---|---|
committer | Fatih Acet <acetfatih@gmail.com> | 2016-08-12 23:24:43 +0300 |
commit | 14a4b17d1c8a43c77b0459fd543be36838031610 (patch) | |
tree | d47104567085d3d711976eb299875f5e1aab0d24 /lib/gitlab/conflict | |
parent | a1c79612172ce07c7b0de4c01fba8fa7369c71de (diff) |
Allow resolving conflicts in MR controller
Diffstat (limited to 'lib/gitlab/conflict')
-rw-r--r-- | lib/gitlab/conflict/file.rb | 44 | ||||
-rw-r--r-- | lib/gitlab/conflict/file_collection.rb | 20 |
2 files changed, 63 insertions, 1 deletions
diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index 7f81c72431d..80f6f7feecf 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -1,6 +1,9 @@ module Gitlab module Conflict class File + class MissingResolution < StandardError + end + CONTEXT_LINES = 3 attr_reader :merge_file_result, :their_path, :their_ref, :our_path, :our_ref, :repository @@ -21,6 +24,39 @@ module Gitlab their_path: their_path) end + def resolve!(resolution, index:, rugged:) + new_file = resolve_lines(resolution).map(&:text).join("\n") + + oid = rugged.write(new_file, :blob) + our_mode = index.conflict_get(our_path)[:ours][:mode] + index.add(path: our_path, oid: oid, mode: our_mode) + index.conflict_remove(our_path) + end + + def resolve_lines(resolution) + current_section = nil + + lines.map do |line| + unless line.type + current_section = nil + next line + end + + current_section ||= resolution[line_code(line)] + + case current_section + when 'ours' + next unless line.type == 'new' + when 'theirs' + next unless line.type == 'old' + else + raise MissingResolution + end + + line + end.compact + end + def highlighted_lines return @highlighted_lines if @highlighted_lines @@ -77,10 +113,16 @@ module Gitlab match_line.text = "@@ -#{match_line.old_pos},#{lines.last.old_pos} +#{match_line.new_pos},#{lines.last.new_pos} @@" end - section || { conflict: !no_conflict, lines: lines } + section ||= { conflict: !no_conflict, lines: lines } + section[:id] = line_code(lines.first) unless no_conflict + section end end + def line_code(line) + Gitlab::Diff::LineCode.generate(our_path, line.new_pos, line.old_pos) + end + def as_json(opts = nil) { old_path: their_path, diff --git a/lib/gitlab/conflict/file_collection.rb b/lib/gitlab/conflict/file_collection.rb index a3035a5c3e6..a4a1505bb7d 100644 --- a/lib/gitlab/conflict/file_collection.rb +++ b/lib/gitlab/conflict/file_collection.rb @@ -17,6 +17,26 @@ module Gitlab @merge_index ||= repository.rugged.merge_commits(our_commit, their_commit) end + def resolve_conflicts!(resolutions, commit_message, user:) + rugged = repository.rugged + committer = repository.user_to_committer(user) + commit_message ||= default_commit_message + + files.each do |file| + file.resolve!(resolutions, index: merge_index, rugged: rugged) + end + + new_tree = merge_index.write_tree(rugged) + + Rugged::Commit.create(rugged, + author: committer, + committer: committer, + tree: new_tree, + message: commit_message, + parents: [our_commit, their_commit], + update_ref: Gitlab::Git::BRANCH_REF_PREFIX + merge_request.source_branch) + end + def files @files ||= merge_index.conflicts.map do |conflict| their_path = conflict[:theirs][:path] |