new diff; in progress
This commit is contained in:
parent
f5a68ed4ae
commit
f202d1d449
2
Gemfile
2
Gemfile
|
@ -30,7 +30,7 @@ gem 'state_machines-activerecord'
|
||||||
gem 'redis-rails'
|
gem 'redis-rails'
|
||||||
|
|
||||||
gem 'grack', git: 'git://github.com/rosa-abf/grack.git', require: 'git_http'
|
gem 'grack', git: 'git://github.com/rosa-abf/grack.git', require: 'git_http'
|
||||||
gem 'grit', git: 'git://github.com/rosa-abf/grit.git', tag: '2.6.16'
|
gem 'grit', git: 'git://github.com/rosa-abf/grit.git', tag: '2.6.17'
|
||||||
gem 'charlock_holmes'
|
gem 'charlock_holmes'
|
||||||
gem 'github-linguist', '3.1.5', require: 'linguist'
|
gem 'github-linguist', '3.1.5', require: 'linguist'
|
||||||
gem 'diff-display'
|
gem 'diff-display'
|
||||||
|
|
|
@ -41,8 +41,8 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: git://github.com/rosa-abf/grit.git
|
remote: git://github.com/rosa-abf/grit.git
|
||||||
revision: a9548c92188cc307e7af1dd41a733e7000a783a9
|
revision: b733f0ceefb44b18a9dec8f509ba5493dab59e4e
|
||||||
tag: 2.6.16
|
tag: 2.6.17
|
||||||
specs:
|
specs:
|
||||||
grit (2.5.0)
|
grit (2.5.0)
|
||||||
diff-lcs (~> 1.1)
|
diff-lcs (~> 1.1)
|
||||||
|
|
|
@ -1,23 +1,35 @@
|
||||||
module CommitHelper
|
module CommitHelper
|
||||||
MAX_FILES_WITHOUT_COLLAPSE = 25
|
MAX_FILES_WITHOUT_COLLAPSE = 25
|
||||||
|
|
||||||
def render_commit_stats(stats)
|
def render_commit_stats(stats, diff)
|
||||||
res = ["<table class='table table-responsive boffset0'>"]
|
res = ["<ul class='list-group boffset0'>"]
|
||||||
ind=0
|
ind=0
|
||||||
stats.files.each do |filename, adds, deletes, total|
|
stats.files.each do |filename, adds, deletes, total|
|
||||||
res << "<tr>"
|
file_name = if diff[ind].renamed_file
|
||||||
res << "<td><a href='#diff-#{ind}'>#{h(filename.rtruncate 120)}</a></td>"
|
"#{diff[ind].a_path.rtruncate 60}=>#{diff[ind].b_path.rtruncate 60}"
|
||||||
res << "<td class='diffstat'>"
|
else
|
||||||
res << I18n.t("layout.projects.inline_changes_count", count: total).strip +
|
filename.rtruncate(120)
|
||||||
" (" +
|
end
|
||||||
I18n.t("layout.projects.inline_additions_count", count: adds).strip +
|
|
||||||
", " +
|
res << "<li class='list-group-item'>"
|
||||||
I18n.t("layout.projects.inline_deletions_count", count: deletes).strip +
|
res << "<div class='row'>"
|
||||||
")"
|
res << "<div class='col-sm-8'><a href='#diff-#{ind}'>#{diff_file_icon(diff[ind])} #{h(file_name)}</a></div>"
|
||||||
res << "</td>"
|
|
||||||
|
res << "<div class='col-sm-2'>"
|
||||||
|
res << "<div class='pull-right'>"
|
||||||
|
res << "<strong class='text-success'>+#{adds}</strong> <strong class='text-danger'>-#{deletes}</strong>"
|
||||||
|
res << "</div>"
|
||||||
|
res << "</div>"
|
||||||
|
|
||||||
|
res << "<div class='col-sm-2'>"
|
||||||
|
res << render_progress_bar(adds, deletes)
|
||||||
|
res << "</div>"
|
||||||
|
|
||||||
|
res << "</div"
|
||||||
|
res << "</li>"
|
||||||
ind +=1
|
ind +=1
|
||||||
end
|
end
|
||||||
res << "</table>"
|
res << "</ul>"
|
||||||
|
|
||||||
wrap_commit_header_list(stats, res)
|
wrap_commit_header_list(stats, res)
|
||||||
end
|
end
|
||||||
|
@ -73,9 +85,41 @@ module CommitHelper
|
||||||
Russian.p(commits_count, *commits_pluralization_arr)
|
Russian.p(commits_count, *commits_pluralization_arr)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def is_file_open_in_diff(blob, diff)
|
||||||
|
return true if blob.binary? && blob.render_as == :image
|
||||||
|
return true if diff.diff.blank? && diff.a_mode != diff.b_mode
|
||||||
|
diff.diff.present? && diff.diff.split("\n").count <= DiffHelper::MAX_LINES_WITHOUT_COLLAPSE
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def commits_pluralization_arr
|
def commits_pluralization_arr
|
||||||
pluralize ||= t('layout.commits.pluralize').map {|base, title| title.to_s}
|
pluralize ||= t('layout.commits.pluralize').map {|base, title| title.to_s}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def render_progress_bar(adds, deletes)
|
||||||
|
return if adds+deletes == 0
|
||||||
|
res = ''
|
||||||
|
pluses = ((adds/(adds+deletes).to_f)*100).round
|
||||||
|
minuses = 100 - pluses
|
||||||
|
|
||||||
|
res << "<div class='progress' style='margin-bottom: 0'>"
|
||||||
|
res << "<div class='progress-bar progress-bar-success' style='width: #{pluses}%'></div>"
|
||||||
|
res << "<div class='progress-bar progress-bar-danger' style='width: #{minuses}%'></div>"
|
||||||
|
res << "</div>"
|
||||||
|
res
|
||||||
|
end
|
||||||
|
|
||||||
|
def diff_file_icon(diff)
|
||||||
|
icon = if diff.renamed_file
|
||||||
|
'fa-caret-square-o-right text-info'
|
||||||
|
elsif diff.new_file
|
||||||
|
'fa-plus-square text-success'
|
||||||
|
elsif diff.deleted_file
|
||||||
|
'fa-minus-square text-danger'
|
||||||
|
else
|
||||||
|
'fa-pencil-square text-warning'
|
||||||
|
end
|
||||||
|
"<i class='fa #{icon}'></i>"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ module DiffHelper
|
||||||
MAX_FILES_WITHOUT_COLLAPSE = 25
|
MAX_FILES_WITHOUT_COLLAPSE = 25
|
||||||
MAX_LINES_WITHOUT_COLLAPSE = 50
|
MAX_LINES_WITHOUT_COLLAPSE = 50
|
||||||
|
|
||||||
def render_diff_stats(stats)
|
def render_diff_stats(stats, diff)
|
||||||
res = ["<table class='table table-responsive boffset0'>"]
|
res = ["<table class='table table-responsive boffset0'>"]
|
||||||
stats.each_with_index do |stat, ind|
|
stats.each_with_index do |stat, ind|
|
||||||
res << "<tr>"
|
res << "<tr>"
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
- commit_id = diff.deleted_file ? parent_commit.try(:id) : @commit.id
|
- commit_id = diff.deleted_file ? parent_commit.try(:id) : @commit.id
|
||||||
- diff_counter_content = "diff-#{diff_counter}_content"
|
- diff_counter_content = "diff-#{diff_counter}_content"
|
||||||
|
- if diff.renamed_file
|
||||||
- if diff.diff.present?
|
- blob = @project.repo.tree(commit_id) / diff.b_path
|
||||||
|
- else
|
||||||
- blob = @project.repo.tree(commit_id) / diff.a_path
|
- blob = @project.repo.tree(commit_id) / diff.a_path
|
||||||
- is_file_open = 'in' if !blob.binary? && diff.diff.split("\n").count <= DiffHelper::MAX_LINES_WITHOUT_COLLAPSE
|
|
||||||
|
- is_file_open = 'in' if is_file_open_in_diff(blob, diff)
|
||||||
|
|
||||||
.file.offset10
|
.file.offset10
|
||||||
a name = "diff-#{diff_counter}"
|
a name = "diff-#{diff_counter}"
|
||||||
|
@ -34,3 +36,5 @@
|
||||||
- if (@project.repo.tree(commit_id) / diff.b_path).nil?
|
- if (@project.repo.tree(commit_id) / diff.b_path).nil?
|
||||||
= "a_path=#{diff.a_path}; b_path=#{diff.b_path}"
|
= "a_path=#{diff.a_path}; b_path=#{diff.b_path}"
|
||||||
== render_diff(diff, diff_counter: diff_counter, comments: @comments)
|
== render_diff(diff, diff_counter: diff_counter, comments: @comments)
|
||||||
|
- if diff.a_mode != diff.b_mode && diff.diff.blank?
|
||||||
|
== render 'file_change_mode', blob: blob, diff: diff, diff_counter_content: diff_counter_content
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
- begin
|
- begin
|
||||||
- stats = @commit.stats
|
- diffs = @commit.show
|
||||||
= render_commit_stats(stats)
|
- stats = Grit::CommitStats.find_all(@project.repo, @commit.sha, max_count: 1, skip: 0, M: true)[0][-1]
|
||||||
|
= render_commit_stats(stats, diffs)
|
||||||
|
|
||||||
.pull-right
|
.pull-right
|
||||||
=> link_to 'raw diff', commit_path(@project, @commit.id, :diff)
|
=> link_to 'raw diff', commit_path(@project, @commit.id, :diff)
|
||||||
|
@ -8,6 +9,6 @@
|
||||||
=< link_to 'patch', commit_path(@project, @commit.id, :patch)
|
=< link_to 'patch', commit_path(@project, @commit.id, :patch)
|
||||||
.clearfix
|
.clearfix
|
||||||
|
|
||||||
== render partial: 'diff', collection: @commit.diffs, locals: { parent_commit: @commit.parents.try(:first) }
|
== render partial: 'diff', collection: diffs, locals: { parent_commit: @commit.parents.try(:first) }
|
||||||
- rescue Grit::Git::GitTimeout
|
- rescue Grit::Git::GitTimeout
|
||||||
h3.text-danger= t('layout.git.repositories.commit_diff_too_big')
|
h3.text-danger= t('layout.git.repositories.commit_diff_too_big')
|
||||||
|
|
|
@ -21,8 +21,9 @@
|
||||||
deletions: t("layout.projects.commit_deletions_count", count: total_deletions))
|
deletions: t("layout.projects.commit_deletions_count", count: total_deletions))
|
||||||
|
|
||||||
-begin
|
-begin
|
||||||
== render_diff_stats @stats
|
- diffs = @project.repo.diff @common_ancestor.id, @commit.id
|
||||||
- diffs = Grit::Commit.diff(@project.repo, @common_ancestor.id, @commit.id)
|
== render_diff_stats @stats, diffs
|
||||||
|
-# diffs = Grit::Commit.diff(@project.repo, @common_ancestor.id, @commit.id)
|
||||||
== render partial: 'projects/git/commits/diff', collection: diffs, locals: { parent_commit: @common_ancestor }
|
== render partial: 'projects/git/commits/diff', collection: diffs, locals: { parent_commit: @common_ancestor }
|
||||||
|
|
||||||
- rescue Grit::Git::GitTimeout
|
- rescue Grit::Git::GitTimeout
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
-begin
|
-begin
|
||||||
== render_diff_stats(@stats)
|
- diff = @pull.diff
|
||||||
== render partial: 'pull_diff', collection: @pull.diff
|
== render_diff_stats(@stats, diff)
|
||||||
|
== render partial: 'pull_diff', collection: diff
|
||||||
- rescue => ex
|
- rescue => ex
|
||||||
-if ex.try(:message) == 'Grit::Git::GitTimeout'
|
-if ex.try(:message) == 'Grit::Git::GitTimeout'
|
||||||
p= t 'layout.git.repositories.commit_diff_too_big'
|
p= t 'layout.git.repositories.commit_diff_too_big'
|
||||||
|
|
|
@ -7,7 +7,9 @@ class String
|
||||||
force_encoding(default_encoding)
|
force_encoding(default_encoding)
|
||||||
else # should encode
|
else # should encode
|
||||||
options = {invalid: :replace, undef: :replace, replace: ''}
|
options = {invalid: :replace, undef: :replace, replace: ''}
|
||||||
if (detected = detect_encoding) && detected[:encoding]
|
if encoding.name == 'UTF-8'
|
||||||
|
encode!(default_encoding, 'UTF-8', options)
|
||||||
|
elsif (detected = detect_encoding) && detected[:encoding]
|
||||||
force_encoding(detected[:encoding]).encode!(default_encoding, detected[:encoding], options)
|
force_encoding(detected[:encoding]).encode!(default_encoding, detected[:encoding], options)
|
||||||
end
|
end
|
||||||
scrub('')
|
scrub('')
|
||||||
|
|
|
@ -64,7 +64,6 @@ module Grit
|
||||||
|
|
||||||
def diff(a, b, *paths)
|
def diff(a, b, *paths)
|
||||||
diff = self.git.native('diff', {M: true}, "#{a}...#{b}", '--', *paths)
|
diff = self.git.native('diff', {M: true}, "#{a}...#{b}", '--', *paths)
|
||||||
|
|
||||||
if diff =~ /diff --git a/
|
if diff =~ /diff --git a/
|
||||||
diff = diff.sub(/.*?(diff --git a)/m, '\1')
|
diff = diff.sub(/.*?(diff --git a)/m, '\1')
|
||||||
else
|
else
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
require 'posix/spawn'
|
||||||
|
|
||||||
|
module POSIX
|
||||||
|
module Spawn
|
||||||
|
class Child
|
||||||
|
include POSIX::Spawn
|
||||||
|
private
|
||||||
|
# Start a select loop writing any input on the child's stdin and reading
|
||||||
|
# any output from the child's stdout or stderr.
|
||||||
|
#
|
||||||
|
# input - String input to write on stdin. May be nil.
|
||||||
|
# stdin - The write side IO object for the child's stdin stream.
|
||||||
|
# stdout - The read side IO object for the child's stdout stream.
|
||||||
|
# stderr - The read side IO object for the child's stderr stream.
|
||||||
|
# timeout - An optional Numeric specifying the total number of seconds
|
||||||
|
# the read/write operations should occur for.
|
||||||
|
#
|
||||||
|
# Returns an [out, err] tuple where both elements are strings with all
|
||||||
|
# data written to the stdout and stderr streams, respectively.
|
||||||
|
# Raises TimeoutExceeded when all data has not been read / written within
|
||||||
|
# the duration specified in the timeout argument.
|
||||||
|
# Raises MaximumOutputExceeded when the total number of bytes output
|
||||||
|
# exceeds the amount specified by the max argument.
|
||||||
|
def read_and_write(input, stdin, stdout, stderr, timeout=nil, max=nil)
|
||||||
|
max = nil if max && max <= 0
|
||||||
|
@out, @err = '', ''
|
||||||
|
offset = 0
|
||||||
|
|
||||||
|
# force all string and IO encodings to BINARY under 1.9 for now
|
||||||
|
#if @out.respond_to?(:force_encoding) and stdin.respond_to?(:set_encoding)
|
||||||
|
# [stdin, stdout, stderr].each do |fd|
|
||||||
|
# fd.set_encoding('BINARY', 'BINARY')
|
||||||
|
# end
|
||||||
|
# @out.force_encoding('BINARY')
|
||||||
|
# @err.force_encoding('BINARY')
|
||||||
|
# input = input.dup.force_encoding('BINARY') if input
|
||||||
|
#end
|
||||||
|
|
||||||
|
timeout = nil if timeout && timeout <= 0.0
|
||||||
|
@runtime = 0.0
|
||||||
|
start = Time.now
|
||||||
|
|
||||||
|
readers = [stdout, stderr]
|
||||||
|
writers =
|
||||||
|
if input
|
||||||
|
[stdin]
|
||||||
|
else
|
||||||
|
stdin.close
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
slice_method = input.respond_to?(:byteslice) ? :byteslice : :slice
|
||||||
|
t = timeout
|
||||||
|
|
||||||
|
while readers.any? || writers.any?
|
||||||
|
ready = IO.select(readers, writers, readers + writers, t)
|
||||||
|
raise TimeoutExceeded if ready.nil?
|
||||||
|
|
||||||
|
# write to stdin stream
|
||||||
|
ready[1].each do |fd|
|
||||||
|
begin
|
||||||
|
boom = nil
|
||||||
|
size = fd.write_nonblock(input)
|
||||||
|
input = input.send(slice_method, size..-1)
|
||||||
|
rescue Errno::EPIPE => boom
|
||||||
|
rescue Errno::EAGAIN, Errno::EINTR
|
||||||
|
end
|
||||||
|
if boom || input.bytesize == 0
|
||||||
|
stdin.close
|
||||||
|
writers.delete(stdin)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# read from stdout and stderr streams
|
||||||
|
ready[0].each do |fd|
|
||||||
|
buf = (fd == stdout) ? @out : @err
|
||||||
|
begin
|
||||||
|
buf << fd.readpartial(BUFSIZE)
|
||||||
|
rescue Errno::EAGAIN, Errno::EINTR
|
||||||
|
rescue EOFError
|
||||||
|
readers.delete(fd)
|
||||||
|
fd.close
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# keep tabs on the total amount of time we've spent here
|
||||||
|
@runtime = Time.now - start
|
||||||
|
if timeout
|
||||||
|
t = timeout - @runtime
|
||||||
|
raise TimeoutExceeded if t < 0.0
|
||||||
|
end
|
||||||
|
|
||||||
|
# maybe we've hit our max output
|
||||||
|
if max && ready[0].any? && (@out.size + @err.size) > max
|
||||||
|
raise MaximumOutputExceeded
|
||||||
|
end
|
||||||
|
end
|
||||||
|
[@out.mb_chars.default_encoding!, @err.mb_chars.default_encoding!]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue