1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
module Gitlab
module Conflict
class File
CONTEXT_LINES = 3
attr_reader :merge_file_result, :their_path, :their_ref, :our_path, :our_ref, :repository
def initialize(merge_file_result, conflict, diff_refs:, repository:)
@merge_file_result = merge_file_result
@their_path = conflict[:theirs][:path]
@our_path = conflict[:ours][:path]
@their_ref = diff_refs.start_sha
@our_ref = diff_refs.head_sha
@repository = repository
end
# Array of Gitlab::Diff::Line objects
def lines
@lines ||= Gitlab::Conflict::Parser.new.parse(merge_file_result[:data],
our_path: our_path,
their_path: their_path)
end
def highlighted_lines
return @highlighted_lines if @highlighted_lines
their_highlight = Gitlab::Highlight.highlight_lines(repository, their_ref, their_path)
our_highlight = Gitlab::Highlight.highlight_lines(repository, our_ref, our_path)
@highlighted_lines = lines.map do |line|
line = line.dup
if line.type == 'old'
line.rich_text = their_highlight[line.old_line - 1]
else
line.rich_text = our_highlight[line.new_line - 1]
end
line
end
end
def sections
return @sections if @sections
chunked_lines = highlighted_lines.chunk { |line| line.type.nil? }
match_line = nil
@sections = chunked_lines.flat_map.with_index do |(no_conflict, lines), i|
section = nil
if no_conflict
conflict_before = i > 0
conflict_after = chunked_lines.peek
if conflict_before && conflict_after
if lines.length > CONTEXT_LINES * 2
tail_lines = lines.last(CONTEXT_LINES)
first_tail_line = tail_lines.first
match_line = Gitlab::Diff::Line.new('',
'match',
first_tail_line.index,
first_tail_line.old_pos,
first_tail_line.new_pos)
section = [
{ conflict: false, lines: lines.first(CONTEXT_LINES) },
{ conflict: false, lines: tail_lines.unshift(match_line) }
]
end
elsif conflict_after
lines = lines.last(CONTEXT_LINES)
elsif conflict_before
lines = lines.first(CONTEXT_LINES)
end
end
if match_line && !section
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 }
end
end
def as_json(opts = nil)
{
old_path: their_path,
new_path: our_path,
sections: sections
}
end
end
end
end
|