Skip to content

Instantly share code, notes, and snippets.

@chesster
Created May 24, 2011 09:09
Show Gist options
  • Save chesster/988397 to your computer and use it in GitHub Desktop.
Save chesster/988397 to your computer and use it in GitHub Desktop.
Redmine patch: changesets can be downloaded as a Zip Archive
Index: app/helpers/repositories_helper.rb
===================================================================
--- app/helpers/repositories_helper.rb (revision 5885)
+++ app/helpers/repositories_helper.rb (working copy)
@@ -79,7 +79,7 @@
def render_changes_tree(tree)
return '' if tree.nil?
- output = ''
+ output = ''
output << '<ul>'
tree.keys.sort.each do |file|
style = 'change'
Index: app/models/repository.rb
===================================================================
--- app/models/repository.rb (revision 5885)
+++ app/models/repository.rb (working copy)
@@ -83,6 +83,10 @@
scm.cat(path, identifier)
end
+ def diffzip(path, rev, rev_to)
+ scm.diffzip(path, rev, rev_to)
+ end
+
def diff(path, rev, rev_to)
scm.diff(path, rev, rev_to)
end
Index: app/controllers/repositories_controller.rb
===================================================================
--- app/controllers/repositories_controller.rb (revision 5885)
+++ app/controllers/repositories_controller.rb (working copy)
@@ -160,6 +160,16 @@
send_data @diff.join, :filename => "#{filename}.diff",
:type => 'text/x-patch',
:disposition => 'attachment'
+
+ elsif params[:format] == 'zip'
+ @diff = @repository.diffzip(@path, @rev, @rev_to)
+ (show_error_not_found; return) unless @diff
+ filename = "changeset_r#{@rev}"
+ filename << "_r#{@rev_to}" if @rev_to
+ send_data @diff, :filename => "#{filename}.zip",
+ :type => 'application/zip',
+ :disposition => 'attachment'
+
else
@diff_type = params[:type] || User.current.pref[:diff_type] || 'inline'
@diff_type = 'inline' unless %w(inline sbs).include?(@diff_type)
@@ -179,7 +189,7 @@
@changeset = @repository.find_changeset_by_name(@rev)
@changeset_to = @rev_to ? @repository.find_changeset_by_name(@rev_to) : nil
end
- end
+ end
def stats
end
Index: app/views/repositories/diff.rhtml
===================================================================
--- app/views/repositories/diff.rhtml (revision 5885)
+++ app/views/repositories/diff.rhtml (working copy)
@@ -14,6 +14,7 @@
<% other_formats_links do |f| %>
<%= f.link_to 'Diff', :url => params, :caption => 'Unified diff' %>
+ <%= f.link_to 'Zip', :url => params, :caption => 'Zipped files' %>
<% end %>
<% html_title(with_leading_slash(@path), 'Diff') -%>
Index: lib/redmine/scm/adapters/subversion_adapter.rb
===================================================================
--- lib/redmine/scm/adapters/subversion_adapter.rb (revision 5885)
+++ lib/redmine/scm/adapters/subversion_adapter.rb (working copy)
@@ -17,6 +17,9 @@
require 'redmine/scm/adapters/abstract_adapter'
require 'uri'
+require 'rubygems'
+require 'zip/zip'
+require 'fileutils'
module Redmine
module Scm
@@ -171,8 +174,80 @@
return nil if $? && $?.exitstatus != 0
revisions
end
+
+ def diffzip(path, identifier_from, identifier_to=nil, type="inline")
+ path ||= ''
+
+ identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
+ identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
+
+ #cmd = "#{SVN_BIN} diff -r "
+ cmd = "#{SVN_BIN} diff -r #{identifier_to}:#{identifier_from} #{target(path)}@#{identifier_from} --summarize"
+ cmd << credentials_string
+ logger.debug "cmd #{cmd}"
+
+ diff = []
+ shellout(cmd) do |io|
+ io.each_line do |line|
+ file = line.split[1].split('/')
+ name = file[file.length-1,1] #nazwa pliku
+ #pathlen = target(path).split('/').length
+ pathlen = 5
+ fpath = file.slice(pathlen,file.length-pathlen-1).join('/') #sciezka bez poczatku "localhostów" i innych
+
+ if fpath.empty?
+ all = "#{name}"
+ else
+ all = "#{fpath}/#{name}"
+ end
+
+ # logger.error "all #{all}"
+
+ diff << {
+ 'name' => "#{name}",
+ 'path' => "#{fpath}",
+ 'all' => all,
+ 'full' => file.join('/')
+ }
+ end
+ end
+
+ random_string = (0..9).map{0until(c=rand(?z).chr)=~/(?!_)\w/;c}*''
+ tmp = "#{RAILS_ROOT}/tmp/diff/#{random_string}/"
+
+ FileUtils.mkdir_p tmp
+ FileUtils.cd tmp
+
+ zipfile_name = "changeset_#{identifier_to}-#{identifier_from}.zip"
+ Zip::ZipFile.open(zipfile_name, Zip::ZipFile::CREATE) do |zipfile|
+
+ diff.each do |filename|
+
+ if !filename['path'].empty?
+ FileUtils.mkdir_p(filename['path'])
+ end
+
+ export_cmd = "#{SVN_BIN} export -r #{identifier_from} #{filename['full']} #{filename['all']} --depth files --force"
+ export_cmd << credentials_string
+ shellout(export_cmd)
+
+ if File.exists? filename['all']
+ zipfile.add(filename['all'], filename['all'])
+ end
+
+ end
+ end
+ content = File.read(zipfile_name)
+
+ #usunac katalog z exportem
+ FileUtils.cd RAILS_ROOT
+ FileUtils.rm_rf(tmp)
+
+ return content
+ end
- def diff(path, identifier_from, identifier_to=nil, type="inline")
+
+ def diff(path, identifier_from, identifier_to=nil, type="inline")
path ||= ''
identifier_from = (identifier_from and identifier_from.to_i > 0) ? identifier_from.to_i : ''
identifier_to = (identifier_to and identifier_to.to_i > 0) ? identifier_to.to_i : (identifier_from.to_i - 1)
@@ -189,9 +264,9 @@
end
end
return nil if $? && $?.exitstatus != 0
- diff
- end
-
+ diff
+ end
+
def cat(path, identifier=nil)
identifier = (identifier and identifier.to_i > 0) ? identifier.to_i : "HEAD"
cmd = "#{SVN_BIN} cat #{target(path)}@#{identifier}"
@@ -226,7 +301,7 @@
str = ''
str << " --username #{shell_quote(@login)}" unless @login.blank?
str << " --password #{shell_quote(@password)}" unless @login.blank? || @password.blank?
- str << " --no-auth-cache --non-interactive"
+ str << " --no-auth-cache --trust-server-cert --non-interactive"
str
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment