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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
# Defines a specific location, identified by paths and line numbers,
# within a specific diff, identified by start, head and base commit ids.
module Gitlab
module Diff
class Position
attr_reader :old_path
attr_reader :new_path
attr_reader :old_line
attr_reader :new_line
attr_reader :base_sha
attr_reader :start_sha
attr_reader :head_sha
def initialize(attrs = {})
@old_path = attrs[:old_path]
@new_path = attrs[:new_path]
@old_line = attrs[:old_line]
@new_line = attrs[:new_line]
if attrs[:diff_refs]
@base_sha = attrs[:diff_refs].base_sha
@start_sha = attrs[:diff_refs].start_sha
@head_sha = attrs[:diff_refs].head_sha
else
@base_sha = attrs[:base_sha]
@start_sha = attrs[:start_sha]
@head_sha = attrs[:head_sha]
end
end
def init_with(coder)
initialize(coder['attributes'])
self
end
def encode_with(coder)
coder['attributes'] = self.to_h
end
def key
@key ||= [base_sha, start_sha, head_sha, Digest::SHA1.hexdigest(old_path || ""), Digest::SHA1.hexdigest(new_path || ""), old_line, new_line]
end
def ==(other)
other.is_a?(self.class) && key == other.key
end
def to_h
{
old_path: old_path,
new_path: new_path,
old_line: old_line,
new_line: new_line,
base_sha: base_sha,
start_sha: start_sha,
head_sha: head_sha
}
end
def inspect
%(#<#{self.class}:#{object_id} #{to_h}>)
end
def complete?
file_path.present? &&
(old_line || new_line) &&
diff_refs.complete?
end
def to_json
JSON.generate(self.to_h)
end
def type
if old_line && new_line
nil
elsif new_line
'new'
else
'old'
end
end
def unchanged?
type.nil?
end
def added?
type == 'new'
end
def removed?
type == 'old'
end
def paths
[old_path, new_path].compact.uniq
end
def file_path
new_path.presence || old_path
end
def diff_refs
@diff_refs ||= DiffRefs.new(base_sha: base_sha, start_sha: start_sha, head_sha: head_sha)
end
def diff_file(repository)
@diff_file ||= begin
if RequestStore.active?
key = {
project_id: repository.project.id,
start_sha: start_sha,
head_sha: head_sha,
path: file_path
}
RequestStore.fetch(key) { find_diff_file(repository) }
else
find_diff_file(repository)
end
end
end
def diff_line(repository)
@diff_line ||= diff_file(repository).line_for_position(self)
end
def line_code(repository)
@line_code ||= diff_file(repository).line_code_for_position(self)
end
private
def find_diff_file(repository)
diffs = Gitlab::Git::Compare.new(
repository.raw_repository,
start_sha,
head_sha
).diffs(paths: paths)
diff = diffs.first
return unless diff
Gitlab::Diff::File.new(diff, repository: repository, diff_refs: diff_refs)
end
end
end
end
|