Commit e1bdb165 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #5014 from bladealslayer/feature/big-commit-improvements

Improved large commit handling.
parents 71d31a38 01ff084a
......@@ -11,7 +11,7 @@ class MergeRequest
constructor: (@opts) ->
this.$el = $('.merge-request')
@diffs_loaded = false
@diffs_loaded = if @opts.action == 'diffs' then true else false
@commits_loaded = false
this.activateTab(@opts.action)
......
......@@ -20,7 +20,8 @@ class CommitLoadContext < BaseContext
result[:notes_count] = project.notes.for_commit_id(commit.id).count
begin
result[:suppress_diff] = true if commit.diffs.size > Commit::DIFF_SAFE_SIZE && !params[:force_show_diff]
result[:suppress_diff] = true if commit.diff_suppress? && !params[:force_show_diff]
result[:force_suppress_diff] = commit.diff_force_suppress?
rescue Grit::Git::GitTimeout
result[:suppress_diff] = true
result[:status] = :huge_commit
......
......@@ -18,6 +18,7 @@ class Projects::CommitController < Projects::ApplicationController
end
@suppress_diff = result[:suppress_diff]
@force_suppress_diff = result[:force_suppress_diff]
@note = result[:note]
@line_notes = result[:line_notes]
......
......@@ -15,6 +15,10 @@ class Projects::CompareController < Projects::ApplicationController
@diffs = compare.diffs
@refs_are_same = compare.same
@line_notes = []
diff_line_count = Commit::diff_line_count(@diffs)
@suppress_diff = Commit::diff_suppress?(@diffs, diff_line_count) && !params[:force_show_diff]
@force_suppress_diff = Commit::diff_force_suppress?(@diffs, diff_line_count)
end
def create
......
......@@ -40,6 +40,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@comments_target = {noteable_type: 'MergeRequest',
noteable_id: @merge_request.id}
@line_notes = @merge_request.notes.where("line_code is not null")
diff_line_count = Commit::diff_line_count(@merge_request.diffs)
@suppress_diff = Commit::diff_suppress?(@merge_request.diffs, diff_line_count) && !params[:force_show_diff]
@force_suppress_diff = Commit::diff_force_suppress?(@merge_request.diffs, diff_line_count)
end
def new
......
......@@ -6,15 +6,41 @@ class Commit
attr_mentionable :safe_message
# Safe amount of files with diffs in one commit to render
# Safe amount of changes (files and lines) in one commit to render
# Used to prevent 500 error on huge commits by suppressing diff
#
DIFF_SAFE_SIZE = 100
# User can force display of diff above this size
DIFF_SAFE_FILES = 100
DIFF_SAFE_LINES = 5000
# Commits above this size will not be rendered in HTML
DIFF_HARD_LIMIT_FILES = 500
DIFF_HARD_LIMIT_LINES = 10000
def self.decorate(commits)
commits.map { |c| self.new(c) }
end
# Calculate number of lines to render for diffs
def self.diff_line_count(diffs)
diffs.reduce(0){|sum, d| sum + d.diff.lines.count}
end
def self.diff_suppress?(diffs, line_count = nil)
# optimize - check file count first
return true if diffs.size > DIFF_SAFE_FILES
line_count ||= Commit::diff_line_count(diffs)
line_count > DIFF_SAFE_LINES
end
def self.diff_force_suppress?(diffs, line_count = nil)
# optimize - check file count first
return true if diffs.size > DIFF_HARD_LIMIT_FILES
line_count ||= Commit::diff_line_count(diffs)
line_count > DIFF_HARD_LIMIT_LINES
end
attr_accessor :raw
def initialize(raw_commit)
......@@ -27,6 +53,19 @@ class Commit
@raw.id
end
def diff_line_count
@diff_line_count ||= Commit::diff_line_count(self.diffs)
@diff_line_count
end
def diff_suppress?
Commit::diff_suppress?(self.diffs, diff_line_count)
end
def diff_force_suppress?
Commit::diff_force_suppress?(self.diffs, diff_line_count)
end
# Returns a string describing the commit for use in a link title
#
# Example
......
- @suppress_diff ||= @suppress_diff || @force_suppress_diff
- if @suppress_diff
.alert.alert-block
%p
%strong Warning! Large commit with more than #{Commit::DIFF_SAFE_SIZE} files changed.
%p To preserve performance the diff is not shown.
%strong Warning! This is a large diff.
%p
But if you still want to see the diff
= link_to "click this link", project_commit_path(project, @commit, force_show_diff: true), class: "underlined_link"
To preserve performance the diff is not shown.
- if current_controller?(:commit) or current_controller?(:merge_requests)
Please, download the diff as
- if current_controller?(:commit)
= link_to "plain diff", project_commit_path(@project, @commit, format: :diff), class: "underlined_link"
or
= link_to "email patch", project_commit_path(@project, @commit, format: :patch), class: "underlined_link"
- else
= link_to "plain diff", project_merge_request_path(@project, @merge_request, format: :diff), class: "underlined_link"
or
= link_to "email patch", project_merge_request_path(@project, @merge_request, format: :patch), class: "underlined_link"
instead.
- unless @force_suppress_diff
%p
If you still want to see the diff
= link_to "click this link", url_for(force_show_diff: true), class: "underlined_link"
%p.commit-stat-summary
Showing
......
......@@ -27,3 +27,11 @@ Feature: Project Browse commits
Scenario: I browse commits stats
Given I visit my project's commits stats page
Then I see commits stats
Scenario: I browse big commit
Given I visit big commit page
Then I see big commit warning
Scenario: I browse huge commit
Given I visit huge commit page
Then I see huge commit message
......@@ -58,4 +58,24 @@ class ProjectBrowseCommits < Spinach::FeatureSteps
page.should have_content 'Total commits'
page.should have_content 'Authors'
end
Given 'I visit big commit page' do
visit project_commit_path(@project, BigCommits::BIG_COMMIT_ID)
end
Then 'I see big commit warning' do
page.should have_content BigCommits::BIG_COMMIT_MESSAGE
page.should have_content "Warning! This is a large diff"
page.should have_content "If you still want to see the diff"
end
Given 'I visit huge commit page' do
visit project_commit_path(@project, BigCommits::HUGE_COMMIT_ID)
end
Then 'I see huge commit message' do
page.should have_content BigCommits::HUGE_COMMIT_MESSAGE
page.should have_content "Warning! This is a large diff"
page.should_not have_content "If you still want to see the diff"
end
end
......@@ -14,7 +14,7 @@ require 'spinach/capybara'
require 'sidekiq/testing/inline'
%w(valid_commit select2_helper chosen_helper test_env).each do |f|
%w(valid_commit big_commits select2_helper chosen_helper test_env).each do |f|
require Rails.root.join('spec', 'support', f)
end
......
module BigCommits
HUGE_COMMIT_ID = "7f92534f767fa20357a11c63f973ae3b79cc5b85"
HUGE_COMMIT_MESSAGE = "pybments.rb version up. gitignore improved"
BIG_COMMIT_ID = "d62200cad430565bd9f80befaf329297120330b5"
BIG_COMMIT_MESSAGE = "clean-up code"
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