comparison lib/redmine/scm/adapters/mercurial_adapter.rb @ 117:af80e5618e9b redmine-1.1

* Update to Redmine 1.1-stable branch (Redmine SVN rev 4707)
author Chris Cannam
date Thu, 13 Jan 2011 12:53:21 +0000
parents 513646585e45
children b859cc0c4fa1
comparison
equal deleted inserted replaced
39:150ceac17a8d 117:af80e5618e9b
14 # You should have received a copy of the GNU General Public License 14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software 15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 require 'redmine/scm/adapters/abstract_adapter' 18 require 'redmine/scm/adapters/abstract_adapter'
19 require 'cgi'
19 20
20 module Redmine 21 module Redmine
21 module Scm 22 module Scm
22 module Adapters 23 module Adapters
23 class MercurialAdapter < AbstractAdapter 24 class MercurialAdapter < AbstractAdapter
36 def hgversion 37 def hgversion
37 # The hg version is expressed either as a 38 # The hg version is expressed either as a
38 # release number (eg 0.9.5 or 1.0) or as a revision 39 # release number (eg 0.9.5 or 1.0) or as a revision
39 # id composed of 12 hexa characters. 40 # id composed of 12 hexa characters.
40 theversion = hgversion_from_command_line 41 theversion = hgversion_from_command_line
41 if theversion.match(/^\d+(\.\d+)+/) 42 if m = theversion.match(%r{\A(.*?)((\d+\.)+\d+)})
42 theversion.split(".").collect(&:to_i) 43 m[2].scan(%r{\d+}).collect(&:to_i)
43 end 44 end
44 end 45 end
45 46
46 def hgversion_from_command_line 47 def hgversion_from_command_line
47 %x{#{HG_BIN} --version}.match(/\(version (.*)\)/)[1] 48 shellout("#{HG_BIN} --version") { |io| io.read }.to_s
48 end 49 end
49 50
50 def template_path 51 def template_path
51 @@template_path ||= template_path_for(client_version) 52 @@template_path ||= template_path_for(client_version)
52 end 53 end
78 79
79 def entries(path=nil, identifier=nil) 80 def entries(path=nil, identifier=nil)
80 path ||= '' 81 path ||= ''
81 entries = Entries.new 82 entries = Entries.new
82 cmd = "#{HG_BIN} -R #{target('')} --cwd #{target('')} locate" 83 cmd = "#{HG_BIN} -R #{target('')} --cwd #{target('')} locate"
83 cmd << " -r " + (identifier ? identifier.to_s : "tip") 84 cmd << " -r " + shell_quote(identifier ? identifier.to_s : "tip")
84 cmd << " " + shell_quote("path:#{path}") unless path.empty? 85 cmd << " " + shell_quote("path:#{path}") unless path.empty?
85 shellout(cmd) do |io| 86 shellout(cmd) do |io|
86 io.each_line do |line| 87 io.each_line do |line|
87 # HG uses antislashs as separator on Windows 88 # HG uses antislashs as separator on Windows
88 line = line.gsub(/\\/, "/") 89 line = line.gsub(/\\/, "/")
110 cmd << " -r #{identifier_from.to_i}:#{identifier_to.to_i}" 111 cmd << " -r #{identifier_from.to_i}:#{identifier_to.to_i}"
111 elsif identifier_from 112 elsif identifier_from
112 cmd << " -r #{identifier_from.to_i}:" 113 cmd << " -r #{identifier_from.to_i}:"
113 end 114 end
114 cmd << " --limit #{options[:limit].to_i}" if options[:limit] 115 cmd << " --limit #{options[:limit].to_i}" if options[:limit]
115 cmd << " #{path}" if path 116 cmd << " #{shell_quote path}" unless path.blank?
116 shellout(cmd) do |io| 117 shellout(cmd) do |io|
117 begin 118 begin
118 # HG doesn't close the XML Document... 119 # HG doesn't close the XML Document...
119 doc = REXML::Document.new(io.read << "</log>") 120 doc = REXML::Document.new(io.read << "</log>")
120 doc.elements.each("log/logentry") do |logentry| 121 doc.elements.each("log/logentry") do |logentry|
125 if path.attributes['action'] == 'A' and c = copies.find{ |e| e.text == path.text } 126 if path.attributes['action'] == 'A' and c = copies.find{ |e| e.text == path.text }
126 from_path = c.attributes['copyfrom-path'] 127 from_path = c.attributes['copyfrom-path']
127 from_rev = logentry.attributes['revision'] 128 from_rev = logentry.attributes['revision']
128 end 129 end
129 paths << {:action => path.attributes['action'], 130 paths << {:action => path.attributes['action'],
130 :path => "/#{path.text}", 131 :path => "/#{CGI.unescape(path.text)}",
131 :from_path => from_path ? "/#{from_path}" : nil, 132 :from_path => from_path ? "/#{CGI.unescape(from_path)}" : nil,
132 :from_revision => from_rev ? from_rev : nil 133 :from_revision => from_rev ? from_rev : nil
133 } 134 }
134 end 135 end
135 paths.sort! { |x,y| x[:path] <=> y[:path] } 136 paths.sort! { |x,y| x[:path] <=> y[:path] }
136 137
155 if identifier_to 156 if identifier_to
156 identifier_to = identifier_to.to_i 157 identifier_to = identifier_to.to_i
157 else 158 else
158 identifier_to = identifier_from.to_i - 1 159 identifier_to = identifier_from.to_i - 1
159 end 160 end
161 if identifier_from
162 identifier_from = identifier_from.to_i
163 end
160 cmd = "#{HG_BIN} -R #{target('')} diff -r #{identifier_to} -r #{identifier_from} --nodates" 164 cmd = "#{HG_BIN} -R #{target('')} diff -r #{identifier_to} -r #{identifier_from} --nodates"
161 cmd << " -I #{target(path)}" unless path.empty? 165 cmd << " -I #{target(path)}" unless path.empty?
162 diff = [] 166 diff = []
163 shellout(cmd) do |io| 167 shellout(cmd) do |io|
164 io.each_line do |line| 168 io.each_line do |line|
169 diff 173 diff
170 end 174 end
171 175
172 def cat(path, identifier=nil) 176 def cat(path, identifier=nil)
173 cmd = "#{HG_BIN} -R #{target('')} cat" 177 cmd = "#{HG_BIN} -R #{target('')} cat"
174 cmd << " -r " + (identifier ? identifier.to_s : "tip") 178 cmd << " -r " + shell_quote(identifier ? identifier.to_s : "tip")
175 cmd << " #{target(path)}" 179 cmd << " #{target(path)}"
176 cat = nil 180 cat = nil
177 shellout(cmd) do |io| 181 shellout(cmd) do |io|
178 io.binmode 182 io.binmode
179 cat = io.read 183 cat = io.read
184 188
185 def annotate(path, identifier=nil) 189 def annotate(path, identifier=nil)
186 path ||= '' 190 path ||= ''
187 cmd = "#{HG_BIN} -R #{target('')}" 191 cmd = "#{HG_BIN} -R #{target('')}"
188 cmd << " annotate -n -u" 192 cmd << " annotate -n -u"
189 cmd << " -r " + (identifier ? identifier.to_s : "tip") 193 cmd << " -r " + shell_quote(identifier ? identifier.to_s : "tip")
190 cmd << " -r #{identifier.to_i}" if identifier 194 cmd << " -r #{identifier.to_i}" if identifier
191 cmd << " #{target(path)}" 195 cmd << " #{target(path)}"
192 blame = Annotate.new 196 blame = Annotate.new
193 shellout(cmd) do |io| 197 shellout(cmd) do |io|
194 io.each_line do |line| 198 io.each_line do |line|