Save and use actual diff base commit for MR diff highlighting
This commit is contained in:
		
							parent
							
								
									26f7d023e6
								
							
						
					
					
						commit
						577f2fb47a
					
				| 
						 | 
				
			
			@ -21,8 +21,8 @@ class Projects::CompareController < Projects::ApplicationController
 | 
			
		|||
      @commits = Commit.decorate(compare_result.commits, @project)
 | 
			
		||||
      @diffs = compare_result.diffs
 | 
			
		||||
      @commit = @project.commit(head_ref)
 | 
			
		||||
      @first_commit = @project.commit(base_ref)
 | 
			
		||||
      @diff_refs = [@first_commit, @commit]
 | 
			
		||||
      @base_commit = @project.commit(base_ref)
 | 
			
		||||
      @diff_refs = [@base_commit, @commit]
 | 
			
		||||
      @line_notes = []
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,7 +58,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
 | 
			
		|||
 | 
			
		||||
  def diffs
 | 
			
		||||
    @commit = @merge_request.last_commit
 | 
			
		||||
    @first_commit = @merge_request.first_commit
 | 
			
		||||
    @base_commit = @merge_request.diff_base_commit
 | 
			
		||||
 | 
			
		||||
    # MRs created before 8.4 don't have a diff_base_commit,
 | 
			
		||||
    # but we need it for the "View file @ ..." link by deleted files
 | 
			
		||||
    @base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
 | 
			
		||||
 | 
			
		||||
    @comments_allowed = @reply_allowed = true
 | 
			
		||||
    @comments_target = {
 | 
			
		||||
| 
						 | 
				
			
			@ -102,7 +106,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
 | 
			
		|||
    @source_project = merge_request.source_project
 | 
			
		||||
    @commits = @merge_request.compare_commits.reverse
 | 
			
		||||
    @commit = @merge_request.last_commit
 | 
			
		||||
    @first_commit = @merge_request.first_commit
 | 
			
		||||
    @base_commit = @merge_request.diff_base_commit
 | 
			
		||||
    @diffs = @merge_request.compare_diffs
 | 
			
		||||
 | 
			
		||||
    @ci_commit = @merge_request.ci_commit
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -102,8 +102,7 @@ module DiffHelper
 | 
			
		|||
 | 
			
		||||
  def commit_for_diff(diff)
 | 
			
		||||
    if diff.deleted_file
 | 
			
		||||
      first_commit = @first_commit || @commit
 | 
			
		||||
      first_commit.parent || @first_commit
 | 
			
		||||
      @base_commit || @commit.parent || @commit
 | 
			
		||||
    else
 | 
			
		||||
      @commit
 | 
			
		||||
    end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -180,6 +180,14 @@ class MergeRequest < ActiveRecord::Base
 | 
			
		|||
    merge_request_diff ? merge_request_diff.first_commit : compare_commits.first
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def diff_base_commit
 | 
			
		||||
    if merge_request_diff
 | 
			
		||||
      merge_request_diff.base_commit
 | 
			
		||||
    else
 | 
			
		||||
      self.target_project.commit(self.target_branch)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def last_commit_short_sha
 | 
			
		||||
    last_commit.short_id
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -477,8 +485,7 @@ class MergeRequest < ActiveRecord::Base
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def target_sha
 | 
			
		||||
    @target_sha ||= target_project.
 | 
			
		||||
      repository.commit(target_branch).sha
 | 
			
		||||
    @target_sha ||= target_project.repository.commit(target_branch).sha
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def source_sha
 | 
			
		||||
| 
						 | 
				
			
			@ -519,6 +526,8 @@ class MergeRequest < ActiveRecord::Base
 | 
			
		|||
  end
 | 
			
		||||
 | 
			
		||||
  def diff_refs
 | 
			
		||||
    [first_commit.parent || first_commit, last_commit]
 | 
			
		||||
    return nil unless diff_base_commit
 | 
			
		||||
 | 
			
		||||
    [diff_base_commit, last_commit]
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,6 +73,12 @@ class MergeRequestDiff < ActiveRecord::Base
 | 
			
		|||
    commits.last
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def base_commit
 | 
			
		||||
    return nil unless self.base_commit_sha
 | 
			
		||||
 | 
			
		||||
    merge_request.target_project.commit(self.base_commit_sha)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def last_commit_short_sha
 | 
			
		||||
    @last_commit_short_sha ||= last_commit.short_id
 | 
			
		||||
  end
 | 
			
		||||
| 
						 | 
				
			
			@ -156,6 +162,9 @@ class MergeRequestDiff < ActiveRecord::Base
 | 
			
		|||
    end
 | 
			
		||||
 | 
			
		||||
    self.st_diffs = new_diffs
 | 
			
		||||
 | 
			
		||||
    self.base_commit_sha = merge_request.target_project.commit(target_branch).try(:sha)
 | 
			
		||||
 | 
			
		||||
    self.save
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,5 @@
 | 
			
		|||
class AddBaseCommitShaToMergeRequestDiffs < ActiveRecord::Migration
 | 
			
		||||
  def change
 | 
			
		||||
    add_column :merge_request_diffs, :base_commit_sha, :string
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,7 @@
 | 
			
		|||
#
 | 
			
		||||
# It's strongly recommended that you check this file into your version control system.
 | 
			
		||||
 | 
			
		||||
ActiveRecord::Schema.define(version: 20160119145451) do
 | 
			
		||||
ActiveRecord::Schema.define(version: 20160120172143) do
 | 
			
		||||
 | 
			
		||||
  # These are extensions that must be enabled in order to support this database
 | 
			
		||||
  enable_extension "plpgsql"
 | 
			
		||||
| 
						 | 
				
			
			@ -490,6 +490,7 @@ ActiveRecord::Schema.define(version: 20160119145451) do
 | 
			
		|||
    t.integer  "merge_request_id", null: false
 | 
			
		||||
    t.datetime "created_at"
 | 
			
		||||
    t.datetime "updated_at"
 | 
			
		||||
    t.string   "base_commit_sha"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  add_index "merge_request_diffs", ["merge_request_id"], name: "index_merge_request_diffs_on_merge_request_id", unique: true, using: :btree
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,14 +1,22 @@
 | 
			
		|||
module Gitlab
 | 
			
		||||
  module Diff
 | 
			
		||||
    class File
 | 
			
		||||
      attr_reader :diff, :new_ref, :old_ref
 | 
			
		||||
      attr_reader :diff, :diff_refs
 | 
			
		||||
 | 
			
		||||
      delegate :new_file, :deleted_file, :renamed_file,
 | 
			
		||||
        :old_path, :new_path, to: :diff, prefix: false
 | 
			
		||||
 | 
			
		||||
      def initialize(diff, diff_refs)
 | 
			
		||||
        @diff = diff
 | 
			
		||||
        @old_ref, @new_ref = diff_refs
 | 
			
		||||
        @diff_refs = diff_refs
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def old_ref
 | 
			
		||||
        diff_refs[0] if diff_refs
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def new_ref
 | 
			
		||||
        diff_refs[1] if diff_refs
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      # Array of Gitlab::DIff::Line objects
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,8 @@ module Gitlab
 | 
			
		|||
      private
 | 
			
		||||
 | 
			
		||||
      def highlight_line(diff_line, index)
 | 
			
		||||
        return html_escape(diff_line.text) unless diff_file.diff_refs
 | 
			
		||||
 | 
			
		||||
        line_prefix = diff_line.text.match(/\A([+-])/) ? $1 : ' '
 | 
			
		||||
 | 
			
		||||
        case diff_line.type
 | 
			
		||||
| 
						 | 
				
			
			@ -42,7 +44,7 @@ module Gitlab
 | 
			
		|||
 | 
			
		||||
        # Only update text if line is found. This will prevent
 | 
			
		||||
        # issues with submodules given the line only exists in diff content.
 | 
			
		||||
        rich_line ? line_prefix + rich_line : diff_line.text
 | 
			
		||||
        rich_line ? line_prefix + rich_line : html_escape(diff_line.text)
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def inline_diffs
 | 
			
		||||
| 
						 | 
				
			
			@ -63,6 +65,11 @@ module Gitlab
 | 
			
		|||
 | 
			
		||||
        [ref.project.repository, ref.id, path]
 | 
			
		||||
      end
 | 
			
		||||
 | 
			
		||||
      def html_escape(str)
 | 
			
		||||
        replacements = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' }
 | 
			
		||||
        str.gsub(/[&"'><]/, replacements)
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,18 +9,19 @@ module Gitlab
 | 
			
		|||
      end
 | 
			
		||||
 | 
			
		||||
      def mark(line_inline_diffs)
 | 
			
		||||
        offset = 0
 | 
			
		||||
        marker_ranges = []
 | 
			
		||||
        line_inline_diffs.each do |inline_diff_range|
 | 
			
		||||
          # Map the inline-diff range based on the raw line to character positions in the rich line
 | 
			
		||||
          inline_diff_positions = position_mapping[inline_diff_range].flatten
 | 
			
		||||
          # Turn the array of character positions into ranges
 | 
			
		||||
          marker_ranges = collapse_ranges(inline_diff_positions)
 | 
			
		||||
          marker_ranges.concat(collapse_ranges(inline_diff_positions))
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        offset = 0
 | 
			
		||||
        # Mark each range
 | 
			
		||||
        marker_ranges.each do |range|
 | 
			
		||||
          offset = insert_around_range(rich_line, range, "<span class='idiff'>", "</span>", offset)
 | 
			
		||||
        end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        rich_line
 | 
			
		||||
      end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue