From 6b9c730e91962a6d6343bcb7fc4dc75c99b41bde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rub=C3=A9n=20D=C3=A1vila?= <rdavila84@gmail.com>
Date: Thu, 14 Jan 2016 16:38:37 -0500
Subject: [PATCH] More refactoring from last code review. #3945

* Use commit objects instead of IDs when generating diffs
* Use proper references when generating MR's source and target
* Update broken specs
---
 app/controllers/projects/commit_controller.rb |   2 +-
 .../projects/compare_controller.rb            |   2 +-
 .../projects/merge_requests_controller.rb     |   3 -
 app/helpers/diff_helper.rb                    |   4 +-
 app/models/merge_request.rb                   |   4 +
 app/views/projects/diffs/_diffs.html.haml     |   2 +-
 .../merge_requests/_new_submit.html.haml      |   2 +-
 .../merge_requests/show/_diffs.html.haml      |   3 +-
 lib/gitlab/diff/file.rb                       |   5 +-
 lib/gitlab/diff/highlight.rb                  |  17 +-
 spec/fixtures/parallel_diff_result.yml        | 590 ++++++++++--------
 spec/helpers/diff_helper_spec.rb              |  24 +-
 spec/lib/gitlab/diff/file_spec.rb             |   2 +-
 spec/lib/gitlab/diff/highlight_spec.rb        |   2 +-
 14 files changed, 366 insertions(+), 296 deletions(-)

diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index c8f143dd6b4..ba924ccc5a5 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -72,7 +72,7 @@ class Projects::CommitController < Projects::ApplicationController
       @diffs = commit.diffs
     end
 
-    @diff_refs = [commit.parent_id || commit.id, commit.id]
+    @diff_refs = [commit.parent || commit, commit]
     @notes_count = commit.notes.count
 
     @statuses = ci_commit.statuses if ci_commit
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 5b88aed7a64..60360c8e5c8 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -20,9 +20,9 @@ class Projects::CompareController < Projects::ApplicationController
     if compare_result
       @commits = Commit.decorate(compare_result.commits, @project)
       @diffs = compare_result.diffs
-      @diff_refs = [base_ref, head_ref]
       @commit = @project.commit(head_ref)
       @first_commit = @project.commit(base_ref)
+      @diff_refs = [@first_commit, @commit]
       @line_notes = []
     end
   end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 3d792af0a48..ab5c953189c 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -59,7 +59,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
   def diffs
     @commit = @merge_request.last_commit
     @first_commit = @merge_request.first_commit
