BigW Consortium Gitlab

Commit faa9bd40 by Alejandro Rodríguez

Create a Gitlab::Git submodule for conlict-related files

Rename classes to (hopefully) clearer names while we're doing that.
parent 3fcab51e
...@@ -53,7 +53,7 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap ...@@ -53,7 +53,7 @@ class Projects::MergeRequests::ConflictsController < Projects::MergeRequests::Ap
flash[:notice] = 'All merge conflicts were resolved. The merge request can now be merged.' flash[:notice] = 'All merge conflicts were resolved. The merge request can now be merged.'
render json: { redirect_to: project_merge_request_url(@project, @merge_request, resolved_conflicts: true) } render json: { redirect_to: project_merge_request_url(@project, @merge_request, resolved_conflicts: true) }
rescue Gitlab::Git::Merge::ResolutionError => e rescue Gitlab::Git::Conflict::Resolver::ResolutionError => e
render status: :bad_request, json: { message: e.message } render status: :bad_request, json: { message: e.message }
end end
end end
......
...@@ -23,7 +23,7 @@ module MergeRequests ...@@ -23,7 +23,7 @@ module MergeRequests
# when there are no conflict files. # when there are no conflict files.
conflicts.files.each(&:lines) conflicts.files.each(&:lines)
@conflicts_can_be_resolved_in_ui = conflicts.files.length > 0 @conflicts_can_be_resolved_in_ui = conflicts.files.length > 0
rescue Rugged::OdbError, Gitlab::Git::ConflictParser::UnresolvableError, Gitlab::Git::Merge::ConflictSideMissing rescue Rugged::OdbError, Gitlab::Git::Conflict::Parser::UnresolvableError, Gitlab::Git::Conflict::Resolver::ConflictSideMissing
@conflicts_can_be_resolved_in_ui = false @conflicts_can_be_resolved_in_ui = false
end end
end end
......
...@@ -186,7 +186,7 @@ module API ...@@ -186,7 +186,7 @@ module API
lines.each do |line| lines.each do |line|
next unless line.new_pos == params[:line] && line.type == params[:line_type] next unless line.new_pos == params[:line] && line.type == params[:line_type]
break opts[:line_code] = Gitlab::Git::DiffLineCode.generate(diff.new_path, line.new_pos, line.old_pos) break opts[:line_code] = Gitlab::Git::Conflict::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
end end
break if opts[:line_code] break if opts[:line_code]
......
...@@ -173,7 +173,7 @@ module API ...@@ -173,7 +173,7 @@ module API
lines.each do |line| lines.each do |line|
next unless line.new_pos == params[:line] && line.type == params[:line_type] next unless line.new_pos == params[:line] && line.type == params[:line_type]
break opts[:line_code] = Gitlab::Git::DiffLineCode.generate(diff.new_path, line.new_pos, line.old_pos) break opts[:line_code] = Gitlab::Git::Conflict::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
end end
break if opts[:line_code] break if opts[:line_code]
......
...@@ -23,7 +23,7 @@ module Github ...@@ -23,7 +23,7 @@ module Github
private private
def generate_line_code(line) def generate_line_code(line)
Gitlab::Git::DiffLineCode.generate(file_path, line.new_pos, line.old_pos) Gitlab::Git::Conflict::LineCode.generate(file_path, line.new_pos, line.old_pos)
end end
def on_diff? def on_diff?
......
...@@ -241,7 +241,7 @@ module Gitlab ...@@ -241,7 +241,7 @@ module Gitlab
end end
def generate_line_code(pr_comment) def generate_line_code(pr_comment)
Gitlab::Git::DiffLineCode.generate(pr_comment.file_path, pr_comment.new_pos, pr_comment.old_pos) Gitlab::Git::Conflict::LineCode.generate(pr_comment.file_path, pr_comment.new_pos, pr_comment.old_pos)
end end
def pull_request_comment_attributes(comment) def pull_request_comment_attributes(comment)
......
...@@ -6,7 +6,10 @@ module Gitlab ...@@ -6,7 +6,10 @@ module Gitlab
CONTEXT_LINES = 3 CONTEXT_LINES = 3
attr_reader :merge_request, :raw attr_reader :merge_request
# 'raw' holds the Gitlab::Git::Conflict::File that this instance wraps
attr_reader :raw
delegate :type, :content, :their_path, :our_path, :our_mode, :our_blob, :repository, to: :raw delegate :type, :content, :their_path, :our_path, :our_mode, :our_blob, :repository, to: :raw
...@@ -107,7 +110,7 @@ module Gitlab ...@@ -107,7 +110,7 @@ module Gitlab
end end
def line_code(line) def line_code(line)
Gitlab::Git::DiffLineCode.generate(our_path, line.new_pos, line.old_pos) Gitlab::Git::Conflict::LineCode.generate(our_path, line.new_pos, line.old_pos)
end end
def create_match_line(line) def create_match_line(line)
......
module Gitlab module Gitlab
module Conflict module Conflict
class FileCollection class FileCollection
attr_reader :merge_request, :merge attr_reader :merge_request, :resolver
def initialize(merge_request) def initialize(merge_request)
source_repo = merge_request.source_project.repository.raw source_repo = merge_request.source_project.repository.raw
our_commit = merge_request.source_branch_head.raw our_commit = merge_request.source_branch_head.raw
their_commit = merge_request.target_branch_head.raw their_commit = merge_request.target_branch_head.raw
target_repo = merge_request.target_project.repository.raw target_repo = merge_request.target_project.repository.raw
@merge = Gitlab::Git::Merge.new(source_repo, our_commit, target_repo, their_commit) @resolver = Gitlab::Git::Conflict::Resolver.new(source_repo, our_commit, target_repo, their_commit)
@merge_request = merge_request @merge_request = merge_request
end end
...@@ -18,11 +18,11 @@ module Gitlab ...@@ -18,11 +18,11 @@ module Gitlab
target_branch: merge_request.target_branch, target_branch: merge_request.target_branch,
commit_message: commit_message || default_commit_message commit_message: commit_message || default_commit_message
} }
merge.resolve_conflicts(user, files, args) resolver.resolve_conflicts(user, files, args)
end end
def files def files
@files ||= merge.conflicts.map do |conflict_file| @files ||= resolver.conflicts.map do |conflict_file|
Gitlab::Conflict::File.new(conflict_file, merge_request: merge_request) Gitlab::Conflict::File.new(conflict_file, merge_request: merge_request)
end end
end end
......
...@@ -49,7 +49,7 @@ module Gitlab ...@@ -49,7 +49,7 @@ module Gitlab
def line_code(line) def line_code(line)
return if line.meta? return if line.meta?
Gitlab::Git::DiffLineCode.generate(file_path, line.new_pos, line.old_pos) Gitlab::Git::Conflict::LineCode.generate(file_path, line.new_pos, line.old_pos)
end end
def line_for_line_code(code) def line_for_line_code(code)
......
module Gitlab module Gitlab
module Git module Git
class ConflictFile module Conflict
attr_reader :content, :their_path, :our_path, :our_mode, :repository class File
attr_reader :content, :their_path, :our_path, :our_mode, :repository
def initialize(repository, commit_oid, conflict, content) def initialize(repository, commit_oid, conflict, content)
@repository = repository @repository = repository
@commit_oid = commit_oid @commit_oid = commit_oid
@their_path = conflict[:theirs][:path] @their_path = conflict[:theirs][:path]
@our_path = conflict[:ours][:path] @our_path = conflict[:ours][:path]
@our_mode = conflict[:ours][:mode] @our_mode = conflict[:ours][:mode]
@content = content @content = content
end end
def lines def lines
return @lines if defined?(@lines) return @lines if defined?(@lines)
begin begin
@type = 'text' @type = 'text'
@lines = Gitlab::Git::ConflictParser.parse(content, @lines = Gitlab::Git::Conflict::Parser.parse(content,
our_path: our_path, our_path: our_path,
their_path: their_path) their_path: their_path)
rescue Gitlab::Git::ConflictParser::ParserError rescue Gitlab::Git::Conflict::Parser::ParserError
@type = 'text-editor' @type = 'text-editor'
@lines = nil @lines = nil
end
end end
end
def type def type
lines unless @type lines unless @type
@type.inquiry @type.inquiry
end end
def our_blob
# REFACTOR NOTE: the source of `commit_oid` used to be
# `merge_request.diff_refs.head_sha`. Instead of passing this value
# around the new lib structure, I decided to use `@commit_oid` which is
# equivalent to `merge_request.source_branch_head.raw.rugged_commit.oid`.
# That is what `merge_request.diff_refs.head_sha` is equivalent to when
# `merge_request` is not persisted (see `MergeRequest#diff_head_commit`).
# I think using the same oid is more consistent anyways, but if Conflicts
# start breaking, the change described above is a good place to look at.
@our_blob ||= repository.blob_at(@commit_oid, our_path)
end
def line_code(line) def our_blob
Gitlab::Git::DiffLineCode.generate(our_path, line[:line_new], line[:line_old]) # REFACTOR NOTE: the source of `commit_oid` used to be
end # `merge_request.diff_refs.head_sha`. Instead of passing this value
# around the new lib structure, I decided to use `@commit_oid` which is
# equivalent to `merge_request.source_branch_head.raw.rugged_commit.oid`.
# That is what `merge_request.diff_refs.head_sha` is equivalent to when
# `merge_request` is not persisted (see `MergeRequest#diff_head_commit`).
# I think using the same oid is more consistent anyways, but if Conflicts
# start breaking, the change described above is a good place to look at.
@our_blob ||= repository.blob_at(@commit_oid, our_path)
end
def resolve_lines(resolution) def line_code(line)
section_id = nil Gitlab::Git::Conflict::LineCode.generate(our_path, line[:line_new], line[:line_old])
end
lines.map do |line| def resolve_lines(resolution)
unless line[:type] section_id = nil
section_id = nil
next line
end
section_id ||= line_code(line) lines.map do |line|
unless line[:type]
section_id = nil
next line
end
case resolution[section_id] section_id ||= line_code(line)
when 'head'
next unless line[:type] == 'new'
when 'origin'
next unless line[:type] == 'old'
else
raise Gitlab::Git::Merge::ResolutionError, "Missing resolution for section ID: #{section_id}"
end
line case resolution[section_id]
end.compact when 'head'
end next unless line[:type] == 'new'
when 'origin'
next unless line[:type] == 'old'
else
raise Gitlab::Git::Conflict::Resolver::ResolutionError, "Missing resolution for section ID: #{section_id}"
end
def resolve_content(resolution) line
if resolution == content end.compact
raise Gitlab::Git::Merge::ResolutionError, "Resolved content has no changes for file #{our_path}"
end end
resolution def resolve_content(resolution)
if resolution == content
raise Gitlab::Git::Conflict::Resolver::ResolutionError, "Resolved content has no changes for file #{our_path}"
end
resolution
end
end end
end end
end end
......
module Gitlab module Gitlab
module Git module Git
class DiffLineCode module Conflict
def self.generate(file_path, new_line_position, old_line_position) class LineCode
"#{Digest::SHA1.hexdigest(file_path)}_#{old_line_position}_#{new_line_position}" def self.generate(file_path, new_line_position, old_line_position)
"#{Digest::SHA1.hexdigest(file_path)}_#{old_line_position}_#{new_line_position}"
end
end end
end end
end end
......
module Gitlab module Gitlab
module Git module Git
class ConflictParser module Conflict
UnresolvableError = Class.new(StandardError) class Parser
UnmergeableFile = Class.new(UnresolvableError) UnresolvableError = Class.new(StandardError)
UnsupportedEncoding = Class.new(UnresolvableError) UnmergeableFile = Class.new(UnresolvableError)
UnsupportedEncoding = Class.new(UnresolvableError)
# Recoverable errors - the conflict can be resolved in an editor, but not with
# sections. # Recoverable errors - the conflict can be resolved in an editor, but not with
ParserError = Class.new(StandardError) # sections.
UnexpectedDelimiter = Class.new(ParserError) ParserError = Class.new(StandardError)
MissingEndDelimiter = Class.new(ParserError) UnexpectedDelimiter = Class.new(ParserError)
MissingEndDelimiter = Class.new(ParserError)
class << self
def parse(text, our_path:, their_path:, parent_file: nil) class << self
validate_text!(text) def parse(text, our_path:, their_path:, parent_file: nil)
validate_text!(text)
line_obj_index = 0
line_old = 1 line_obj_index = 0
line_new = 1 line_old = 1
type = nil line_new = 1
lines = [] type = nil
conflict_start = "<<<<<<< #{our_path}" lines = []
conflict_middle = '=======' conflict_start = "<<<<<<< #{our_path}"
conflict_end = ">>>>>>> #{their_path}" conflict_middle = '======='
conflict_end = ">>>>>>> #{their_path}"
text.each_line.map do |line|
full_line = line.delete("\n") text.each_line.map do |line|
full_line = line.delete("\n")
if full_line == conflict_start
validate_delimiter!(type.nil?) if full_line == conflict_start
validate_delimiter!(type.nil?)
type = 'new'
elsif full_line == conflict_middle type = 'new'
validate_delimiter!(type == 'new') elsif full_line == conflict_middle
validate_delimiter!(type == 'new')
type = 'old'
elsif full_line == conflict_end type = 'old'
validate_delimiter!(type == 'old') elsif full_line == conflict_end
validate_delimiter!(type == 'old')
type = nil
elsif line[0] == '\\' type = nil
type = 'nonewline' elsif line[0] == '\\'
lines << { type = 'nonewline'
full_line: full_line, lines << {
type: type, full_line: full_line,
line_obj_index: line_obj_index, type: type,
line_old: line_old, line_obj_index: line_obj_index,
line_new: line_new line_old: line_old,
} line_new: line_new
else }
lines << { else
full_line: full_line, lines << {
type: type, full_line: full_line,
line_obj_index: line_obj_index, type: type,
line_old: line_old, line_obj_index: line_obj_index,
line_new: line_new line_old: line_old,
} line_new: line_new
}
line_old += 1 if type != 'new'
line_new += 1 if type != 'old' line_old += 1 if type != 'new'
line_new += 1 if type != 'old'
line_obj_index += 1
line_obj_index += 1
end
end end
end
raise MissingEndDelimiter unless type.nil? raise MissingEndDelimiter unless type.nil?
lines lines
end end
private private
def validate_text!(text) def validate_text!(text)
raise UnmergeableFile if text.blank? # Typically a binary file raise UnmergeableFile if text.blank? # Typically a binary file
raise UnmergeableFile if text.length > 200.kilobytes raise UnmergeableFile if text.length > 200.kilobytes
text.force_encoding('UTF-8') text.force_encoding('UTF-8')
raise UnsupportedEncoding unless text.valid_encoding? raise UnsupportedEncoding unless text.valid_encoding?
end end
def validate_delimiter!(condition) def validate_delimiter!(condition)
raise UnexpectedDelimiter unless condition raise UnexpectedDelimiter unless condition
end
end end
end end
end end
......
module Gitlab module Gitlab
module Git module Git
class Merge module Conflict
ConflictSideMissing = Class.new(StandardError) class Resolver
ResolutionError = Class.new(StandardError) ConflictSideMissing = Class.new(StandardError)
ResolutionError = Class.new(StandardError)
def initialize(repository, our_commit, target_repository, their_commit)
@repository = repository def initialize(repository, our_commit, target_repository, their_commit)
@our_commit = our_commit.rugged_commit @repository = repository
@target_repository = target_repository @our_commit = our_commit.rugged_commit
@their_commit = their_commit.rugged_commit @target_repository = target_repository
end @their_commit = their_commit.rugged_commit
end
def conflicts def conflicts
@conflicts ||= begin @conflicts ||= begin
target_index = @target_repository.rugged.merge_commits(@our_commit, @their_commit) target_index = @target_repository.rugged.merge_commits(@our_commit, @their_commit)
# We don't need to do `with_repo_branch_commit` here, because the target # We don't need to do `with_repo_branch_commit` here, because the target
# project always fetches source refs when creating merge request diffs. # project always fetches source refs when creating merge request diffs.
target_index.conflicts.map do |conflict| target_index.conflicts.map do |conflict|
raise ConflictSideMissing unless conflict[:theirs] && conflict[:ours] raise ConflictSideMissing unless conflict[:theirs] && conflict[:ours]
Gitlab::Git::ConflictFile.new( Gitlab::Git::Conflict::File.new(
@target_repository, @target_repository,
@our_commit.oid, @our_commit.oid,
conflict, conflict,
target_index.merge_file(conflict[:ours][:path])[:data] target_index.merge_file(conflict[:ours][:path])[:data]
) )
end
end end
end end
end
def resolve_conflicts(user, files, source_branch:, target_branch:, commit_message:) def resolve_conflicts(user, files, source_branch:, target_branch:, commit_message:)
@repository.with_repo_branch_commit(@target_repository, target_branch) do @repository.with_repo_branch_commit(@target_repository, target_branch) do
files.each do |file_params| files.each do |file_params|
conflict_file = conflict_for_path(file_params[:old_path], file_params[:new_path]) conflict_file = conflict_for_path(file_params[:old_path], file_params[:new_path])
write_resolved_file_to_index(conflict_file, file_params) write_resolved_file_to_index(conflict_file, file_params)
end end
unless index.conflicts.empty? unless index.conflicts.empty?
missing_files = index.conflicts.map { |file| file[:ours][:path] } missing_files = index.conflicts.map { |file| file[:ours][:path] }
raise ResolutionError, "Missing resolutions for the following files: #{missing_files.join(', ')}" raise ResolutionError, "Missing resolutions for the following files: #{missing_files.join(', ')}"
end end
commit_params = { commit_params = {
message: commit_message, message: commit_message,
parents: [@our_commit, @their_commit].map(&:oid) parents: [@our_commit, @their_commit].map(&:oid)
} }
@repository.commit_index(user, source_branch, index, commit_params) @repository.commit_index(user, source_branch, index, commit_params)
end
end end
end
def conflict_for_path(old_path, new_path) def conflict_for_path(old_path, new_path)
conflicts.find do |conflict| conflicts.find do |conflict|
conflict.their_path == old_path && conflict.our_path == new_path conflict.their_path == old_path && conflict.our_path == new_path
end
end end
end
private private
# We can only write when getting the merge index from the source # We can only write when getting the merge index from the source
# project, because we will write to that project. We don't use this all # project, because we will write to that project. We don't use this all
# the time because this fetches a ref into the source project, which # the time because this fetches a ref into the source project, which
# isn't needed for reading. # isn't needed for reading.
def index def index
@index ||= @repository.rugged.merge_commits(@our_commit, @their_commit) @index ||= @repository.rugged.merge_commits(@our_commit, @their_commit)
end end
def write_resolved_file_to_index(file, params) def write_resolved_file_to_index(file, params)
if params[:sections] if params[:sections]
resolved_lines = file.resolve_lines(params[:sections]) resolved_lines = file.resolve_lines(params[:sections])
new_file = resolved_lines.map { |line| line[:full_line] }.join("\n") new_file = resolved_lines.map { |line| line[:full_line] }.join("\n")
new_file << "\n" if file.our_blob.data.ends_with?("\n") new_file << "\n" if file.our_blob.data.ends_with?("\n")
elsif params[:content] elsif params[:content]
new_file = file.resolve_content(params[:content]) new_file = file.resolve_content(params[:content])
end end
our_path = file.our_path our_path = file.our_path
index.add(path: our_path, oid: @repository.rugged.write(new_file, :blob), mode: file.our_mode) index.add(path: our_path, oid: @repository.rugged.write(new_file, :blob), mode: file.our_mode)
index.conflict_remove(our_path) index.conflict_remove(our_path)
end
end end
end end
end end
......
...@@ -38,7 +38,7 @@ module Gitlab ...@@ -38,7 +38,7 @@ module Gitlab
end end
def generate_line_code(line) def generate_line_code(line)
Gitlab::Git::DiffLineCode.generate(file_path, line.new_pos, line.old_pos) Gitlab::Git::Conflict::LineCode.generate(file_path, line.new_pos, line.old_pos)
end end
def on_diff? def on_diff?
......
...@@ -17,8 +17,8 @@ describe Projects::MergeRequests::ConflictsController do ...@@ -17,8 +17,8 @@ describe Projects::MergeRequests::ConflictsController do
describe 'GET show' do describe 'GET show' do
context 'when the conflicts cannot be resolved in the UI' do context 'when the conflicts cannot be resolved in the UI' do
before do before do
allow(Gitlab::Git::ConflictParser).to receive(:parse) allow(Gitlab::Git::Conflict::Parser).to receive(:parse)
.and_raise(Gitlab::Git::ConflictParser::UnmergeableFile) .and_raise(Gitlab::Git::Conflict::Parser::UnmergeableFile)
get :show, get :show,
namespace_id: merge_request_with_conflicts.project.namespace.to_param, namespace_id: merge_request_with_conflicts.project.namespace.to_param,
...@@ -109,8 +109,8 @@ describe Projects::MergeRequests::ConflictsController do ...@@ -109,8 +109,8 @@ describe Projects::MergeRequests::ConflictsController do
context 'when the conflicts cannot be resolved in the UI' do context 'when the conflicts cannot be resolved in the UI' do
before do before do
allow(Gitlab::Git::ConflictParser).to receive(:parse) allow(Gitlab::Git::Conflict::Parser).to receive(:parse)
.and_raise(Gitlab::Git::ConflictParser::UnmergeableFile) .and_raise(Gitlab::Git::Conflict::Parser::UnmergeableFile)
conflict_for_path('files/ruby/regex.rb') conflict_for_path('files/ruby/regex.rb')
end end
......
...@@ -10,7 +10,7 @@ describe Gitlab::Conflict::File do ...@@ -10,7 +10,7 @@ describe Gitlab::Conflict::File do
let(:index) { rugged.merge_commits(our_commit, their_commit) } let(:index) { rugged.merge_commits(our_commit, their_commit) }
let(:rugged_conflict) { index.conflicts.last } let(:rugged_conflict) { index.conflicts.last }
let(:raw_conflict_content) { index.merge_file('files/ruby/regex.rb')[:data] } let(:raw_conflict_content) { index.merge_file('files/ruby/regex.rb')[:data] }
let(:raw_conflict_file) { Gitlab::Git::ConflictFile.new(repository, our_commit.oid, rugged_conflict, raw_conflict_content) } let(:raw_conflict_file) { Gitlab::Git::Conflict::File.new(repository, our_commit.oid, rugged_conflict, raw_conflict_content) }
let(:conflict_file) { described_class.new(raw_conflict_file, merge_request: merge_request) } let(:conflict_file) { described_class.new(raw_conflict_file, merge_request: merge_request) }
describe '#resolve_lines' do describe '#resolve_lines' do
...@@ -54,13 +54,13 @@ describe Gitlab::Conflict::File do ...@@ -54,13 +54,13 @@ describe Gitlab::Conflict::File do
invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h invalid_hash = section_keys.map { |key| [key, 'invalid'] }.to_h
expect { conflict_file.resolve_lines({}) } expect { conflict_file.resolve_lines({}) }
.to raise_error(Gitlab::Git::Merge::ResolutionError) .to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
expect { conflict_file.resolve_lines(empty_hash) } expect { conflict_file.resolve_lines(empty_hash) }
.to raise_error(Gitlab::Git::Merge::ResolutionError) .to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
expect { conflict_file.resolve_lines(invalid_hash) } expect { conflict_file.resolve_lines(invalid_hash) }
.to raise_error(Gitlab::Git::Merge::ResolutionError) .to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
end end
end end
......
...@@ -40,7 +40,7 @@ describe Gitlab::Diff::Position do ...@@ -40,7 +40,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, subject.new_line, 0) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, subject.new_line, 0)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -108,7 +108,7 @@ describe Gitlab::Diff::Position do ...@@ -108,7 +108,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, subject.new_line, 15) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, subject.new_line, 15)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -149,7 +149,7 @@ describe Gitlab::Diff::Position do ...@@ -149,7 +149,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, subject.new_line, subject.old_line) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, subject.new_line, subject.old_line)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -189,7 +189,7 @@ describe Gitlab::Diff::Position do ...@@ -189,7 +189,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, 13, subject.old_line) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, 13, subject.old_line)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -233,7 +233,7 @@ describe Gitlab::Diff::Position do ...@@ -233,7 +233,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, subject.new_line, 5) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, subject.new_line, 5)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -274,7 +274,7 @@ describe Gitlab::Diff::Position do ...@@ -274,7 +274,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, subject.new_line, subject.old_line) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, subject.new_line, subject.old_line)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -314,7 +314,7 @@ describe Gitlab::Diff::Position do ...@@ -314,7 +314,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, 4, subject.old_line) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, 4, subject.old_line)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -357,7 +357,7 @@ describe Gitlab::Diff::Position do ...@@ -357,7 +357,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, 0, subject.old_line) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, 0, subject.old_line)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -399,7 +399,7 @@ describe Gitlab::Diff::Position do ...@@ -399,7 +399,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, subject.new_line, 0) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, subject.new_line, 0)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
...@@ -447,7 +447,7 @@ describe Gitlab::Diff::Position do ...@@ -447,7 +447,7 @@ describe Gitlab::Diff::Position do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(subject.file_path, 0, subject.old_line) line_code = Gitlab::Git::Conflict::LineCode.generate(subject.file_path, 0, subject.old_line)
expect(subject.line_code(project.repository)).to eq(line_code) expect(subject.line_code(project.repository)).to eq(line_code)
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Git::ConflictParser do describe Gitlab::Git::Conflict::Parser do
describe '.parse' do describe '.parse' do
def parse_text(text) def parse_text(text)
described_class.parse(text, our_path: 'README.md', their_path: 'README.md') described_class.parse(text, our_path: 'README.md', their_path: 'README.md')
...@@ -125,12 +125,12 @@ CONFLICT ...@@ -125,12 +125,12 @@ CONFLICT
context 'when there is a non-start delimiter first' do context 'when there is a non-start delimiter first' do
it 'raises UnexpectedDelimiter when there is a middle delimiter first' do it 'raises UnexpectedDelimiter when there is a middle delimiter first' do
expect { parse_text('=======') } expect { parse_text('=======') }
.to raise_error(Gitlab::Git::ConflictParser::UnexpectedDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::UnexpectedDelimiter)
end end
it 'raises UnexpectedDelimiter when there is an end delimiter first' do it 'raises UnexpectedDelimiter when there is an end delimiter first' do
expect { parse_text('>>>>>>> README.md') } expect { parse_text('>>>>>>> README.md') }
.to raise_error(Gitlab::Git::ConflictParser::UnexpectedDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::UnexpectedDelimiter)
end end
it 'does not raise when there is an end delimiter for a different path first' do it 'does not raise when there is an end delimiter for a different path first' do
...@@ -145,12 +145,12 @@ CONFLICT ...@@ -145,12 +145,12 @@ CONFLICT
it 'raises UnexpectedDelimiter when it is followed by an end delimiter' do it 'raises UnexpectedDelimiter when it is followed by an end delimiter' do
expect { parse_text(start_text + '>>>>>>> README.md' + end_text) } expect { parse_text(start_text + '>>>>>>> README.md' + end_text) }
.to raise_error(Gitlab::Git::ConflictParser::UnexpectedDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::UnexpectedDelimiter)
end end
it 'raises UnexpectedDelimiter when it is followed by another start delimiter' do it 'raises UnexpectedDelimiter when it is followed by another start delimiter' do
expect { parse_text(start_text + start_text + end_text) } expect { parse_text(start_text + start_text + end_text) }
.to raise_error(Gitlab::Git::ConflictParser::UnexpectedDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::UnexpectedDelimiter)
end end
it 'does not raise when it is followed by a start delimiter for a different path' do it 'does not raise when it is followed by a start delimiter for a different path' do
...@@ -165,12 +165,12 @@ CONFLICT ...@@ -165,12 +165,12 @@ CONFLICT
it 'raises UnexpectedDelimiter when it is followed by another middle delimiter' do it 'raises UnexpectedDelimiter when it is followed by another middle delimiter' do
expect { parse_text(start_text + '=======' + end_text) } expect { parse_text(start_text + '=======' + end_text) }
.to raise_error(Gitlab::Git::ConflictParser::UnexpectedDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::UnexpectedDelimiter)
end end
it 'raises UnexpectedDelimiter when it is followed by a start delimiter' do it 'raises UnexpectedDelimiter when it is followed by a start delimiter' do
expect { parse_text(start_text + start_text + end_text) } expect { parse_text(start_text + start_text + end_text) }
.to raise_error(Gitlab::Git::ConflictParser::UnexpectedDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::UnexpectedDelimiter)
end end
it 'does not raise when it is followed by a start delimiter for another path' do it 'does not raise when it is followed by a start delimiter for another path' do
...@@ -183,25 +183,25 @@ CONFLICT ...@@ -183,25 +183,25 @@ CONFLICT
start_text = "<<<<<<< README.md\n=======\n" start_text = "<<<<<<< README.md\n=======\n"
expect { parse_text(start_text) } expect { parse_text(start_text) }
.to raise_error(Gitlab::Git::ConflictParser::MissingEndDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::MissingEndDelimiter)
expect { parse_text(start_text + '>>>>>>> some-other-path.md') } expect { parse_text(start_text + '>>>>>>> some-other-path.md') }
.to raise_error(Gitlab::Git::ConflictParser::MissingEndDelimiter) .to raise_error(Gitlab::Git::Conflict::Parser::MissingEndDelimiter)
end end
end end
context 'other file types' do context 'other file types' do
it 'raises UnmergeableFile when lines is blank, indicating a binary file' do it 'raises UnmergeableFile when lines is blank, indicating a binary file' do
expect { parse_text('') } expect { parse_text('') }
.to raise_error(Gitlab::Git::ConflictParser::UnmergeableFile) .to raise_error(Gitlab::Git::Conflict::Parser::UnmergeableFile)
expect { parse_text(nil) } expect { parse_text(nil) }
.to raise_error(Gitlab::Git::ConflictParser::UnmergeableFile) .to raise_error(Gitlab::Git::Conflict::Parser::UnmergeableFile)
end end
it 'raises UnmergeableFile when the file is over 200 KB' do it 'raises UnmergeableFile when the file is over 200 KB' do
expect { parse_text('a' * 204801) } expect { parse_text('a' * 204801) }
.to raise_error(Gitlab::Git::ConflictParser::UnmergeableFile) .to raise_error(Gitlab::Git::Conflict::Parser::UnmergeableFile)
end end
# All text from Rugged has an encoding of ASCII_8BIT, so force that in # All text from Rugged has an encoding of ASCII_8BIT, so force that in
...@@ -216,7 +216,7 @@ CONFLICT ...@@ -216,7 +216,7 @@ CONFLICT
context 'when the file contains non-UTF-8 characters' do context 'when the file contains non-UTF-8 characters' do
it 'raises UnsupportedEncoding' do it 'raises UnsupportedEncoding' do
expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) } expect { parse_text("a\xC4\xFC".force_encoding(Encoding::ASCII_8BIT)) }
.to raise_error(Gitlab::Git::ConflictParser::UnsupportedEncoding) .to raise_error(Gitlab::Git::Conflict::Parser::UnsupportedEncoding)
end end
end end
end end
......
...@@ -105,7 +105,7 @@ describe DiffNote do ...@@ -105,7 +105,7 @@ describe DiffNote do
describe "#line_code" do describe "#line_code" do
it "returns the correct line code" do it "returns the correct line code" do
line_code = Gitlab::Git::DiffLineCode.generate(position.file_path, position.formatter.new_line, 15) line_code = Gitlab::Git::Conflict::LineCode.generate(position.file_path, position.formatter.new_line, 15)
expect(subject.line_code).to eq(line_code) expect(subject.line_code).to eq(line_code)
end end
......
...@@ -204,16 +204,16 @@ describe MergeRequests::Conflicts::ResolveService do ...@@ -204,16 +204,16 @@ describe MergeRequests::Conflicts::ResolveService do
it 'raises a ResolutionError error' do it 'raises a ResolutionError error' do
expect { service.execute(user, invalid_params) } expect { service.execute(user, invalid_params) }
.to raise_error(Gitlab::Git::Merge::ResolutionError) .to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
end end
end end
context 'when the content of a file is unchanged' do context 'when the content of a file is unchanged' do
let(:merge) do let(:resolver) do
MergeRequests::Conflicts::ListService.new(merge_request).conflicts.merge MergeRequests::Conflicts::ListService.new(merge_request).conflicts.resolver
end end
let(:regex_conflict) do let(:regex_conflict) do
merge.conflict_for_path('files/ruby/regex.rb', 'files/ruby/regex.rb') resolver.conflict_for_path('files/ruby/regex.rb', 'files/ruby/regex.rb')
end end
let(:invalid_params) do let(:invalid_params) do
...@@ -235,7 +235,7 @@ describe MergeRequests::Conflicts::ResolveService do ...@@ -235,7 +235,7 @@ describe MergeRequests::Conflicts::ResolveService do
it 'raises a ResolutionError error' do it 'raises a ResolutionError error' do
expect { service.execute(user, invalid_params) } expect { service.execute(user, invalid_params) }
.to raise_error(Gitlab::Git::Merge::ResolutionError) .to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
end end
end end
...@@ -255,7 +255,7 @@ describe MergeRequests::Conflicts::ResolveService do ...@@ -255,7 +255,7 @@ describe MergeRequests::Conflicts::ResolveService do
it 'raises a ResolutionError error' do it 'raises a ResolutionError error' do
expect { service.execute(user, invalid_params) } expect { service.execute(user, invalid_params) }
.to raise_error(Gitlab::Git::Merge::ResolutionError) .to raise_error(Gitlab::Git::Conflict::Resolver::ResolutionError)
end 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