2014-09-08 13:25:50 +00:00
|
|
|
module Gitlab
|
|
|
|
module Diff
|
|
|
|
class File
|
2017-05-15 18:19:49 +00:00
|
|
|
attr_reader :diff, :repository, :diff_refs, :fallback_diff_refs
|
2014-09-08 13:25:50 +00:00
|
|
|
|
2017-05-15 17:10:29 +00:00
|
|
|
delegate :new_file?, :deleted_file?, :renamed_file?,
|
|
|
|
:old_path, :new_path, :a_mode, :b_mode, :mode_changed?,
|
2016-07-15 07:04:18 +00:00
|
|
|
:submodule?, :too_large?, :collapsed?, to: :diff, prefix: false
|
2014-09-08 13:25:50 +00:00
|
|
|
|
2017-05-15 18:19:49 +00:00
|
|
|
def initialize(diff, repository:, diff_refs: nil, fallback_diff_refs: nil)
|
2014-09-08 13:25:50 +00:00
|
|
|
@diff = diff
|
2016-06-20 16:51:48 +00:00
|
|
|
@repository = repository
|
2016-01-20 17:44:27 +00:00
|
|
|
@diff_refs = diff_refs
|
2017-05-15 18:19:49 +00:00
|
|
|
@fallback_diff_refs = fallback_diff_refs
|
2016-01-20 17:44:27 +00:00
|
|
|
end
|
|
|
|
|
2016-06-20 17:17:25 +00:00
|
|
|
def position(line)
|
|
|
|
return unless diff_refs
|
|
|
|
|
|
|
|
Position.new(
|
|
|
|
old_path: old_path,
|
|
|
|
new_path: new_path,
|
|
|
|
old_line: line.old_line,
|
|
|
|
new_line: line.new_line,
|
2016-07-06 23:29:41 +00:00
|
|
|
diff_refs: diff_refs
|
2016-06-20 17:17:25 +00:00
|
|
|
)
|
|
|
|
end
|
|
|
|
|
2016-06-20 17:15:44 +00:00
|
|
|
def line_code(line)
|
|
|
|
return if line.meta?
|
|
|
|
|
|
|
|
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
|
|
|
|
end
|
|
|
|
|
|
|
|
def line_for_line_code(code)
|
|
|
|
diff_lines.find { |line| line_code(line) == code }
|
|
|
|
end
|
|
|
|
|
2016-06-20 17:17:25 +00:00
|
|
|
def line_for_position(pos)
|
|
|
|
diff_lines.find { |line| position(line) == pos }
|
|
|
|
end
|
|
|
|
|
|
|
|
def position_for_line_code(code)
|
|
|
|
line = line_for_line_code(code)
|
|
|
|
position(line) if line
|
|
|
|
end
|
|
|
|
|
|
|
|
def line_code_for_position(pos)
|
|
|
|
line = line_for_position(pos)
|
|
|
|
line_code(line) if line
|
|
|
|
end
|
|
|
|
|
2017-05-15 18:19:49 +00:00
|
|
|
def old_sha
|
|
|
|
diff_refs&.base_sha
|
|
|
|
end
|
|
|
|
|
|
|
|
def new_sha
|
|
|
|
diff_refs&.head_sha
|
|
|
|
end
|
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
def new_content_sha
|
|
|
|
return if deleted_file?
|
|
|
|
return @new_content_sha if defined?(@new_content_sha)
|
2017-05-15 18:19:49 +00:00
|
|
|
|
|
|
|
refs = diff_refs || fallback_diff_refs
|
2017-06-06 21:24:32 +00:00
|
|
|
@new_content_sha = refs&.head_sha
|
2017-05-15 18:19:49 +00:00
|
|
|
end
|
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
def new_content_commit
|
|
|
|
return @new_content_commit if defined?(@new_content_commit)
|
2017-05-15 18:19:49 +00:00
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
sha = new_content_commit
|
|
|
|
@new_content_commit = repository.commit(sha) if sha
|
2017-05-15 18:19:49 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def old_content_sha
|
|
|
|
return if new_file?
|
|
|
|
return @old_content_sha if defined?(@old_content_sha)
|
2016-07-06 23:29:41 +00:00
|
|
|
|
2017-05-15 18:19:49 +00:00
|
|
|
refs = diff_refs || fallback_diff_refs
|
|
|
|
@old_content_sha = refs&.base_sha
|
2016-06-20 16:54:53 +00:00
|
|
|
end
|
|
|
|
|
2016-08-28 03:59:48 +00:00
|
|
|
def old_content_commit
|
2017-05-15 18:19:49 +00:00
|
|
|
return @old_content_commit if defined?(@old_content_commit)
|
2016-08-28 03:59:48 +00:00
|
|
|
|
2017-05-15 18:19:49 +00:00
|
|
|
sha = old_content_sha
|
|
|
|
@old_content_commit = repository.commit(sha) if sha
|
2016-08-28 03:59:48 +00:00
|
|
|
end
|
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
def new_blob
|
|
|
|
return @new_blob if defined?(@new_blob)
|
2017-05-15 18:19:49 +00:00
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
sha = new_content_sha
|
|
|
|
return @new_blob = nil unless sha
|
2017-05-15 18:19:49 +00:00
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
@new_blob = repository.blob_at(sha, file_path)
|
2016-01-20 17:44:27 +00:00
|
|
|
end
|
|
|
|
|
2017-05-15 18:19:49 +00:00
|
|
|
def old_blob
|
|
|
|
return @old_blob if defined?(@old_blob)
|
|
|
|
|
|
|
|
sha = old_content_sha
|
|
|
|
return @old_blob = nil unless sha
|
|
|
|
|
|
|
|
@old_blob = repository.blob_at(sha, old_path)
|
2014-09-08 13:25:50 +00:00
|
|
|
end
|
|
|
|
|
2017-06-06 21:24:32 +00:00
|
|
|
def content_sha
|
|
|
|
new_content_sha || old_content_sha
|
|
|
|
end
|
|
|
|
|
|
|
|
def content_commit
|
|
|
|
new_content_commit || old_content_commit
|
|
|
|
end
|
|
|
|
|
|
|
|
def blob
|
|
|
|
new_blob || old_blob
|
|
|
|
end
|
|
|
|
|
2016-07-26 07:21:42 +00:00
|
|
|
attr_writer :highlighted_diff_lines
|
2016-07-20 16:25:36 +00:00
|
|
|
|
2016-06-20 16:51:48 +00:00
|
|
|
# Array of Gitlab::Diff::Line objects
|
2014-09-08 13:25:50 +00:00
|
|
|
def diff_lines
|
2016-07-20 16:25:36 +00:00
|
|
|
@diff_lines ||= Gitlab::Diff::Parser.new.parse(raw_diff.each_line).to_a
|
2016-03-11 16:40:59 +00:00
|
|
|
end
|
|
|
|
|
2015-12-30 05:52:50 +00:00
|
|
|
def highlighted_diff_lines
|
2016-06-20 16:51:48 +00:00
|
|
|
@highlighted_diff_lines ||= Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
|
2015-12-30 05:52:50 +00:00
|
|
|
end
|
|
|
|
|
2016-07-20 16:25:36 +00:00
|
|
|
# Array[<Hash>] with right/left keys that contains Gitlab::Diff::Line objects which text is hightlighted
|
2016-01-20 13:51:56 +00:00
|
|
|
def parallel_diff_lines
|
2016-06-20 16:51:48 +00:00
|
|
|
@parallel_diff_lines ||= Gitlab::Diff::ParallelDiff.new(self).parallelize
|
2016-01-20 13:51:56 +00:00
|
|
|
end
|
|
|
|
|
2014-09-08 18:54:52 +00:00
|
|
|
def raw_diff
|
2014-09-24 10:26:53 +00:00
|
|
|
diff.diff.to_s
|
2014-09-08 18:54:52 +00:00
|
|
|
end
|
|
|
|
|
2014-09-08 13:25:50 +00:00
|
|
|
def next_line(index)
|
|
|
|
diff_lines[index + 1]
|
|
|
|
end
|
|
|
|
|
|
|
|
def prev_line(index)
|
2016-06-20 16:57:10 +00:00
|
|
|
diff_lines[index - 1] if index > 0
|
2014-09-08 13:25:50 +00:00
|
|
|
end
|
2014-09-08 18:54:52 +00:00
|
|
|
|
2016-06-20 17:17:25 +00:00
|
|
|
def paths
|
|
|
|
[old_path, new_path].compact
|
|
|
|
end
|
|
|
|
|
2014-09-08 18:54:52 +00:00
|
|
|
def file_path
|
2016-06-20 16:57:10 +00:00
|
|
|
new_path.presence || old_path
|
2014-09-08 18:54:52 +00:00
|
|
|
end
|
2015-10-01 11:52:08 +00:00
|
|
|
|
|
|
|
def added_lines
|
2015-12-15 02:53:52 +00:00
|
|
|
diff_lines.count(&:added?)
|
2015-10-01 11:52:08 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def removed_lines
|
2015-12-15 02:53:52 +00:00
|
|
|
diff_lines.count(&:removed?)
|
2015-10-01 11:52:08 +00:00
|
|
|
end
|
2016-06-20 16:54:53 +00:00
|
|
|
|
2016-11-10 17:24:12 +00:00
|
|
|
def file_identifier
|
2017-05-15 17:10:29 +00:00
|
|
|
"#{file_path}-#{new_file?}-#{deleted_file?}-#{renamed_file?}"
|
2016-10-12 13:34:47 +00:00
|
|
|
end
|
2017-06-06 21:24:32 +00:00
|
|
|
|
|
|
|
def diffable?
|
|
|
|
repository.attributes(file_path).fetch('diff') { true }
|
|
|
|
end
|
|
|
|
|
|
|
|
def binary?
|
|
|
|
old_blob&.binary? || new_blob&.binary?
|
|
|
|
end
|
|
|
|
|
|
|
|
def text?
|
|
|
|
!binary?
|
|
|
|
end
|
2014-09-08 13:25:50 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|