-    @diff_refs = [@merge_request.last_commit.parent_id, @merge_request.source_sha]
 
     @comments_allowed = @reply_allowed = true
     @comments_target = {
@@ -104,8 +103,6 @@ class Projects::MergeRequestsController < Projects::ApplicationController
     @commit = @merge_request.last_commit
     @first_commit = @merge_request.first_commit
     @diffs = @merge_request.compare_diffs
-    # We need to use #source_branch because #source_sha requires an existent MergeRequestDiff object.
-    @diff_refs = [@merge_request.target_sha, @merge_request.source_branch]
 
     @ci_commit = @merge_request.ci_commit
     @statuses = @ci_commit.statuses if @ci_commit
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index 1596f9e7d19..425a8ced549 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -19,13 +19,13 @@ module DiffHelper
     end
   end
 
-  def safe_diff_files(diffs, diff_refs, repository)
+  def safe_diff_files(diffs, diff_refs)
     lines = 0
     safe_files = []
     diffs.first(allowed_diff_size).each do |diff|
       lines += diff.diff.lines.count
       break if lines > allowed_diff_lines
-      safe_files << Gitlab::Diff::File.new(diff, diff_refs, repository)
+      safe_files << Gitlab::Diff::File.new(diff, diff_refs)
     end
     safe_files
   end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index ac25d38eb63..fe87b820e98 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -511,4 +511,8 @@ class MergeRequest < ActiveRecord::Base
   def broken?
     self.commits.blank? || branch_missing? || cannot_be_merged?
   end
+
+  def diff_range
+    [last_commit.parent, first_commit]
+  end
 end
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 58ad7d79af9..b2f9c14da88 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -1,7 +1,7 @@
 - if diff_view == 'parallel'
   - fluid_layout true
 
-- diff_files = safe_diff_files(diffs, diff_refs, repository)
+- diff_files = safe_diff_files(diffs, diff_refs)
 
 .gray-content-block.middle-block.oneline-block
   .inline-parallel-buttons
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index 0cb8b6daedb..f2a12099b26 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -38,7 +38,7 @@
       = render "projects/merge_requests/show/commits"
     #diffs.diffs.tab-pane.active
       - if @diffs.present?
-        = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
+        = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @merge_request.diff_range
       - elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
         .alert.alert-danger
           %h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml
index 1d9af1e4160..46c6f79937b 100644
--- a/app/views/projects/merge_requests/show/_diffs.html.haml
+++ b/app/views/projects/merge_requests/show/_diffs.html.haml
@@ -1,5 +1,6 @@
 - if @merge_request_diff.collected?
-  = render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs, project: @merge_request.project, diff_refs: @diff_refs
+  = render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs,
+    project: @merge_request.project, diff_refs: @merge_request.diff_range
 - elsif @merge_request_diff.empty?
   .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
 - else
diff --git a/lib/gitlab/diff/file.rb b/lib/gitlab/diff/file.rb
index c1a6e16da5a..a6a7fc8ff4c 100644
--- a/lib/gitlab/diff/file.rb
+++ b/lib/gitlab/diff/file.rb
@@ -1,14 +1,13 @@
 module Gitlab
   module Diff
     class File
-      attr_reader :diff, :repository, :new_ref, :old_ref
+      attr_reader :diff, :new_ref, :old_ref
 
       delegate :new_file, :deleted_file, :renamed_file,
         :old_path, :new_path, to: :diff, prefix: false
 
-      def initialize(diff, diff_refs, repository)
+      def initialize(diff, diff_refs)
         @diff = diff
-        @repository = repository
         @old_ref, @new_ref = diff_refs
       end
 
diff --git a/lib/gitlab/diff/highlight.rb b/lib/gitlab/diff/highlight.rb
index e21f496102d..fb79a2a69de 100644
--- a/lib/gitlab/diff/highlight.rb
+++ b/lib/gitlab/diff/highlight.rb
@@ -3,8 +3,7 @@ module Gitlab
     class Highlight
       attr_reader :diff_file
 
-      delegate :repository, :old_path, :new_path, :old_ref, :new_ref,
-        to: :diff_file, prefix: :diff
+      delegate :old_path, :new_path, :old_ref, :new_ref, to: :diff_file, prefix: :diff
 
       def initialize(diff_file)
         @diff_file = diff_file
@@ -141,11 +140,11 @@ module Gitlab
       end
 
       def old_lines
-        @old_lines ||= Gitlab::Highlight.highlight_lines(diff_repository, diff_old_ref, diff_old_path)
+        @old_lines ||= self.class.process_file(*processing_args(:old))
       end
 
       def new_lines
-        @new_lines ||= Gitlab::Highlight.highlight_lines(diff_repository, diff_new_ref, diff_new_path)
+        @new_lines ||= self.class.process_file(*processing_args(:new))
       end
 
       def longest_common_suffix(a, b)
@@ -200,6 +199,16 @@ module Gitlab
 
         offset
       end
+
+      private
+
+      def processing_args(version)
+        ref  = send("diff_#{version}_ref")
+        path = send("diff_#{version}_path")
+
+        [ref.project.repository, ref.id, path]
+      end
+
     end
   end
 end
diff --git a/spec/fixtures/parallel_diff_result.yml b/spec/fixtures/parallel_diff_result.yml
index 020c1817226..4583de1231e 100644
--- a/spec/fixtures/parallel_diff_result.yml
+++ b/spec/fixtures/parallel_diff_result.yml
@@ -1,268 +1,324 @@
 ---
-- - match
-  - 6
-  - "@@ -6,12 +6,18 @@ module Popen"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
-  - match
-  - 6
-  - "@@ -6,12 +6,18 @@ module Popen"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
-- - 
-  - 6
-  - |2
-     <span id="LC6" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
-  - 
-  - 6
-  - |2
-     <span id="LC6" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
-- - 
-  - 7
-  - |2
-     <span id="LC7" class="line">  <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7
-  - 
-  - 7
-  - |2
-     <span id="LC7" class="line">  <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7
-- - 
-  - 8
-  - |2
-     <span id="LC8" class="line">    <span class="k">unless</span> <span class="n">cmd</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="no">Array</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_8_8
-  - 
-  - 8
-  - |2
-     <span id="LC8" class="line">    <span class="k">unless</span> <span class="n">cmd</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="no">Array</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_8_8
-- - old
-  - 9
-  - |
-    -<span id="LC9" class="line">      <span class="k">raise</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9
-  - new
-  - 9
-  - |
-    +<span id="LC9" class="line">      <span class="k">raise</span> <span class="no">RuntimeError</span><span class="p">,</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9
-- - 
-  - 10
-  - |2
-     <span id="LC10" class="line">    <span class="k">end</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_10
-  - 
-  - 10
-  - |2
-     <span id="LC10" class="line">    <span class="k">end</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_10
-- - 
-  - 11
-  - |2
-     <span id="LC11" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_11_11
-  - 
-  - 11
-  - |2
-     <span id="LC11" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_11_11
-- - 
-  - 12
-  - |2
-     <span id="LC12" class="line">    <span class="n">path</span> <span class="o">||=</span> <span class="no">Dir</span><span class="p">.</span><span class="nf">pwd</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_12_12
-  - 
-  - 12
-  - |2
-     <span id="LC12" class="line">    <span class="n">path</span> <span class="o">||=</span> <span class="no">Dir</span><span class="p">.</span><span class="nf">pwd</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_12_12
-- - old
-  - 13
-  - |
-    -<span id="LC13" class="line">    <span class="n">vars</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;PWD&quot;</span> <span class="o">=&gt;</span> <span class="n">path</span> <span class="p">}</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_13_13
-  - old
-  - 
-  - "&nbsp;"
-  - 
-- - old
-  - 14
-  - |
-    -<span id="LC14" class="line">    <span class="n">options</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">chdir: </span><span class="n">path</span> <span class="p">}</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_13
-  - new
-  - 13
-  - |
-    +<span id="LC13" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_13
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14
-  - new
-  - 14
-  - |
-    +<span id="LC14" class="line">    <span class="n">vars</span> <span class="o">=</span> <span class="p">{</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15
-  - new
-  - 15
-  - |
-    +<span id="LC15" class="line">      <span class="s2">&quot;PWD&quot;</span> <span class="o">=&gt;</span> <span class="n">path</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_16
-  - new
-  - 16
-  - |
-    +<span id="LC16" class="line">    <span class="p">}</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_16
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_17
-  - new
-  - 17
-  - |
-    +<span id="LC17" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_17
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_18
-  - new
-  - 18
-  - |
-    +<span id="LC18" class="line">    <span class="n">options</span> <span class="o">=</span> <span class="p">{</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_18
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_19
-  - new
-  - 19
-  - |
-    +<span id="LC19" class="line">      <span class="ss">chdir: </span><span class="n">path</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_19
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_20
-  - new
-  - 20
-  - |
-    +<span id="LC20" class="line">    <span class="p">}</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_20
-- - 
-  - 15
-  - |2
-     <span id="LC21" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_21
-  - 
-  - 21
-  - |2
-     <span id="LC21" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_21
-- - 
-  - 16
-  - |2
-     <span id="LC22" class="line">    <span class="k">unless</span> <span class="no">File</span><span class="p">.</span><span class="nf">directory?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_16_22
-  - 
-  - 22
-  - |2
-     <span id="LC22" class="line">    <span class="k">unless</span> <span class="no">File</span><span class="p">.</span><span class="nf">directory?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_16_22
-- - 
-  - 17
-  - |2
-     <span id="LC23" class="line">      <span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_17_23
-  - 
-  - 23
-  - |2
-     <span id="LC23" class="line">      <span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_17_23
-- - match
-  - 19
-  - "@@ -19,6 +25,7 @@ module Popen"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
-  - match
-  - 25
-  - "@@ -19,6 +25,7 @@ module Popen"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
-- - 
-  - 19
-  - |2
-     <span id="LC25" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
-  - 
-  - 25
-  - |2
-     <span id="LC25" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
-- - 
-  - 20
-  - |2
-     <span id="LC26" class="line">    <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26
-  - 
-  - 26
-  - |2
-     <span id="LC26" class="line">    <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26
-- - 
-  - 21
-  - |2
-     <span id="LC27" class="line">    <span class="vi">@cmd_status</span> <span class="o">=</span> <span class="mi">0</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_21_27
-  - 
-  - 27
-  - |2
-     <span id="LC27" class="line">    <span class="vi">@cmd_status</span> <span class="o">=</span> <span class="mi">0</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_21_27
-- - 
-  - 
-  - "&nbsp;"
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_28
-  - new
-  - 28
-  - |
-    +<span id="LC28" class="line"></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_28
-- - 
-  - 22
-  - |2
-     <span id="LC29" class="line">    <span class="no">Open3</span><span class="p">.</span><span class="nf">popen3</span><span class="p">(</span><span class="n">vars</span><span class="p">,</span> <span class="o">*</span><span class="n">cmd</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">wait_thr</span><span class="o">|</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_29
-  - 
-  - 29
-  - |2
-     <span id="LC29" class="line">    <span class="no">Open3</span><span class="p">.</span><span class="nf">popen3</span><span class="p">(</span><span class="n">vars</span><span class="p">,</span> <span class="o">*</span><span class="n">cmd</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">wait_thr</span><span class="o">|</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_29
-- - 
-  - 23
-  - |2
-     <span id="LC30" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stdout</span><span class="p">.</span><span class="nf">read</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_23_30
-  - 
-  - 30
-  - |2
-     <span id="LC30" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stdout</span><span class="p">.</span><span class="nf">read</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_23_30
-- - 
-  - 24
-  - |2
-     <span id="LC31" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stderr</span><span class="p">.</span><span class="nf">read</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_24_31
-  - 
-  - 31
-  - |2
-     <span id="LC31" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stderr</span><span class="p">.</span><span class="nf">read</span></span>
-  - 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_24_31
+- :left:
+    :type: match
+    :number: 6
+    :text: "@@ -6,12 +6,18 @@ module Popen"
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
+  :right:
+    :type: match
+    :number: 6
+    :text: "@@ -6,12 +6,18 @@ module Popen"
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
+- :left:
+    :type: 
+    :number: 6
+    :text: |2
+       <span id="LC6" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
+  :right:
+    :type: 
+    :number: 6
+    :text: |2
+       <span id="LC6" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_6_6
+- :left:
+    :type: 
+    :number: 7
+    :text: |2
+       <span id="LC7" class="line">  <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7
+  :right:
+    :type: 
+    :number: 7
+    :text: |2
+       <span id="LC7" class="line">  <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_7_7
+- :left:
+    :type: 
+    :number: 8
+    :text: |2
+       <span id="LC8" class="line">    <span class="k">unless</span> <span class="n">cmd</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="no">Array</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_8_8
+  :right:
+    :type: 
+    :number: 8
+    :text: |2
+       <span id="LC8" class="line">    <span class="k">unless</span> <span class="n">cmd</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="no">Array</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_8_8
+- :left:
+    :type: old
+    :number: 9
+    :text: |
+      -<span id="LC9" class="line">      <span class="k">raise</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_9_9
+  :right:
+    :type: new
+    :number: 9
+    :text: |
+      +<span id="LC9" class="line">      <span class="k">raise</span> <span class="no">RuntimeError</span><span class="p">,</span> <span class="s2">&quot;System commands must be given as an array of strings&quot;</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_9
+- :left:
+    :type: 
+    :number: 10
+    :text: |2
+       <span id="LC10" class="line">    <span class="k">end</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_10
+  :right:
+    :type: 
+    :number: 10
+    :text: |2
+       <span id="LC10" class="line">    <span class="k">end</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_10_10
+- :left:
+    :type: 
+    :number: 11
+    :text: |2
+       <span id="LC11" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_11_11
+  :right:
+    :type: 
+    :number: 11
+    :text: |2
+       <span id="LC11" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_11_11
+- :left:
+    :type: 
+    :number: 12
+    :text: |2
+       <span id="LC12" class="line">    <span class="n">path</span> <span class="o">||=</span> <span class="no">Dir</span><span class="p">.</span><span class="nf">pwd</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_12_12
+  :right:
+    :type: 
+    :number: 12
+    :text: |2
+       <span id="LC12" class="line">    <span class="n">path</span> <span class="o">||=</span> <span class="no">Dir</span><span class="p">.</span><span class="nf">pwd</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_12_12
+- :left:
+    :type: old
+    :number: 13
+    :text: |
+      -<span id="LC13" class="line">    <span class="n">vars</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">&quot;PWD&quot;</span> <span class="o">=&gt;</span> <span class="n">path</span> <span class="p">}</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_13_13
+  :right:
+    :type: old
+    :number: 
+    :text: ''
+    :line_code: 
+- :left:
+    :type: old
+    :number: 14
+    :text: |
+      -<span id="LC14" class="line">    <span class="n">options</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">chdir: </span><span class="n">path</span> <span class="p">}</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_14_13
+  :right:
+    :type: new
+    :number: 13
+    :text: |
+      +<span id="LC13" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_13
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14
+  :right:
+    :type: new
+    :number: 14
+    :text: |
+      +<span id="LC14" class="line">    <span class="n">vars</span> <span class="o">=</span> <span class="p">{</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_14
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15
+  :right:
+    :type: new
+    :number: 15
+    :text: |
+      +<span id="LC15" class="line">      <span class="s2">&quot;PWD&quot;</span> <span class="o">=&gt;</span> <span class="n">path</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_15
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_16
+  :right:
+    :type: new
+    :number: 16
+    :text: |
+      +<span id="LC16" class="line">    <span class="p">}</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_16
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_17
+  :right:
+    :type: new
+    :number: 17
+    :text: |
+      +<span id="LC17" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_17
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_18
+  :right:
+    :type: new
+    :number: 18
+    :text: |
+      +<span id="LC18" class="line">    <span class="n">options</span> <span class="o">=</span> <span class="p">{</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_18
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_19
+  :right:
+    :type: new
+    :number: 19
+    :text: |
+      +<span id="LC19" class="line">      <span class="ss">chdir: </span><span class="n">path</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_19
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_20
+  :right:
+    :type: new
+    :number: 20
+    :text: |
+      +<span id="LC20" class="line">    <span class="p">}</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_20
+- :left:
+    :type: 
+    :number: 15
+    :text: |2
+       <span id="LC21" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_21
+  :right:
+    :type: 
+    :number: 21
+    :text: |2
+       <span id="LC21" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_15_21
+- :left:
+    :type: 
+    :number: 16
+    :text: |2
+       <span id="LC22" class="line">    <span class="k">unless</span> <span class="no">File</span><span class="p">.</span><span class="nf">directory?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_16_22
+  :right:
+    :type: 
+    :number: 22
+    :text: |2
+       <span id="LC22" class="line">    <span class="k">unless</span> <span class="no">File</span><span class="p">.</span><span class="nf">directory?</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_16_22
+- :left:
+    :type: 
+    :number: 17
+    :text: |2
+       <span id="LC23" class="line">      <span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_17_23
+  :right:
+    :type: 
+    :number: 23
+    :text: |2
+       <span id="LC23" class="line">      <span class="no">FileUtils</span><span class="p">.</span><span class="nf">mkdir_p</span><span class="p">(</span><span class="n">path</span><span class="p">)</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_17_23
+- :left:
+    :type: match
+    :number: 19
+    :text: "@@ -19,6 +25,7 @@ module Popen"
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
+  :right:
+    :type: match
+    :number: 25
+    :text: "@@ -19,6 +25,7 @@ module Popen"
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
+- :left:
+    :type: 
+    :number: 19
+    :text: |2
+       <span id="LC25" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
+  :right:
+    :type: 
+    :number: 25
+    :text: |2
+       <span id="LC25" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_19_25
+- :left:
+    :type: 
+    :number: 20
+    :text: |2
+       <span id="LC26" class="line">    <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26
+  :right:
+    :type: 
+    :number: 26
+    :text: |2
+       <span id="LC26" class="line">    <span class="vi">@cmd_output</span> <span class="o">=</span> <span class="s2">&quot;&quot;</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_20_26
+- :left:
+    :type: 
+    :number: 21
+    :text: |2
+       <span id="LC27" class="line">    <span class="vi">@cmd_status</span> <span class="o">=</span> <span class="mi">0</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_21_27
+  :right:
+    :type: 
+    :number: 27
+    :text: |2
+       <span id="LC27" class="line">    <span class="vi">@cmd_status</span> <span class="o">=</span> <span class="mi">0</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_21_27
+- :left:
+    :type: 
+    :number: 
+    :text: ''
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_28
+  :right:
+    :type: new
+    :number: 28
+    :text: |
+      +<span id="LC28" class="line"></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_28
+- :left:
+    :type: 
+    :number: 22
+    :text: |2
+       <span id="LC29" class="line">    <span class="no">Open3</span><span class="p">.</span><span class="nf">popen3</span><span class="p">(</span><span class="n">vars</span><span class="p">,</span> <span class="o">*</span><span class="n">cmd</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">wait_thr</span><span class="o">|</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_29
+  :right:
+    :type: 
+    :number: 29
+    :text: |2
+       <span id="LC29" class="line">    <span class="no">Open3</span><span class="p">.</span><span class="nf">popen3</span><span class="p">(</span><span class="n">vars</span><span class="p">,</span> <span class="o">*</span><span class="n">cmd</span><span class="p">,</span> <span class="n">options</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">stdin</span><span class="p">,</span> <span class="n">stdout</span><span class="p">,</span> <span class="n">stderr</span><span class="p">,</span> <span class="n">wait_thr</span><span class="o">|</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_22_29
+- :left:
+    :type: 
+    :number: 23
+    :text: |2
+       <span id="LC30" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stdout</span><span class="p">.</span><span class="nf">read</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_23_30
+  :right:
+    :type: 
+    :number: 30
+    :text: |2
+       <span id="LC30" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stdout</span><span class="p">.</span><span class="nf">read</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_23_30
+- :left:
+    :type: 
+    :number: 24
+    :text: |2
+       <span id="LC31" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stderr</span><span class="p">.</span><span class="nf">read</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_24_31
+  :right:
+    :type: 
+    :number: 31
+    :text: |2
+       <span id="LC31" class="line">      <span class="vi">@cmd_output</span> <span class="o">&lt;&lt;</span> <span class="n">stderr</span><span class="p">.</span><span class="nf">read</span></span>
+    :line_code: 2f6fcd96b88b36ce98c38da085c795a27d92a3dd_24_31
diff --git a/spec/helpers/diff_helper_spec.rb b/spec/helpers/diff_helper_spec.rb
index 4b10ee3d33c..435ecd04fbe 100644
--- a/spec/helpers/diff_helper_spec.rb
+++ b/spec/helpers/diff_helper_spec.rb
@@ -8,8 +8,8 @@ describe DiffHelper do
   let(:commit) { project.commit(sample_commit.id) }
   let(:diffs) { commit.diffs }
   let(:diff) { diffs.first }
-  let(:diff_refs) { [commit.parent.id, commit.id] }
-  let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs, repository) }
+  let(:diff_refs) { [commit.parent, commit] }
+  let(:diff_file) { Gitlab::Diff::File.new(diff, diff_refs) }
 
   describe 'diff_hard_limit_enabled?' do
     it 'should return true if param is provided' do
@@ -46,41 +46,41 @@ describe DiffHelper do
 
   describe 'safe_diff_files' do
     it 'should return all files from a commit that is smaller than safe limits' do
-      expect(safe_diff_files(diffs, diff_refs, repository).length).to eq(2)
+      expect(safe_diff_files(diffs, diff_refs).length).to eq(2)
     end
 
     it 'should return only the first file if the diff line count in the 2nd file takes the total beyond safe limits' do
       allow(diffs[1].diff).to receive(:lines).and_return([""] * 4999) #simulate 4999 lines
-      expect(safe_diff_files(diffs, diff_refs, repository).length).to eq(1)
+      expect(safe_diff_files(diffs, diff_refs).length).to eq(1)
     end
 
     it 'should return all files from a commit that is beyond safe limit for numbers of lines if force diff is true' do
       allow(controller).to receive(:params) { { force_show_diff: true } }
       allow(diffs[1].diff).to receive(:lines).and_return([""] * 4999) #simulate 4999 lines
-      expect(safe_diff_files(diffs, diff_refs, repository).length).to eq(2)
+      expect(safe_diff_files(diffs, diff_refs).length).to eq(2)
     end
 
     it 'should return only the first file if the diff line count in the 2nd file takes the total beyond hard limits' do
       allow(controller).to receive(:params) { { force_show_diff: true } }
       allow(diffs[1].diff).to receive(:lines).and_return([""] * 49999) #simulate 49999 lines
-      expect(safe_diff_files(diffs, diff_refs, repository).length).to eq(1)
+      expect(safe_diff_files(diffs, diff_refs).length).to eq(1)
     end
 
     it 'should return only a safe number of file diffs if a commit touches more files than the safe limits' do
       large_diffs = diffs * 100 #simulate 200 diffs
-      expect(safe_diff_files(large_diffs, diff_refs, repository).length).to eq(100)
+      expect(safe_diff_files(large_diffs, diff_refs).length).to eq(100)
     end
 
     it 'should return all file diffs if a commit touches more files than the safe limits but force diff is true' do
       allow(controller).to receive(:params) { { force_show_diff: true } }
       large_diffs = diffs * 100 #simulate 200 diffs
-      expect(safe_diff_files(large_diffs, diff_refs, repository).length).to eq(200)
+      expect(safe_diff_files(large_diffs, diff_refs).length).to eq(200)
     end
 
     it 'should return a limited file diffs if a commit touches more files than the hard limits and force diff is true' do
       allow(controller).to receive(:params) { { force_show_diff: true } }
       very_large_diffs = diffs * 1000 #simulate 2000 diffs
-      expect(safe_diff_files(very_large_diffs, diff_refs, repository).length).to eq(1000)
+      expect(safe_diff_files(very_large_diffs, diff_refs).length).to eq(1000)
     end
   end
 
@@ -128,7 +128,11 @@ describe DiffHelper do
       expect(diff_line_content(diff_file.diff_lines.first.text)).
         to eq('@@ -6,12 +6,18 @@ module Popen')
       expect(diff_line_content(diff_file.diff_lines.first.type)).to eq('match')
-      expect(diff_line_content(diff_file.diff_lines.first.new_pos)).to eq(6)
+      expect(diff_file.diff_lines.first.new_pos).to eq(6)
+    end
+
+    it 'should return safe HTML' do
+      expect(diff_line_content(diff_file.diff_lines.first.text)).to be_html_safe
     end
   end
 
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index 97ba7f14eb1..0d9694f2c13 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::Diff::File, lib: true do
   let(:project) { create(:project) }
   let(:commit) { project.commit(sample_commit.id) }
   let(:diff) { commit.diffs.first }
-  let(:diff_file) { Gitlab::Diff::File.new(diff, [commit.parent.id, commit.id], project.repository) }
+  let(:diff_file) { Gitlab::Diff::File.new(diff, [commit.parent, commit]) }
 
   describe :diff_lines do
     let(:diff_lines) { diff_file.diff_lines }
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index 3c66c9889ba..f307dcaae44 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::Diff::Highlight, lib: true do
   let(:project) { create(:project) }
   let(:commit) { project.commit(sample_commit.id) }
   let(:diff) { commit.diffs.first }
-  let(:diff_file) { Gitlab::Diff::File.new(diff, [commit.parent.id, commit.id], project.repository) }
+  let(:diff_file) { Gitlab::Diff::File.new(diff, [commit.parent, commit]) }
 
   describe '.process_diff_lines' do
     context 'when processing Gitlab::Diff::Line objects' do
-- 
GitLab