Defect #2664 » for-trunk-r4893-20110220.patch
app/helpers/repositories_helper.rb | ||
---|---|---|
176 | 176 |
end |
177 | 177 |
|
178 | 178 |
def mercurial_field_tags(form, repository) |
179 |
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?))) |
|
179 |
content_tag('p', form.text_field(:url, :label => 'Root directory', :size => 60, :required => true, :disabled => (repository && !repository.root_url.blank?))) + |
|
180 |
content_tag('p', form.select(:path_encoding, [nil] + Setting::ENCODINGS, |
|
181 |
:label => 'Path encoding')) |
|
180 | 182 |
end |
181 | 183 | |
182 | 184 |
def git_field_tags(form, repository) |
app/models/repository.rb | ||
---|---|---|
42 | 42 |
end |
43 | 43 | |
44 | 44 |
def scm |
45 |
@scm ||= self.scm_adapter.new url, root_url, login, password |
|
45 |
@scm ||= self.scm_adapter.new url, root_url, |
|
46 |
login, password, path_encoding, nil |
|
46 | 47 |
update_attribute(:root_url, @scm.root_url) if root_url.blank? |
47 | 48 |
@scm |
48 | 49 |
end |
... | ... | |
248 | 249 |
end |
249 | 250 | |
250 | 251 |
private |
251 |
|
|
252 | ||
252 | 253 |
def before_save |
253 | 254 |
# Strips url and root_url |
254 | 255 |
url.strip! |
lib/redmine/scm/adapters/abstract_adapter.rb | ||
---|---|---|
63 | 63 |
end |
64 | 64 |
end |
65 | 65 | |
66 |
def initialize(url, root_url=nil, login=nil, password=nil) |
|
66 |
def initialize(url, root_url=nil, login=nil, password=nil, |
|
67 |
path_encoding=nil, log_encoding=nil) |
|
67 | 68 |
@url = url |
68 | 69 |
@login = login if login && !login.empty? |
69 | 70 |
@password = (password || "") if @login |
70 | 71 |
@root_url = root_url.blank? ? retrieve_root_url : root_url |
... | ... | |
67 | 68 |
@url = url |
68 | 69 |
@login = login if login && !login.empty? |
69 | 70 |
@password = (password || "") if @login |
70 | 71 |
@root_url = root_url.blank? ? retrieve_root_url : root_url |
72 |
@path_encoding = path_encoding || 'UTF-8' |
|
71 | 73 |
end |
... | ... | |
71 | 73 |
end |
72 |
|
|
74 | ||
73 | 75 |
def adapter_name |
74 | 76 |
'Abstract' |
75 | 77 |
end |
... | ... | |
221 | 223 |
def strip_credential(cmd) |
222 | 224 |
self.class.strip_credential(cmd) |
223 | 225 |
end |
226 | ||
227 |
def scm_iconv(to, from, str) |
|
228 |
return unless str |
|
229 |
return str if to == from |
|
230 |
begin |
|
231 |
Iconv.conv(to, from, str) |
|
232 |
rescue Iconv::Failure => err |
|
233 |
raise CommandFailed, "failed to convert path from #{from} to #{to}. #{err}" |
|
234 |
end |
|
235 |
end |
|
224 | 236 |
end |
225 | 237 |
|
226 | 238 |
class Entries < Array |
lib/redmine/scm/adapters/cvs_adapter.rb | ||
---|---|---|
59 | 59 |
# root_url -> the good old, sometimes damned, CVSROOT |
60 | 60 |
# login -> unnecessary |
61 | 61 |
# password -> unnecessary too |
62 |
def initialize(url, root_url=nil, login=nil, password=nil) |
|
62 |
def initialize(url, root_url=nil, login=nil, password=nil, |
|
63 |
path_encoding=nil, log_encoding=nil) |
|
63 | 64 |
@url = url |
64 | 65 |
@login = login if login && !login.empty? |
65 | 66 |
@password = (password || "") if @login |
lib/redmine/scm/adapters/darcs_adapter.rb | ||
---|---|---|
54 | 54 |
end |
55 | 55 |
end |
56 | 56 | |
57 |
def initialize(url, root_url=nil, login=nil, password=nil) |
|
57 |
def initialize(url, root_url=nil, login=nil, password=nil, |
|
58 |
path_encoding=nil, log_encoding=nil) |
|
58 | 59 |
@url = url |
59 | 60 |
@root_url = url |
60 | 61 |
end |
lib/redmine/scm/adapters/filesystem_adapter.rb | ||
---|---|---|
32 | 32 |
end |
33 | 33 |
end |
34 | 34 | |
35 |
def initialize(url, root_url=nil, login=nil, password=nil) |
|
35 |
def initialize(url, root_url=nil, login=nil, password=nil, |
|
36 |
path_encoding=nil, log_encoding=nil) |
|
36 | 37 |
@url = with_trailling_slash(url) |
37 | 38 |
end |
38 | 39 |
lib/redmine/scm/adapters/mercurial/redminehelper.py | ||
---|---|---|
119 | 119 | |
120 | 120 |
ui.write('</manifest>\n') |
121 | 121 | |
122 |
def rhcat(ui, repo, file1, *pats, **opts): |
|
123 |
return commands.cat(ui, repo, urllib.unquote(file1), *map(urllib.unquote, pats), **opts) |
|
124 | ||
122 | 125 |
def rhdiff(ui, repo, *pats, **opts): |
123 | 126 |
"""diff repository (or selected files)""" |
124 | 127 |
change = opts.pop('change', None) |
... | ... | |
156 | 159 |
# This extension should be compatible with Mercurial 0.9.5. |
157 | 160 |
# Note that Mercurial 0.9.5 doesn't have extensions.wrapfunction(). |
158 | 161 |
cmdtable = { |
162 |
'rhcat': (rhcat, |
|
163 |
[('r', 'rev', '', 'revision')], |
|
164 |
'hg rhcat ([-r REV] ...) FILE...'), |
|
159 | 165 |
'rhdiff': (rhdiff, |
160 | 166 |
[('r', 'rev', [], 'revision'), |
161 | 167 |
('c', 'change', '', 'change made by revision')], |
lib/redmine/scm/adapters/mercurial_adapter.rb | ||
---|---|---|
121 | 121 |
private :summary |
122 | 122 | |
123 | 123 |
def entries(path=nil, identifier=nil) |
124 |
p1 = scm_iconv(@path_encoding, 'UTF-8', path) |
|
124 | 125 |
manifest = hg('rhmanifest', '-r', hgrev(identifier), |
... | ... | |
124 | 125 |
manifest = hg('rhmanifest', '-r', hgrev(identifier), |
125 |
CGI.escape(without_leading_slash(path.to_s))) do |io|
|
|
126 |
CGI.escape(without_leading_slash(p1.to_s))) do |io|
|
|
126 | 127 |
begin |
127 | 128 |
ActiveSupport::XmlMini.parse(io.read)['rhmanifest']['repository']['manifest'] |
128 | 129 |
rescue |
... | ... | |
132 | 133 | |
133 | 134 |
entries = Entries.new |
134 | 135 |
as_ary(manifest['dir']).each do |e| |
135 |
n = CGI.unescape(e['name'])
|
|
136 |
n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
|
|
136 | 137 |
p = "#{path_prefix}#{n}" |
137 | 138 |
entries << Entry.new(:name => n, :path => p, :kind => 'dir') |
138 | 139 |
end |
139 | 140 | |
140 | 141 |
as_ary(manifest['file']).each do |e| |
... | ... | |
136 | 137 |
p = "#{path_prefix}#{n}" |
137 | 138 |
entries << Entry.new(:name => n, :path => p, :kind => 'dir') |
138 | 139 |
end |
139 | 140 | |
140 | 141 |
as_ary(manifest['file']).each do |e| |
141 |
n = CGI.unescape(e['name'])
|
|
142 |
n = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['name']))
|
|
142 | 143 |
p = "#{path_prefix}#{n}" |
143 | 144 |
lr = Revision.new(:revision => e['revision'], :scmid => e['node'], |
144 | 145 |
:identifier => e['node'], |
... | ... | |
180 | 181 |
cpmap = Hash[*cpalist.flatten] |
181 | 182 | |
182 | 183 |
paths = as_ary(le['paths']['path']).map do |e| |
183 |
p = CGI.unescape(e['__content__'])
|
|
184 |
p = scm_iconv('UTF-8', @path_encoding, CGI.unescape(e['__content__']) )
|
|
184 | 185 |
{:action => e['action'], :path => with_leading_slash(p), |
185 | 186 |
:from_path => (cpmap.member?(p) ? with_leading_slash(cpmap[p]) : nil), |
186 | 187 |
:from_revision => (cpmap.member?(p) ? le['revision'] : nil)} |
... | ... | |
203 | 204 |
else |
204 | 205 |
hg_args << '-c' << hgrev(identifier_from) |
205 | 206 |
end |
206 |
hg_args << CGI.escape(hgtarget(path)) unless path.blank? |
|
207 |
unless path.blank? |
|
208 |
p = scm_iconv(@path_encoding, 'UTF-8', path) |
|
209 |
hg_args << CGI.escape(hgtarget(p)) |
|
210 |
end |
|
207 | 211 |
diff = [] |
208 | 212 |
hg *hg_args do |io| |
209 | 213 |
io.each_line do |line| |
... | ... | |
216 | 220 |
end |
217 | 221 | |
218 | 222 |
def cat(path, identifier=nil) |
219 |
hg 'cat', '-r', hgrev(identifier), hgtarget(path) do |io| |
|
223 |
p = CGI.escape(scm_iconv(@path_encoding, 'UTF-8', path)) |
|
224 |
hg 'rhcat', '-r', hgrev(identifier), hgtarget(p) do |io| |
|
220 | 225 |
io.binmode |
221 | 226 |
io.read |
222 | 227 |
end |