Commit 531f16be authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Use new diff parsing logic

Signed-off-by: default avatarDmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
parent e0eb4803
......@@ -31,7 +31,7 @@ class Projects::EditTreeController < Projects::BaseTreeController
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3',
include_diff_info: true)
@diff = Gitlab::DiffParser.new(diffy.diff.scan(/.*\n/))
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/), @path, @path)
render layout: false
end
......
......@@ -16,21 +16,7 @@ module CommitsHelper
commit_person_link(commit, options.merge(source: :committer))
end
def each_diff_line(diff, index)
Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
.each do |full_line, type, line_code, line_new, line_old|
yield(full_line, type, line_code, line_new, line_old)
end
end
def parallel_diff_line(diff, index)
Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
.each do |full_line, type, line_code, line_new, line_old, raw_line, next_type, next_line|
yield(full_line, type, line_code, line_new, line_old, raw_line, next_type, next_line)
end
end
def parallel_diff(diff, index)
def parallel_diff(diff_file, index)
lines = []
skip_next = false
......@@ -38,7 +24,21 @@ module CommitsHelper
#
# [left_type, left_line_number, left_line_content, right_line_type, right_line_number, right_line_content]
#
parallel_diff_line(diff, index) do |full_line, type, line_code, line_new, line_old, raw_line, next_type, next_line|
diff_file.diff_lines.each do |line|
full_line = line.text
type = line.type
line_code = line.code
line_new = line.new_pos
line_old = line.old_pos
next_line = diff_file.next_line(line.index)
if next_line
next_type = next_line.type
next_line = next_line.text
end
line = [type, line_old, full_line, next_type, line_new]
if type == 'match' || type.nil?
# line in the right panel is the same as in the left one
......@@ -72,31 +72,6 @@ module CommitsHelper
lines
end
def each_diff_line_near(diff, index, expected_line_code)
max_number_of_lines = 16
prev_match_line = nil
prev_lines = []
each_diff_line(diff, index) do |full_line, type, line_code, line_new, line_old|
line = [full_line, type, line_code, line_new, line_old]
if line_code != expected_line_code
if type == "match"
prev_lines.clear
prev_match_line = line
else
prev_lines.push(line)
prev_lines.shift if prev_lines.length >= max_number_of_lines
end
else
yield(prev_match_line) if !prev_match_line.nil?
prev_lines.each { |ln| yield(ln) }
yield(line)
break
end
end
end
def image_diff_class(diff)
if diff.deleted_file
"deleted"
......@@ -202,10 +177,6 @@ module CommitsHelper
end
end
def diff_file_mode_changed?(diff)
diff.a_mode && diff.b_mode && diff.a_mode != diff.b_mode
end
def unfold_bottom_class(bottom)
(bottom) ? 'js-unfold-bottom' : ''
end
......
module DiffHelper
def safe_diff_files(diffs)
def safe_diff_files(project, diffs)
if diff_hard_limit_enabled?
diffs.first(Commit::DIFF_HARD_LIMIT_FILES)
else
diffs.first(Commit::DIFF_SAFE_FILES)
end.map do |diff|
Gitlab::Diff::File.new(project, @commit, diff)
end
end
def show_diff_size_warninig?(diffs)
safe_diff_files(diffs).size < diffs.size
def show_diff_size_warninig?(project, diffs)
safe_diff_files(project, diffs).size < diffs.size
end
def diff_hard_limit_enabled?
......
......@@ -209,9 +209,10 @@ class Note < ActiveRecord::Base
noteable.diffs.each do |mr_diff|
next unless mr_diff.new_path == self.diff.new_path
Gitlab::DiffParser.new(mr_diff.diff.lines.to_a, mr_diff.new_path).
each do |full_line, type, line_code, line_new, line_old|
if full_line == diff_line
lines = Gitlab::Diff::Parser.new.parse(mr_diff.diff.lines.to_a, mr_diff.old_path, mr_diff.new_path)
lines.each do |line|
if line.text == diff_line
return true
end
end
......@@ -244,15 +245,39 @@ class Note < ActiveRecord::Base
return @diff_line if @diff_line
if diff
Gitlab::DiffParser.new(diff.diff.lines.to_a, diff.new_path)
.each do |full_line, type, line_code, line_new, line_old|
@diff_line = full_line if line_code == self.line_code
end
diff_lines.each do |line|
@diff_line = line.text if line.code == self.line_code
end
end
@diff_line
end
def truncated_diff_lines
max_number_of_lines = 16
prev_match_line = nil
prev_lines = []
diff_lines.each do |line|
if line.code != self.line_code
if line.type == "match"
prev_lines.clear
prev_match_line = line
else
prev_lines.push(line)
prev_lines.shift if prev_lines.length >= max_number_of_lines
end
else
prev_lines << line
return prev_lines
end
end
end
def diff_lines
@diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a, diff.old_path, diff.new_path)
end
def discussion_id
@discussion_id ||= Note.build_discussion_id(noteable_type, noteable_id || commit_id, line_code)
end
......
= render "commit_box"
= render "projects/commits/diffs", diffs: @diffs, project: @project
= render "projects/diffs/diffs", diffs: @diffs, project: @project
= render "projects/notes/notes_with_form"
......@@ -9,18 +9,18 @@
= raw render_markup(@blob.name, @content)
- else
.file-content.code
- unless @diff.empty?
- unless @diff_lines.empty?
%table.text-file
- @diff.each do |line, type, line_code, line_new, line_old, raw_line|
%tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match"
- @diff_lines.each do |line|
%tr.line_holder{ id: line.code, class: "#{line.type}" }
- if line.type == "match"
%td.old_line= "..."
%td.new_line= "..."
%td.line_content.matched= line
%td.line_content.matched= line.text
- else
%td.old_line
= link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
%td.new_line= link_to raw(type == "old" ? "&nbsp;" : line_new) , "##{line_code}", id: line_code
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line)
= link_to raw(line.type == "new" ? "&nbsp;" : line.old_pos), "##{line.code}", id: line.code
%td.new_line= link_to raw(line.type == "old" ? "&nbsp;" : line.new_pos) , "##{line.code}", id: line.code
%td.line_content{class: "noteable_line #{line.type} #{line.code}", "line.code" => line.code}= raw diff_line_content(line.text)
- else
.nothing-here-block No changes.
- if @merge_request_diff.collected?
= render "projects/commits/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
= render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
- else
......
......@@ -11,16 +11,16 @@
%br/
.diff-content
%table
- each_diff_line_near(diff, note.diff_file_index, note.line_code) do |line, type, line_code, line_new, line_old|
%tr.line_holder{ id: line_code }
- if type == "match"
- note.truncated_diff_lines.each do |line|
%tr.line_holder{ id: line.code }
- if line.type == "match"
%td.old_line= "..."
%td.new_line= "..."
%td.line_content.matched= line
%td.line_content.matched= line.text
- else
%td.old_line= raw(type == "new" ? "&nbsp;" : line_old)
%td.new_line= raw(type == "old" ? "&nbsp;" : line_new)
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw "#{line} &nbsp;"
%td.old_line= raw(line.type == "new" ? "&nbsp;" : line.old_pos)
%td.new_line= raw(line.type == "old" ? "&nbsp;" : line.new_pos)
%td.line_content{class: "noteable_line #{line.type} #{line.code}", "line_code" => line.code}= raw "#{line.text} &nbsp;"
- if line_code == note.line_code
- if line.code == note.line_code
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes
module Gitlab
class DiffParser
include Enumerable
attr_reader :lines, :new_path
def initialize(lines, new_path = '')
@lines = lines
@new_path = new_path
end
def each
line_old = 1
line_new = 1
type = nil
lines_arr = ::Gitlab::InlineDiff.processing lines
lines_arr.each_cons(2) do |line, next_line|
raw_line = line.dup
next if filename?(line)
full_line = html_escape(line.gsub(/\n/, ''))
full_line = ::Gitlab::InlineDiff.replace_markers full_line
next_line = html_escape(next_line.gsub(/\n/, ''))
next_line = ::Gitlab::InlineDiff.replace_markers next_line
if line.match(/^@@ -/)
type = "match"
line_old = line.match(/\-[0-9]*/)[0].to_i.abs rescue 0
line_new = line.match(/\+[0-9]*/)[0].to_i.abs rescue 0
next if line_old == 1 && line_new == 1 #top of file
yield(full_line, type, nil, line_new, line_old)
next
else
type = identification_type(line)
next_type = identification_type(next_line)
line_code = generate_line_code(new_path, line_new, line_old)
yield(full_line, type, line_code, line_new, line_old, raw_line, next_type, next_line)
end
if line[0] == "+"
line_new += 1
elsif line[0] == "-"
line_old += 1
else
line_new += 1
line_old += 1
end
end
end
def empty?
@lines.empty?
end
private
def filename?(line)
line.start_with?('--- /dev/null', '+++ /dev/null', '--- a', '+++ b',
'--- /tmp/diffy', '+++ /tmp/diffy')
end
def identification_type(line)
if line[0] == "+"
"new"
elsif line[0] == "-"
"old"
else
nil
end
end
def generate_line_code(path, line_new, line_old)
"#{Digest::SHA1.hexdigest(path)}_#{line_old}_#{line_new}"
end
def html_escape str
replacements = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
str.gsub(/[&"'><]/, replacements)
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