Defect #8857 » 0001-Pass-revisions-to-git-log-via-stdin.patch
| lib/redmine/scm/adapters/abstract_adapter.rb | ||
|---|---|---|
| 206 | 206 |
self.class.logger |
| 207 | 207 |
end |
| 208 | 208 | |
| 209 |
def shellout(cmd, &block) |
|
| 210 |
self.class.shellout(cmd, &block) |
|
| 209 |
def shellout(cmd, options = {}, &block)
|
|
| 210 |
self.class.shellout(cmd, options, &block)
|
|
| 211 | 211 |
end |
| 212 | 212 | |
| 213 | 213 |
def self.logger |
| 214 | 214 |
Rails.logger |
| 215 | 215 |
end |
| 216 | 216 | |
| 217 |
def self.shellout(cmd, &block) |
|
| 217 |
def self.shellout(cmd, options = {}, &block)
|
|
| 218 | 218 |
if logger && logger.debug? |
| 219 | 219 |
logger.debug "Shelling out: #{strip_credential(cmd)}"
|
| 220 | 220 |
end |
| ... | ... | |
| 223 | 223 |
cmd = "#{cmd} 2>>#{shell_quote(Rails.root.join('log/scm.stderr.log').to_s)}"
|
| 224 | 224 |
end |
| 225 | 225 |
begin |
| 226 |
if RUBY_VERSION < '1.9' |
|
| 227 |
mode = "r+" |
|
| 228 |
else |
|
| 229 |
mode = "r+:ASCII-8BIT" |
|
| 230 |
end |
|
| 226 |
mode = (options[:mode] || 'r').to_s |
|
| 231 | 227 |
IO.popen(cmd, mode) do |io| |
| 232 |
io.close_write
|
|
| 228 |
io.set_encoding("ASCII-8BIT") if io.respond_to?(:set_encoding)
|
|
| 233 | 229 |
block.call(io) if block_given? |
| 234 | 230 |
end |
| 235 | 231 |
## If scm command does not exist, |
| lib/redmine/scm/adapters/git_adapter.rb | ||
|---|---|---|
| 197 | 197 | |
| 198 | 198 |
def revisions(path, identifier_from, identifier_to, options={})
|
| 199 | 199 |
revs = Revisions.new |
| 200 |
cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents| |
|
| 200 |
cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents --stdin|
|
|
| 201 | 201 |
cmd_args << "--reverse" if options[:reverse] |
| 202 | 202 |
cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit]
|
| 203 |
from_to = "" |
|
| 203 |
cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty? |
|
| 204 |
revisions = [] |
|
| 204 | 205 |
if identifier_from || identifier_to |
| 205 |
from_to << "#{identifier_from}.." if identifier_from
|
|
| 206 |
from_to << "#{identifier_to}" if identifier_to
|
|
| 207 |
cmd_args << from_to if !from_to.empty?
|
|
| 206 |
revisions << ""
|
|
| 207 |
revisions[0] << "#{identifier_from}.." if identifier_from
|
|
| 208 |
revisions[0] << "#{identifier_to}" if identifier_to
|
|
| 208 | 209 |
else |
| 209 |
cmd_args += options[:includes] unless options[:includes].blank? |
|
| 210 |
unless options[:includes].blank? |
|
| 211 |
revisions += ignore_missing_revisions(options[:includes]) |
|
| 212 |
end |
|
| 210 | 213 |
unless options[:excludes].blank? |
| 211 |
cmd_args << "--not"
|
|
| 212 |
cmd_args += options[:excludes]
|
|
| 214 |
revisions +=
|
|
| 215 |
ignore_missing_revisions(options[:excludes]).map{|r| "^#{r}"}
|
|
| 213 | 216 |
end |
| 214 | 217 |
end |
| 215 |
cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty? |
|
| 216 | 218 | |
| 217 |
scm_cmd *cmd_args do |io| |
|
| 219 |
scm_cmd(*cmd_args, :mode => "r+") do |io| |
|
| 220 |
io.puts(revisions.join("\n"))
|
|
| 221 |
io.close_write |
|
| 222 | ||
| 218 | 223 |
files=[] |
| 219 | 224 |
changeset = {}
|
| 220 | 225 |
parsing_descr = 0 #0: not parsing desc or files, 1: parsing desc, 2: parsing files |
| ... | ... | |
| 384 | 389 |
end |
| 385 | 390 | |
| 386 | 391 |
def scm_cmd(*args, &block) |
| 392 |
options = args.last.kind_of?(Hash) ? args.pop : {}
|
|
| 387 | 393 |
repo_path = root_url || url |
| 388 | 394 |
full_args = ['--git-dir', repo_path] |
| 389 | 395 |
if self.class.client_version_above?([1, 7, 2]) |
| ... | ... | |
| 393 | 399 |
full_args += args |
| 394 | 400 |
ret = shellout( |
| 395 | 401 |
self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
|
| 402 |
options, |
|
| 396 | 403 |
&block |
| 397 | 404 |
) |
| 398 | 405 |
if $? && $?.exitstatus != 0 |
| ... | ... | |
| 401 | 408 |
ret |
| 402 | 409 |
end |
| 403 | 410 |
private :scm_cmd |
| 411 | ||
| 412 |
# Return an array containing only the given revisions that exist in the |
|
| 413 |
# repository. |
|
| 414 |
# |
|
| 415 |
# NOTE: |
|
| 416 |
# This can be removed once the minimum supported Git version supports |
|
| 417 |
# the --ignore-missing option for git-log and #revisions is modified to |
|
| 418 |
# use that option. |
|
| 419 |
def ignore_missing_revisions(revisions) |
|
| 420 |
revisions.select do |revision| |
|
| 421 |
begin |
|
| 422 |
scm_cmd(*%w|rev-parse --verify --quiet|, revision) do |io| |
|
| 423 |
# Read and discard the output in order to make the command |
|
| 424 |
# happy. |
|
| 425 |
io.read |
|
| 426 |
end |
|
| 427 |
true |
|
| 428 |
rescue ScmCommandAborted |
|
| 429 |
false |
|
| 430 |
end |
|
| 431 |
end |
|
| 432 |
end |
|
| 433 |
private :ignore_missing_revisions |
|
| 404 | 434 |
end |
| 405 | 435 |
end |
| 406 | 436 |
end |
| test/unit/lib/redmine/scm/adapters/git_adapter_test.rb | ||
|---|---|---|
| 289 | 289 |
end |
| 290 | 290 | |
| 291 | 291 |
def test_revisions_invalid_rev_excludes |
| 292 |
assert_equal [], |
|
| 293 |
@adapter.revisions('', nil, nil,
|
|
| 294 |
{:reverse => true,
|
|
| 295 |
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], |
|
| 296 |
:excludes => ['0123abcd4567']}) |
|
| 297 |
assert_raise Redmine::Scm::Adapters::CommandFailed do |
|
| 298 |
revs1 = [] |
|
| 299 |
@adapter.revisions('', nil, nil,
|
|
| 300 |
{:reverse => true,
|
|
| 301 |
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], |
|
| 302 |
:excludes => ['0123abcd4567']}) do |rev| |
|
| 303 |
revs1 << rev |
|
| 304 |
end |
|
| 292 |
revs1 = @adapter.revisions('', nil, nil,
|
|
| 293 |
{:reverse => true,
|
|
| 294 |
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], |
|
| 295 |
:excludes => ['0123abcd4567']}) |
|
| 296 |
assert_equal 15, revs1.length |
|
| 297 |
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier |
|
| 298 |
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[ 0].identifier |
|
| 299 | ||
| 300 |
revs2 = [] |
|
| 301 |
@adapter.revisions('', nil, nil,
|
|
| 302 |
{:reverse => true,
|
|
| 303 |
:includes => ['83ca5fd546063a3c7dc2e568ba3355661a9e2b2c'], |
|
| 304 |
:excludes => ['0123abcd4567']}) do |rev| |
|
| 305 |
revs2 << rev |
|
| 305 | 306 |
end |
| 307 |
assert_equal 15, revs2.length |
|
| 308 |
assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier |
|
| 309 |
assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier |
|
| 306 | 310 |
end |
| 307 | 311 | |
| 308 | 312 |
def test_getting_revisions_with_spaces_in_filename |