##// END OF EJS Templates
Adds configuration settings to limit valid repository path (#1415)....
Jean-Philippe Lang -
r13191:13f9ccaed853
parent child
Show More
@@ -1,292 +1,314
1 1 # encoding: utf-8
2 2 #
3 3 # Redmine - project management software
4 4 # Copyright (C) 2006-2014 Jean-Philippe Lang
5 5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; either version 2
9 9 # of the License, or (at your option) any later version.
10 10 #
11 11 # This program is distributed in the hope that it will be useful,
12 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 14 # GNU General Public License for more details.
15 15 #
16 16 # You should have received a copy of the GNU General Public License
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 19
20 20 module RepositoriesHelper
21 21 def format_revision(revision)
22 22 if revision.respond_to? :format_identifier
23 23 revision.format_identifier
24 24 else
25 25 revision.to_s
26 26 end
27 27 end
28 28
29 29 def truncate_at_line_break(text, length = 255)
30 30 if text
31 31 text.gsub(%r{^(.{#{length}}[^\n]*)\n.+$}m, '\\1...')
32 32 end
33 33 end
34 34
35 35 def render_properties(properties)
36 36 unless properties.nil? || properties.empty?
37 37 content = ''
38 38 properties.keys.sort.each do |property|
39 39 content << content_tag('li', "<b>#{h property}</b>: <span>#{h properties[property]}</span>".html_safe)
40 40 end
41 41 content_tag('ul', content.html_safe, :class => 'properties')
42 42 end
43 43 end
44 44
45 45 def render_changeset_changes
46 46 changes = @changeset.filechanges.limit(1000).reorder('path').collect do |change|
47 47 case change.action
48 48 when 'A'
49 49 # Detects moved/copied files
50 50 if !change.from_path.blank?
51 51 change.action =
52 52 @changeset.filechanges.detect {|c| c.action == 'D' && c.path == change.from_path} ? 'R' : 'C'
53 53 end
54 54 change
55 55 when 'D'
56 56 @changeset.filechanges.detect {|c| c.from_path == change.path} ? nil : change
57 57 else
58 58 change
59 59 end
60 60 end.compact
61 61
62 62 tree = { }
63 63 changes.each do |change|
64 64 p = tree
65 65 dirs = change.path.to_s.split('/').select {|d| !d.blank?}
66 66 path = ''
67 67 dirs.each do |dir|
68 68 path += '/' + dir
69 69 p[:s] ||= {}
70 70 p = p[:s]
71 71 p[path] ||= {}
72 72 p = p[path]
73 73 end
74 74 p[:c] = change
75 75 end
76 76 render_changes_tree(tree[:s])
77 77 end
78 78
79 79 def render_changes_tree(tree)
80 80 return '' if tree.nil?
81 81 output = ''
82 82 output << '<ul>'
83 83 tree.keys.sort.each do |file|
84 84 style = 'change'
85 85 text = File.basename(h(file))
86 86 if s = tree[file][:s]
87 87 style << ' folder'
88 88 path_param = to_path_param(@repository.relative_path(file))
89 89 text = link_to(h(text), :controller => 'repositories',
90 90 :action => 'show',
91 91 :id => @project,
92 92 :repository_id => @repository.identifier_param,
93 93 :path => path_param,
94 94 :rev => @changeset.identifier)
95 95 output << "<li class='#{style}'>#{text}"
96 96 output << render_changes_tree(s)
97 97 output << "</li>"
98 98 elsif c = tree[file][:c]
99 99 style << " change-#{c.action}"
100 100 path_param = to_path_param(@repository.relative_path(c.path))
101 101 text = link_to(h(text), :controller => 'repositories',
102 102 :action => 'entry',
103 103 :id => @project,
104 104 :repository_id => @repository.identifier_param,
105 105 :path => path_param,
106 106 :rev => @changeset.identifier) unless c.action == 'D'
107 107 text << " - #{h(c.revision)}" unless c.revision.blank?
108 108 text << ' ('.html_safe + link_to(l(:label_diff), :controller => 'repositories',
109 109 :action => 'diff',
110 110 :id => @project,
111 111 :repository_id => @repository.identifier_param,
112 112 :path => path_param,
113 113 :rev => @changeset.identifier) + ') '.html_safe if c.action == 'M'
114 114 text << ' '.html_safe + content_tag('span', h(c.from_path), :class => 'copied-from') unless c.from_path.blank?
115 115 output << "<li class='#{style}'>#{text}</li>"
116 116 end
117 117 end
118 118 output << '</ul>'
119 119 output.html_safe
120 120 end
121 121
122 122 def repository_field_tags(form, repository)
123 123 method = repository.class.name.demodulize.underscore + "_field_tags"
124 124 if repository.is_a?(Repository) &&
125 125 respond_to?(method) && method != 'repository_field_tags'
126 126 send(method, form, repository)
127 127 end
128 128 end
129 129
130 130 def scm_select_tag(repository)
131 131 scm_options = [["--- #{l(:actionview_instancetag_blank_option)} ---", '']]
132 132 Redmine::Scm::Base.all.each do |scm|
133 133 if Setting.enabled_scm.include?(scm) ||
134 134 (repository && repository.class.name.demodulize == scm)
135 135 scm_options << ["Repository::#{scm}".constantize.scm_name, scm]
136 136 end
137 137 end
138 138 select_tag('repository_scm',
139 139 options_for_select(scm_options, repository.class.name.demodulize),
140 140 :disabled => (repository && !repository.new_record?),
141 141 :data => {:remote => true, :method => 'get'})
142 142 end
143 143
144 144 def with_leading_slash(path)
145 145 path.to_s.starts_with?('/') ? path : "/#{path}"
146 146 end
147 147
148 148 def without_leading_slash(path)
149 149 path.gsub(%r{^/+}, '')
150 150 end
151 151
152 152 def subversion_field_tags(form, repository)
153 153 content_tag('p', form.text_field(:url, :size => 60, :required => true,
154 154 :disabled => !repository.safe_attribute?('url')) +
155 content_tag('em', '(file:///, http://, https://, svn://, svn+[tunnelscheme]://)', :class => 'info')) +
155 scm_path_info_tag(repository)) +
156 156 content_tag('p', form.text_field(:login, :size => 30)) +
157 157 content_tag('p', form.password_field(
158 158 :password, :size => 30, :name => 'ignore',
159 159 :value => ((repository.new_record? || repository.password.blank?) ? '' : ('x'*15)),
160 160 :onfocus => "this.value=''; this.name='repository[password]';",
161 161 :onchange => "this.name='repository[password]';"))
162 162 end
163 163
164 164 def darcs_field_tags(form, repository)
165 165 content_tag('p', form.text_field(
166 166 :url, :label => l(:field_path_to_repository),
167 167 :size => 60, :required => true,
168 :disabled => !repository.safe_attribute?('url'))) +
168 :disabled => !repository.safe_attribute?('url')) +
169 scm_path_info_tag(repository)) +
169 170 scm_log_encoding_tag(form, repository)
170 171 end
171 172
172 173 def mercurial_field_tags(form, repository)
173 174 content_tag('p', form.text_field(
174 175 :url, :label => l(:field_path_to_repository),
175 176 :size => 60, :required => true,
176 177 :disabled => !repository.safe_attribute?('url')
177 178 ) +
178 content_tag('em', l(:text_mercurial_repository_note), :class => 'info')) +
179 scm_path_info_tag(repository)) +
179 180 scm_path_encoding_tag(form, repository)
180 181 end
181 182
182 183 def git_field_tags(form, repository)
183 184 content_tag('p', form.text_field(
184 185 :url, :label => l(:field_path_to_repository),
185 186 :size => 60, :required => true,
186 187 :disabled => !repository.safe_attribute?('url')
187 188 ) +
188 content_tag('em', l(:text_git_repository_note), :class => 'info')) +
189 scm_path_info_tag(repository)) +
189 190 scm_path_encoding_tag(form, repository) +
190 191 content_tag('p', form.check_box(
191 192 :extra_report_last_commit,
192 193 :label => l(:label_git_report_last_commit)
193 194 ))
194 195 end
195 196
196 197 def cvs_field_tags(form, repository)
197 198 content_tag('p', form.text_field(
198 199 :root_url,
199 200 :label => l(:field_cvsroot),
200 201 :size => 60, :required => true,
201 :disabled => !repository.safe_attribute?('root_url'))) +
202 :disabled => !repository.safe_attribute?('root_url')) +
203 scm_path_info_tag(repository)) +
202 204 content_tag('p', form.text_field(
203 205 :url,
204 206 :label => l(:field_cvs_module),
205 207 :size => 30, :required => true,
206 208 :disabled => !repository.safe_attribute?('url'))) +
207 209 scm_log_encoding_tag(form, repository) +
208 210 scm_path_encoding_tag(form, repository)
209 211 end
210 212
211 213 def bazaar_field_tags(form, repository)
212 214 content_tag('p', form.text_field(
213 215 :url, :label => l(:field_path_to_repository),
214 216 :size => 60, :required => true,
215 :disabled => !repository.safe_attribute?('url'))) +
217 :disabled => !repository.safe_attribute?('url')) +
218 scm_path_info_tag(repository)) +
216 219 scm_log_encoding_tag(form, repository)
217 220 end
218 221
219 222 def filesystem_field_tags(form, repository)
220 223 content_tag('p', form.text_field(
221 224 :url, :label => l(:field_root_directory),
222 225 :size => 60, :required => true,
223 :disabled => !repository.safe_attribute?('url'))) +
226 :disabled => !repository.safe_attribute?('url')) +
227 scm_path_info_tag(repository)) +
224 228 scm_path_encoding_tag(form, repository)
225 229 end
226 230
231 def scm_path_info_tag(repository)
232 text = scm_path_info(repository)
233 if text.present?
234 content_tag('em', text, :class => 'info')
235 else
236 ''
237 end
238 end
239
240 def scm_path_info(repository)
241 scm_name = repository.scm_name.to_s.downcase
242
243 info_from_config = Redmine::Configuration["scm_#{scm_name}_path_info"].presence
244 return info_from_config.html_safe if info_from_config
245
246 l("text_#{scm_name}_repository_note", :default => '')
247 end
248
227 249 def scm_log_encoding_tag(form, repository)
228 250 select = form.select(
229 251 :log_encoding,
230 252 [nil] + Setting::ENCODINGS,
231 253 :label => l(:field_commit_logs_encoding),
232 254 :required => true
233 255 )
234 256 content_tag('p', select)
235 257 end
236 258
237 259 def scm_path_encoding_tag(form, repository)
238 260 select = form.select(
239 261 :path_encoding,
240 262 [nil] + Setting::ENCODINGS,
241 263 :label => l(:field_scm_path_encoding)
242 264 )
243 265 content_tag('p', select + content_tag('em', l(:text_scm_path_encoding_note), :class => 'info'))
244 266 end
245 267
246 268 def index_commits(commits, heads)
247 269 return nil if commits.nil? or commits.first.parents.nil?
248 270 refs_map = {}
249 271 heads.each do |head|
250 272 refs_map[head.scmid] ||= []
251 273 refs_map[head.scmid] << head
252 274 end
253 275 commits_by_scmid = {}
254 276 commits.reverse.each_with_index do |commit, commit_index|
255 277 commits_by_scmid[commit.scmid] = {
256 278 :parent_scmids => commit.parents.collect { |parent| parent.scmid },
257 279 :rdmid => commit_index,
258 280 :refs => refs_map.include?(commit.scmid) ? refs_map[commit.scmid].join(" ") : nil,
259 281 :scmid => commit.scmid,
260 282 :href => block_given? ? yield(commit.scmid) : commit.scmid
261 283 }
262 284 end
263 285 heads.sort! { |head1, head2| head1.to_s <=> head2.to_s }
264 286 space = nil
265 287 heads.each do |head|
266 288 if commits_by_scmid.include? head.scmid
267 289 space = index_head((space || -1) + 1, head, commits_by_scmid)
268 290 end
269 291 end
270 292 # when no head matched anything use first commit
271 293 space ||= index_head(0, commits.first, commits_by_scmid)
272 294 return commits_by_scmid, space
273 295 end
274 296
275 297 def index_head(space, commit, commits_by_scmid)
276 298 stack = [[space, commits_by_scmid[commit.scmid]]]
277 299 max_space = space
278 300 until stack.empty?
279 301 space, commit = stack.pop
280 302 commit[:space] = space if commit[:space].nil?
281 303 space -= 1
282 304 commit[:parent_scmids].each_with_index do |parent_scmid, parent_index|
283 305 parent_commit = commits_by_scmid[parent_scmid]
284 306 if parent_commit and parent_commit[:space].nil?
285 307 stack.unshift [space += 1, parent_commit]
286 308 end
287 309 end
288 310 max_space = space if max_space < space
289 311 end
290 312 max_space
291 313 end
292 314 end
@@ -1,498 +1,511
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class ScmFetchError < Exception; end
19 19
20 20 class Repository < ActiveRecord::Base
21 21 include Redmine::Ciphering
22 22 include Redmine::SafeAttributes
23 23
24 24 # Maximum length for repository identifiers
25 25 IDENTIFIER_MAX_LENGTH = 255
26 26
27 27 belongs_to :project
28 28 has_many :changesets, lambda{order("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC")}
29 29 has_many :filechanges, :class_name => 'Change', :through => :changesets
30 30
31 31 serialize :extra_info
32 32
33 33 before_save :check_default
34 34
35 35 # Raw SQL to delete changesets and changes in the database
36 36 # has_many :changesets, :dependent => :destroy is too slow for big repositories
37 37 before_destroy :clear_changesets
38 38
39 39 validates_length_of :password, :maximum => 255, :allow_nil => true
40 40 validates_length_of :identifier, :maximum => IDENTIFIER_MAX_LENGTH, :allow_blank => true
41 41 validates_presence_of :identifier, :unless => Proc.new { |r| r.is_default? || r.set_as_default? }
42 42 validates_uniqueness_of :identifier, :scope => :project_id, :allow_blank => true
43 43 validates_exclusion_of :identifier, :in => %w(browse show entry raw changes annotate diff statistics graph revisions revision)
44 44 # donwcase letters, digits, dashes, underscores but not digits only
45 45 validates_format_of :identifier, :with => /\A(?!\d+$)[a-z0-9\-_]*\z/, :allow_blank => true
46 46 # Checks if the SCM is enabled when creating a repository
47 47 validate :repo_create_validation, :on => :create
48 validate :validate_repository_path
48 49 attr_protected :id
49 50
50 51 safe_attributes 'identifier',
51 52 'login',
52 53 'password',
53 54 'path_encoding',
54 55 'log_encoding',
55 56 'is_default'
56 57
57 58 safe_attributes 'url',
58 59 :if => lambda {|repository, user| repository.new_record?}
59 60
60 61 def repo_create_validation
61 62 unless Setting.enabled_scm.include?(self.class.name.demodulize)
62 63 errors.add(:type, :invalid)
63 64 end
64 65 end
65 66
66 67 def self.human_attribute_name(attribute_key_name, *args)
67 68 attr_name = attribute_key_name.to_s
68 69 if attr_name == "log_encoding"
69 70 attr_name = "commit_logs_encoding"
70 71 end
71 72 super(attr_name, *args)
72 73 end
73 74
74 75 # Removes leading and trailing whitespace
75 76 def url=(arg)
76 77 write_attribute(:url, arg ? arg.to_s.strip : nil)
77 78 end
78 79
79 80 # Removes leading and trailing whitespace
80 81 def root_url=(arg)
81 82 write_attribute(:root_url, arg ? arg.to_s.strip : nil)
82 83 end
83 84
84 85 def password
85 86 read_ciphered_attribute(:password)
86 87 end
87 88
88 89 def password=(arg)
89 90 write_ciphered_attribute(:password, arg)
90 91 end
91 92
92 93 def scm_adapter
93 94 self.class.scm_adapter_class
94 95 end
95 96
96 97 def scm
97 98 unless @scm
98 99 @scm = self.scm_adapter.new(url, root_url,
99 100 login, password, path_encoding)
100 101 if root_url.blank? && @scm.root_url.present?
101 102 update_attribute(:root_url, @scm.root_url)
102 103 end
103 104 end
104 105 @scm
105 106 end
106 107
107 108 def scm_name
108 109 self.class.scm_name
109 110 end
110 111
111 112 def name
112 113 if identifier.present?
113 114 identifier
114 115 elsif is_default?
115 116 l(:field_repository_is_default)
116 117 else
117 118 scm_name
118 119 end
119 120 end
120 121
121 122 def identifier=(identifier)
122 123 super unless identifier_frozen?
123 124 end
124 125
125 126 def identifier_frozen?
126 127 errors[:identifier].blank? && !(new_record? || identifier.blank?)
127 128 end
128 129
129 130 def identifier_param
130 131 if is_default?
131 132 nil
132 133 elsif identifier.present?
133 134 identifier
134 135 else
135 136 id.to_s
136 137 end
137 138 end
138 139
139 140 def <=>(repository)
140 141 if is_default?
141 142 -1
142 143 elsif repository.is_default?
143 144 1
144 145 else
145 146 identifier.to_s <=> repository.identifier.to_s
146 147 end
147 148 end
148 149
149 150 def self.find_by_identifier_param(param)
150 151 if param.to_s =~ /^\d+$/
151 152 find_by_id(param)
152 153 else
153 154 find_by_identifier(param)
154 155 end
155 156 end
156 157
157 158 # TODO: should return an empty hash instead of nil to avoid many ||{}
158 159 def extra_info
159 160 h = read_attribute(:extra_info)
160 161 h.is_a?(Hash) ? h : nil
161 162 end
162 163
163 164 def merge_extra_info(arg)
164 165 h = extra_info || {}
165 166 return h if arg.nil?
166 167 h.merge!(arg)
167 168 write_attribute(:extra_info, h)
168 169 end
169 170
170 171 def report_last_commit
171 172 true
172 173 end
173 174
174 175 def supports_cat?
175 176 scm.supports_cat?
176 177 end
177 178
178 179 def supports_annotate?
179 180 scm.supports_annotate?
180 181 end
181 182
182 183 def supports_all_revisions?
183 184 true
184 185 end
185 186
186 187 def supports_directory_revisions?
187 188 false
188 189 end
189 190
190 191 def supports_revision_graph?
191 192 false
192 193 end
193 194
194 195 def entry(path=nil, identifier=nil)
195 196 scm.entry(path, identifier)
196 197 end
197 198
198 199 def scm_entries(path=nil, identifier=nil)
199 200 scm.entries(path, identifier)
200 201 end
201 202 protected :scm_entries
202 203
203 204 def entries(path=nil, identifier=nil)
204 205 entries = scm_entries(path, identifier)
205 206 load_entries_changesets(entries)
206 207 entries
207 208 end
208 209
209 210 def branches
210 211 scm.branches
211 212 end
212 213
213 214 def tags
214 215 scm.tags
215 216 end
216 217
217 218 def default_branch
218 219 nil
219 220 end
220 221
221 222 def properties(path, identifier=nil)
222 223 scm.properties(path, identifier)
223 224 end
224 225
225 226 def cat(path, identifier=nil)
226 227 scm.cat(path, identifier)
227 228 end
228 229
229 230 def diff(path, rev, rev_to)
230 231 scm.diff(path, rev, rev_to)
231 232 end
232 233
233 234 def diff_format_revisions(cs, cs_to, sep=':')
234 235 text = ""
235 236 text << cs_to.format_identifier + sep if cs_to
236 237 text << cs.format_identifier if cs
237 238 text
238 239 end
239 240
240 241 # Returns a path relative to the url of the repository
241 242 def relative_path(path)
242 243 path
243 244 end
244 245
245 246 # Finds and returns a revision with a number or the beginning of a hash
246 247 def find_changeset_by_name(name)
247 248 return nil if name.blank?
248 249 s = name.to_s
249 250 if s.match(/^\d*$/)
250 251 changesets.where("revision = ?", s).first
251 252 else
252 253 changesets.where("revision LIKE ?", s + '%').first
253 254 end
254 255 end
255 256
256 257 def latest_changeset
257 258 @latest_changeset ||= changesets.first
258 259 end
259 260
260 261 # Returns the latest changesets for +path+
261 262 # Default behaviour is to search in cached changesets
262 263 def latest_changesets(path, rev, limit=10)
263 264 if path.blank?
264 265 changesets.
265 266 reorder("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC").
266 267 limit(limit).
267 268 preload(:user).
268 269 to_a
269 270 else
270 271 filechanges.
271 272 where("path = ?", path.with_leading_slash).
272 273 reorder("#{Changeset.table_name}.committed_on DESC, #{Changeset.table_name}.id DESC").
273 274 limit(limit).
274 275 preload(:changeset => :user).
275 276 collect(&:changeset)
276 277 end
277 278 end
278 279
279 280 def scan_changesets_for_issue_ids
280 281 self.changesets.each(&:scan_comment_for_issue_ids)
281 282 end
282 283
283 284 # Returns an array of committers usernames and associated user_id
284 285 def committers
285 286 @committers ||= Changeset.connection.select_rows(
286 287 "SELECT DISTINCT committer, user_id FROM #{Changeset.table_name} WHERE repository_id = #{id}")
287 288 end
288 289
289 290 # Maps committers username to a user ids
290 291 def committer_ids=(h)
291 292 if h.is_a?(Hash)
292 293 committers.each do |committer, user_id|
293 294 new_user_id = h[committer]
294 295 if new_user_id && (new_user_id.to_i != user_id.to_i)
295 296 new_user_id = (new_user_id.to_i > 0 ? new_user_id.to_i : nil)
296 297 Changeset.where(["repository_id = ? AND committer = ?", id, committer]).
297 298 update_all("user_id = #{new_user_id.nil? ? 'NULL' : new_user_id}")
298 299 end
299 300 end
300 301 @committers = nil
301 302 @found_committer_users = nil
302 303 true
303 304 else
304 305 false
305 306 end
306 307 end
307 308
308 309 # Returns the Redmine User corresponding to the given +committer+
309 310 # It will return nil if the committer is not yet mapped and if no User
310 311 # with the same username or email was found
311 312 def find_committer_user(committer)
312 313 unless committer.blank?
313 314 @found_committer_users ||= {}
314 315 return @found_committer_users[committer] if @found_committer_users.has_key?(committer)
315 316
316 317 user = nil
317 318 c = changesets.where(:committer => committer).
318 319 includes(:user).references(:user).first
319 320 if c && c.user
320 321 user = c.user
321 322 elsif committer.strip =~ /^([^<]+)(<(.*)>)?$/
322 323 username, email = $1.strip, $3
323 324 u = User.find_by_login(username)
324 325 u ||= User.find_by_mail(email) unless email.blank?
325 326 user = u
326 327 end
327 328 @found_committer_users[committer] = user
328 329 user
329 330 end
330 331 end
331 332
332 333 def repo_log_encoding
333 334 encoding = log_encoding.to_s.strip
334 335 encoding.blank? ? 'UTF-8' : encoding
335 336 end
336 337
337 338 # Fetches new changesets for all repositories of active projects
338 339 # Can be called periodically by an external script
339 340 # eg. ruby script/runner "Repository.fetch_changesets"
340 341 def self.fetch_changesets
341 342 Project.active.has_module(:repository).all.each do |project|
342 343 project.repositories.each do |repository|
343 344 begin
344 345 repository.fetch_changesets
345 346 rescue Redmine::Scm::Adapters::CommandFailed => e
346 347 logger.error "scm: error during fetching changesets: #{e.message}"
347 348 end
348 349 end
349 350 end
350 351 end
351 352
352 353 # scan changeset comments to find related and fixed issues for all repositories
353 354 def self.scan_changesets_for_issue_ids
354 355 all.each(&:scan_changesets_for_issue_ids)
355 356 end
356 357
357 358 def self.scm_name
358 359 'Abstract'
359 360 end
360 361
361 362 def self.available_scm
362 363 subclasses.collect {|klass| [klass.scm_name, klass.name]}
363 364 end
364 365
365 366 def self.factory(klass_name, *args)
366 367 klass = "Repository::#{klass_name}".constantize
367 368 klass.new(*args)
368 369 rescue
369 370 nil
370 371 end
371 372
372 373 def self.scm_adapter_class
373 374 nil
374 375 end
375 376
376 377 def self.scm_command
377 378 ret = ""
378 379 begin
379 380 ret = self.scm_adapter_class.client_command if self.scm_adapter_class
380 381 rescue Exception => e
381 382 logger.error "scm: error during get command: #{e.message}"
382 383 end
383 384 ret
384 385 end
385 386
386 387 def self.scm_version_string
387 388 ret = ""
388 389 begin
389 390 ret = self.scm_adapter_class.client_version_string if self.scm_adapter_class
390 391 rescue Exception => e
391 392 logger.error "scm: error during get version string: #{e.message}"
392 393 end
393 394 ret
394 395 end
395 396
396 397 def self.scm_available
397 398 ret = false
398 399 begin
399 400 ret = self.scm_adapter_class.client_available if self.scm_adapter_class
400 401 rescue Exception => e
401 402 logger.error "scm: error during get scm available: #{e.message}"
402 403 end
403 404 ret
404 405 end
405 406
406 407 def set_as_default?
407 408 new_record? && project && Repository.where(:project_id => project.id).empty?
408 409 end
409 410
410 411 # Returns a hash with statistics by author in the following form:
411 412 # {
412 413 # "John Smith" => { :commits => 45, :changes => 324 },
413 414 # "Bob" => { ... }
414 415 # }
415 416 #
416 417 # Notes:
417 418 # - this hash honnors the users mapping defined for the repository
418 419 def stats_by_author
419 420 commits = Changeset.where("repository_id = ?", id).select("committer, user_id, count(*) as count").group("committer, user_id")
420 421
421 422 #TODO: restore ordering ; this line probably never worked
422 423 #commits.to_a.sort! {|x, y| x.last <=> y.last}
423 424
424 425 changes = Change.joins(:changeset).where("#{Changeset.table_name}.repository_id = ?", id).select("committer, user_id, count(*) as count").group("committer, user_id")
425 426
426 427 user_ids = changesets.map(&:user_id).compact.uniq
427 428 authors_names = User.where(:id => user_ids).inject({}) do |memo, user|
428 429 memo[user.id] = user.to_s
429 430 memo
430 431 end
431 432
432 433 (commits + changes).inject({}) do |hash, element|
433 434 mapped_name = element.committer
434 435 if username = authors_names[element.user_id.to_i]
435 436 mapped_name = username
436 437 end
437 438 hash[mapped_name] ||= { :commits_count => 0, :changes_count => 0 }
438 439 if element.is_a?(Changeset)
439 440 hash[mapped_name][:commits_count] += element.count.to_i
440 441 else
441 442 hash[mapped_name][:changes_count] += element.count.to_i
442 443 end
443 444 hash
444 445 end
445 446 end
446 447
447 448 # Returns a scope of changesets that come from the same commit as the given changeset
448 449 # in different repositories that point to the same backend
449 450 def same_commits_in_scope(scope, changeset)
450 451 scope = scope.joins(:repository).where(:repositories => {:url => url, :root_url => root_url, :type => type})
451 452 if changeset.scmid.present?
452 453 scope = scope.where(:scmid => changeset.scmid)
453 454 else
454 455 scope = scope.where(:revision => changeset.revision)
455 456 end
456 457 scope
457 458 end
458 459
459 460 protected
460 461
462 # Validates repository url based against an optional regular expression
463 # that can be set in the Redmine configuration file.
464 def validate_repository_path(attribute=:url)
465 regexp = Redmine::Configuration["scm_#{scm_name.to_s.downcase}_path_regexp"]
466 if changes[attribute] && regexp.present?
467 regexp = regexp.to_s.strip.gsub('%project%') {Regexp.escape(project.try(:identifier).to_s)}
468 unless send(attribute).to_s.match(Regexp.new("\\A#{regexp}\\z"))
469 errors.add(attribute, :invalid)
470 end
471 end
472 end
473
461 474 def check_default
462 475 if !is_default? && set_as_default?
463 476 self.is_default = true
464 477 end
465 478 if is_default? && is_default_changed?
466 479 Repository.where(["project_id = ?", project_id]).update_all(["is_default = ?", false])
467 480 end
468 481 end
469 482
470 483 def load_entries_changesets(entries)
471 484 if entries
472 485 entries.each do |entry|
473 486 if entry.lastrev && entry.lastrev.identifier
474 487 entry.changeset = find_changeset_by_name(entry.lastrev.identifier)
475 488 end
476 489 end
477 490 end
478 491 end
479 492
480 493 private
481 494
482 495 # Deletes repository data
483 496 def clear_changesets
484 497 cs = Changeset.table_name
485 498 ch = Change.table_name
486 499 ci = "#{table_name_prefix}changesets_issues#{table_name_suffix}"
487 500 cp = "#{table_name_prefix}changeset_parents#{table_name_suffix}"
488 501
489 502 self.class.connection.delete("DELETE FROM #{ch} WHERE #{ch}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
490 503 self.class.connection.delete("DELETE FROM #{ci} WHERE #{ci}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
491 504 self.class.connection.delete("DELETE FROM #{cp} WHERE #{cp}.changeset_id IN (SELECT #{cs}.id FROM #{cs} WHERE #{cs}.repository_id = #{id})")
492 505 self.class.connection.delete("DELETE FROM #{cs} WHERE #{cs}.repository_id = #{id}")
493 506 clear_extra_info_of_changesets
494 507 end
495 508
496 509 def clear_extra_info_of_changesets
497 510 end
498 511 end
@@ -1,205 +1,213
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'redmine/scm/adapters/cvs_adapter'
19 19 require 'digest/sha1'
20 20
21 21 class Repository::Cvs < Repository
22 22 validates_presence_of :url, :root_url, :log_encoding
23 23
24 24 safe_attributes 'root_url',
25 25 :if => lambda {|repository, user| repository.new_record?}
26 26
27 27 def self.human_attribute_name(attribute_key_name, *args)
28 28 attr_name = attribute_key_name.to_s
29 29 if attr_name == "root_url"
30 30 attr_name = "cvsroot"
31 31 elsif attr_name == "url"
32 32 attr_name = "cvs_module"
33 33 end
34 34 super(attr_name, *args)
35 35 end
36 36
37 37 def self.scm_adapter_class
38 38 Redmine::Scm::Adapters::CvsAdapter
39 39 end
40 40
41 41 def self.scm_name
42 42 'CVS'
43 43 end
44 44
45 45 def entry(path=nil, identifier=nil)
46 46 rev = identifier.nil? ? nil : changesets.find_by_revision(identifier)
47 47 scm.entry(path, rev.nil? ? nil : rev.committed_on)
48 48 end
49 49
50 50 def scm_entries(path=nil, identifier=nil)
51 51 rev = nil
52 52 if ! identifier.nil?
53 53 rev = changesets.find_by_revision(identifier)
54 54 return nil if rev.nil?
55 55 end
56 56 entries = scm.entries(path, rev.nil? ? nil : rev.committed_on)
57 57 if entries
58 58 entries.each() do |entry|
59 59 if ( ! entry.lastrev.nil? ) && ( ! entry.lastrev.revision.nil? )
60 60 change = filechanges.find_by_revision_and_path(
61 61 entry.lastrev.revision,
62 62 scm.with_leading_slash(entry.path) )
63 63 if change
64 64 entry.lastrev.identifier = change.changeset.revision
65 65 entry.lastrev.revision = change.changeset.revision
66 66 entry.lastrev.author = change.changeset.committer
67 67 # entry.lastrev.branch = change.branch
68 68 end
69 69 end
70 70 end
71 71 end
72 72 entries
73 73 end
74 74 protected :scm_entries
75 75
76 76 def cat(path, identifier=nil)
77 77 rev = nil
78 78 if ! identifier.nil?
79 79 rev = changesets.find_by_revision(identifier)
80 80 return nil if rev.nil?
81 81 end
82 82 scm.cat(path, rev.nil? ? nil : rev.committed_on)
83 83 end
84 84
85 85 def annotate(path, identifier=nil)
86 86 rev = nil
87 87 if ! identifier.nil?
88 88 rev = changesets.find_by_revision(identifier)
89 89 return nil if rev.nil?
90 90 end
91 91 scm.annotate(path, rev.nil? ? nil : rev.committed_on)
92 92 end
93 93
94 94 def diff(path, rev, rev_to)
95 95 # convert rev to revision. CVS can't handle changesets here
96 96 diff=[]
97 97 changeset_from = changesets.find_by_revision(rev)
98 98 if rev_to.to_i > 0
99 99 changeset_to = changesets.find_by_revision(rev_to)
100 100 end
101 101 changeset_from.filechanges.each() do |change_from|
102 102 revision_from = nil
103 103 revision_to = nil
104 104 if path.nil? || (change_from.path.starts_with? scm.with_leading_slash(path))
105 105 revision_from = change_from.revision
106 106 end
107 107 if revision_from
108 108 if changeset_to
109 109 changeset_to.filechanges.each() do |change_to|
110 110 revision_to = change_to.revision if change_to.path == change_from.path
111 111 end
112 112 end
113 113 unless revision_to
114 114 revision_to = scm.get_previous_revision(revision_from)
115 115 end
116 116 file_diff = scm.diff(change_from.path, revision_from, revision_to)
117 117 diff = diff + file_diff unless file_diff.nil?
118 118 end
119 119 end
120 120 return diff
121 121 end
122 122
123 123 def fetch_changesets
124 124 # some nifty bits to introduce a commit-id with cvs
125 125 # natively cvs doesn't provide any kind of changesets,
126 126 # there is only a revision per file.
127 127 # we now take a guess using the author, the commitlog and the commit-date.
128 128
129 129 # last one is the next step to take. the commit-date is not equal for all
130 130 # commits in one changeset. cvs update the commit-date when the *,v file was touched. so
131 131 # we use a small delta here, to merge all changes belonging to _one_ changeset
132 132 time_delta = 10.seconds
133 133 fetch_since = latest_changeset ? latest_changeset.committed_on : nil
134 134 transaction do
135 135 tmp_rev_num = 1
136 136 scm.revisions('', fetch_since, nil, :log_encoding => repo_log_encoding) do |revision|
137 137 # only add the change to the database, if it doen't exists. the cvs log
138 138 # is not exclusive at all.
139 139 tmp_time = revision.time.clone
140 140 unless filechanges.find_by_path_and_revision(
141 141 scm.with_leading_slash(revision.paths[0][:path]),
142 142 revision.paths[0][:revision]
143 143 )
144 144 cmt = Changeset.normalize_comments(revision.message, repo_log_encoding)
145 145 author_utf8 = Changeset.to_utf8(revision.author, repo_log_encoding)
146 146 cs = changesets.where(
147 147 :committed_on => tmp_time - time_delta .. tmp_time + time_delta,
148 148 :committer => author_utf8,
149 149 :comments => cmt
150 150 ).first
151 151 # create a new changeset....
152 152 unless cs
153 153 # we use a temporary revision number here (just for inserting)
154 154 # later on, we calculate a continous positive number
155 155 tmp_time2 = tmp_time.clone.gmtime
156 156 branch = revision.paths[0][:branch]
157 157 scmid = branch + "-" + tmp_time2.strftime("%Y%m%d-%H%M%S")
158 158 cs = Changeset.create(:repository => self,
159 159 :revision => "tmp#{tmp_rev_num}",
160 160 :scmid => scmid,
161 161 :committer => revision.author,
162 162 :committed_on => tmp_time,
163 163 :comments => revision.message)
164 164 tmp_rev_num += 1
165 165 end
166 166 # convert CVS-File-States to internal Action-abbrevations
167 167 # default action is (M)odified
168 168 action = "M"
169 169 if revision.paths[0][:action] == "Exp" && revision.paths[0][:revision] == "1.1"
170 170 action = "A" # add-action always at first revision (= 1.1)
171 171 elsif revision.paths[0][:action] == "dead"
172 172 action = "D" # dead-state is similar to Delete
173 173 end
174 174 Change.create(
175 175 :changeset => cs,
176 176 :action => action,
177 177 :path => scm.with_leading_slash(revision.paths[0][:path]),
178 178 :revision => revision.paths[0][:revision],
179 179 :branch => revision.paths[0][:branch]
180 180 )
181 181 end
182 182 end
183 183
184 184 # Renumber new changesets in chronological order
185 185 Changeset.
186 186 order('committed_on ASC, id ASC').
187 187 where("repository_id = ? AND revision LIKE 'tmp%'", id).
188 188 each do |changeset|
189 189 changeset.update_attribute :revision, next_revision_number
190 190 end
191 191 end # transaction
192 192 @current_revision_number = nil
193 193 end
194 194
195 protected
196
197 # Overrides Repository#validate_repository_path to validate
198 # against root_url attribute.
199 def validate_repository_path(attribute=:root_url)
200 super(attribute)
201 end
202
195 203 private
196 204
197 205 # Returns the next revision number to assign to a CVS changeset
198 206 def next_revision_number
199 207 # Need to retrieve existing revision numbers to sort them as integers
200 208 sql = "SELECT revision FROM #{Changeset.table_name} "
201 209 sql << "WHERE repository_id = #{id} AND revision NOT LIKE 'tmp%'"
202 210 @current_revision_number ||= (self.class.connection.select_values(sql).collect(&:to_i).max || 0)
203 211 @current_revision_number += 1
204 212 end
205 213 end
@@ -1,186 +1,213
1 1 # = Redmine configuration file
2 2 #
3 3 # Each environment has it's own configuration options. If you are only
4 4 # running in production, only the production block needs to be configured.
5 5 # Environment specific configuration options override the default ones.
6 6 #
7 7 # Note that this file needs to be a valid YAML file.
8 8 # DO NOT USE TABS! Use 2 spaces instead of tabs for identation.
9 9
10 10 # default configuration options for all environments
11 11 default:
12 12 # Outgoing emails configuration
13 13 # See the examples below and the Rails guide for more configuration options:
14 14 # http://guides.rubyonrails.org/action_mailer_basics.html#action-mailer-configuration
15 15 email_delivery:
16 16
17 17 # ==== Simple SMTP server at localhost
18 18 #
19 19 # email_delivery:
20 20 # delivery_method: :smtp
21 21 # smtp_settings:
22 22 # address: "localhost"
23 23 # port: 25
24 24 #
25 25 # ==== SMTP server at example.com using LOGIN authentication and checking HELO for foo.com
26 26 #
27 27 # email_delivery:
28 28 # delivery_method: :smtp
29 29 # smtp_settings:
30 30 # address: "example.com"
31 31 # port: 25
32 32 # authentication: :login
33 33 # domain: 'foo.com'
34 34 # user_name: 'myaccount'
35 35 # password: 'password'
36 36 #
37 37 # ==== SMTP server at example.com using PLAIN authentication
38 38 #
39 39 # email_delivery:
40 40 # delivery_method: :smtp
41 41 # smtp_settings:
42 42 # address: "example.com"
43 43 # port: 25
44 44 # authentication: :plain
45 45 # domain: 'example.com'
46 46 # user_name: 'myaccount'
47 47 # password: 'password'
48 48 #
49 49 # ==== SMTP server at using TLS (GMail)
50 50 # This might require some additional configuration. See the guides at:
51 51 # http://www.redmine.org/projects/redmine/wiki/EmailConfiguration
52 52 #
53 53 # email_delivery:
54 54 # delivery_method: :smtp
55 55 # smtp_settings:
56 56 # enable_starttls_auto: true
57 57 # address: "smtp.gmail.com"
58 58 # port: 587
59 59 # domain: "smtp.gmail.com" # 'your.domain.com' for GoogleApps
60 60 # authentication: :plain
61 61 # user_name: "your_email@gmail.com"
62 62 # password: "your_password"
63 63 #
64 64 # ==== Sendmail command
65 65 #
66 66 # email_delivery:
67 67 # delivery_method: :sendmail
68 68
69 69 # Absolute path to the directory where attachments are stored.
70 70 # The default is the 'files' directory in your Redmine instance.
71 71 # Your Redmine instance needs to have write permission on this
72 72 # directory.
73 73 # Examples:
74 74 # attachments_storage_path: /var/redmine/files
75 75 # attachments_storage_path: D:/redmine/files
76 76 attachments_storage_path:
77 77
78 78 # Configuration of the autologin cookie.
79 79 # autologin_cookie_name: the name of the cookie (default: autologin)
80 80 # autologin_cookie_path: the cookie path (default: /)
81 81 # autologin_cookie_secure: true sets the cookie secure flag (default: false)
82 82 autologin_cookie_name:
83 83 autologin_cookie_path:
84 84 autologin_cookie_secure:
85 85
86 86 # Configuration of SCM executable command.
87 87 #
88 88 # Absolute path (e.g. /usr/local/bin/hg) or command name (e.g. hg.exe, bzr.exe)
89 89 # On Windows + CRuby, *.cmd, *.bat (e.g. hg.cmd, bzr.bat) does not work.
90 90 #
91 91 # On Windows + JRuby 1.6.2, path which contains spaces does not work.
92 92 # For example, "C:\Program Files\TortoiseHg\hg.exe".
93 93 # If you want to this feature, you need to install to the path which does not contains spaces.
94 94 # For example, "C:\TortoiseHg\hg.exe".
95 95 #
96 96 # Examples:
97 97 # scm_subversion_command: svn # (default: svn)
98 98 # scm_mercurial_command: C:\Program Files\TortoiseHg\hg.exe # (default: hg)
99 99 # scm_git_command: /usr/local/bin/git # (default: git)
100 100 # scm_cvs_command: cvs # (default: cvs)
101 101 # scm_bazaar_command: bzr.exe # (default: bzr)
102 102 # scm_darcs_command: darcs-1.0.9-i386-linux # (default: darcs)
103 103 #
104 104 scm_subversion_command:
105 105 scm_mercurial_command:
106 106 scm_git_command:
107 107 scm_cvs_command:
108 108 scm_bazaar_command:
109 109 scm_darcs_command:
110 110
111 # SCM paths validation.
112 #
113 # You can configure a regular expression for each SCM that will be used to
114 # validate the path of new repositories (eg. path entered by users with the
115 # "Manage repositories" permission and path returned by reposman.rb).
116 # The regexp will be wrapped with \A \z, so it must match the whole path.
117 # And the regexp is case sensitive.
118 #
119 # You can match the project identifier by using %project% in the regexp.
120 #
121 # You can also set a custom hint message for each SCM that will be displayed
122 # on the repository form instead of the default one.
123 #
124 # Examples:
125 # scm_subversion_path_regexp: file:///svnpath/[a-z0-9_]+
126 # scm_subversion_path_info: SVN URL (eg. file:///svnpath/foo)
127 #
128 # scm_git_path_regexp: /gitpath/%project%(\.[a-z0-9_])?/
129 #
130 scm_subversion_path_regexp:
131 scm_mercurial_path_regexp:
132 scm_git_path_regexp:
133 scm_cvs_path_regexp:
134 scm_bazaar_path_regexp:
135 scm_darcs_path_regexp:
136 scm_filesystem_path_regexp:
137
111 138 # Absolute path to the SCM commands errors (stderr) log file.
112 139 # The default is to log in the 'log' directory of your Redmine instance.
113 140 # Example:
114 141 # scm_stderr_log_file: /var/log/redmine_scm_stderr.log
115 142 scm_stderr_log_file:
116 143
117 144 # Key used to encrypt sensitive data in the database (SCM and LDAP passwords).
118 145 # If you don't want to enable data encryption, just leave it blank.
119 146 # WARNING: losing/changing this key will make encrypted data unreadable.
120 147 #
121 148 # If you want to encrypt existing passwords in your database:
122 149 # * set the cipher key here in your configuration file
123 150 # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
124 151 #
125 152 # If you have encrypted data and want to change this key, you have to:
126 153 # * decrypt data using 'rake db:decrypt RAILS_ENV=production' first
127 154 # * change the cipher key here in your configuration file
128 155 # * encrypt data using 'rake db:encrypt RAILS_ENV=production'
129 156 database_cipher_key:
130 157
131 158 # Set this to false to disable plugins' assets mirroring on startup.
132 159 # You can use `rake redmine:plugins:assets` to manually mirror assets
133 160 # to public/plugin_assets when you install/upgrade a Redmine plugin.
134 161 #
135 162 #mirror_plugins_assets_on_startup: false
136 163
137 164 # Your secret key for verifying cookie session data integrity. If you
138 165 # change this key, all old sessions will become invalid! Make sure the
139 166 # secret is at least 30 characters and all random, no regular words or
140 167 # you'll be exposed to dictionary attacks.
141 168 #
142 169 # If you have a load-balancing Redmine cluster, you have to use the
143 170 # same secret token on each machine.
144 171 #secret_token: 'change it to a long random string'
145 172
146 173 # Absolute path (e.g. /usr/bin/convert, c:/im/convert.exe) to
147 174 # the ImageMagick's `convert` binary. Used to generate attachment thumbnails.
148 175 #imagemagick_convert_command:
149 176
150 177 # Configuration of RMagcik font.
151 178 #
152 179 # Redmine uses RMagcik in order to export gantt png.
153 180 # You don't need this setting if you don't install RMagcik.
154 181 #
155 182 # In CJK (Chinese, Japanese and Korean),
156 183 # in order to show CJK characters correctly,
157 184 # you need to set this configuration.
158 185 #
159 186 # Because there is no standard font across platforms in CJK,
160 187 # you need to set a font installed in your server.
161 188 #
162 189 # This setting is not necessary in non CJK.
163 190 #
164 191 # Examples for Japanese:
165 192 # Windows:
166 193 # rmagick_font_path: C:\windows\fonts\msgothic.ttc
167 194 # Linux:
168 195 # rmagick_font_path: /usr/share/fonts/ipa-mincho/ipam.ttf
169 196 #
170 197 rmagick_font_path:
171 198
172 199 # Maximum number of simultaneous AJAX uploads
173 200 #max_concurrent_ajax_uploads: 2
174 201
175 202 # Configure OpenIdAuthentication.store
176 203 #
177 204 # allowed values: :memory, :file, :memcache
178 205 #openid_authentication_store: :memory
179 206
180 207 # specific configuration options for production environment
181 208 # that overrides the default ones
182 209 production:
183 210
184 211 # specific configuration options for development environment
185 212 # that overrides the default ones
186 213 development:
@@ -1,1113 +1,1114
1 1 en:
2 2 # Text direction: Left-to-Right (ltr) or Right-to-Left (rtl)
3 3 direction: ltr
4 4 date:
5 5 formats:
6 6 # Use the strftime parameters for formats.
7 7 # When no format has been given, it uses default.
8 8 # You can provide other formats here if you like!
9 9 default: "%m/%d/%Y"
10 10 short: "%b %d"
11 11 long: "%B %d, %Y"
12 12
13 13 day_names: [Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday]
14 14 abbr_day_names: [Sun, Mon, Tue, Wed, Thu, Fri, Sat]
15 15
16 16 # Don't forget the nil at the beginning; there's no such thing as a 0th month
17 17 month_names: [~, January, February, March, April, May, June, July, August, September, October, November, December]
18 18 abbr_month_names: [~, Jan, Feb, Mar, Apr, May, Jun, Jul, Aug, Sep, Oct, Nov, Dec]
19 19 # Used in date_select and datime_select.
20 20 order:
21 21 - :year
22 22 - :month
23 23 - :day
24 24
25 25 time:
26 26 formats:
27 27 default: "%m/%d/%Y %I:%M %p"
28 28 time: "%I:%M %p"
29 29 short: "%d %b %H:%M"
30 30 long: "%B %d, %Y %H:%M"
31 31 am: "am"
32 32 pm: "pm"
33 33
34 34 datetime:
35 35 distance_in_words:
36 36 half_a_minute: "half a minute"
37 37 less_than_x_seconds:
38 38 one: "less than 1 second"
39 39 other: "less than %{count} seconds"
40 40 x_seconds:
41 41 one: "1 second"
42 42 other: "%{count} seconds"
43 43 less_than_x_minutes:
44 44 one: "less than a minute"
45 45 other: "less than %{count} minutes"
46 46 x_minutes:
47 47 one: "1 minute"
48 48 other: "%{count} minutes"
49 49 about_x_hours:
50 50 one: "about 1 hour"
51 51 other: "about %{count} hours"
52 52 x_hours:
53 53 one: "1 hour"
54 54 other: "%{count} hours"
55 55 x_days:
56 56 one: "1 day"
57 57 other: "%{count} days"
58 58 about_x_months:
59 59 one: "about 1 month"
60 60 other: "about %{count} months"
61 61 x_months:
62 62 one: "1 month"
63 63 other: "%{count} months"
64 64 about_x_years:
65 65 one: "about 1 year"
66 66 other: "about %{count} years"
67 67 over_x_years:
68 68 one: "over 1 year"
69 69 other: "over %{count} years"
70 70 almost_x_years:
71 71 one: "almost 1 year"
72 72 other: "almost %{count} years"
73 73
74 74 number:
75 75 format:
76 76 separator: "."
77 77 delimiter: ""
78 78 precision: 3
79 79
80 80 human:
81 81 format:
82 82 delimiter: ""
83 83 precision: 3
84 84 storage_units:
85 85 format: "%n %u"
86 86 units:
87 87 byte:
88 88 one: "Byte"
89 89 other: "Bytes"
90 90 kb: "KB"
91 91 mb: "MB"
92 92 gb: "GB"
93 93 tb: "TB"
94 94
95 95 # Used in array.to_sentence.
96 96 support:
97 97 array:
98 98 sentence_connector: "and"
99 99 skip_last_comma: false
100 100
101 101 activerecord:
102 102 errors:
103 103 template:
104 104 header:
105 105 one: "1 error prohibited this %{model} from being saved"
106 106 other: "%{count} errors prohibited this %{model} from being saved"
107 107 messages:
108 108 inclusion: "is not included in the list"
109 109 exclusion: "is reserved"
110 110 invalid: "is invalid"
111 111 confirmation: "doesn't match confirmation"
112 112 accepted: "must be accepted"
113 113 empty: "can't be empty"
114 114 blank: "can't be blank"
115 115 too_long: "is too long (maximum is %{count} characters)"
116 116 too_short: "is too short (minimum is %{count} characters)"
117 117 wrong_length: "is the wrong length (should be %{count} characters)"
118 118 taken: "has already been taken"
119 119 not_a_number: "is not a number"
120 120 not_a_date: "is not a valid date"
121 121 greater_than: "must be greater than %{count}"
122 122 greater_than_or_equal_to: "must be greater than or equal to %{count}"
123 123 equal_to: "must be equal to %{count}"
124 124 less_than: "must be less than %{count}"
125 125 less_than_or_equal_to: "must be less than or equal to %{count}"
126 126 odd: "must be odd"
127 127 even: "must be even"
128 128 greater_than_start_date: "must be greater than start date"
129 129 not_same_project: "doesn't belong to the same project"
130 130 circular_dependency: "This relation would create a circular dependency"
131 131 cant_link_an_issue_with_a_descendant: "An issue cannot be linked to one of its subtasks"
132 132 earlier_than_minimum_start_date: "cannot be earlier than %{date} because of preceding issues"
133 133
134 134 actionview_instancetag_blank_option: Please select
135 135
136 136 general_text_No: 'No'
137 137 general_text_Yes: 'Yes'
138 138 general_text_no: 'no'
139 139 general_text_yes: 'yes'
140 140 general_lang_name: 'English'
141 141 general_csv_separator: ','
142 142 general_csv_decimal_separator: '.'
143 143 general_csv_encoding: ISO-8859-1
144 144 general_pdf_fontname: freesans
145 145 general_first_day_of_week: '7'
146 146
147 147 notice_account_updated: Account was successfully updated.
148 148 notice_account_invalid_creditentials: Invalid user or password
149 149 notice_account_password_updated: Password was successfully updated.
150 150 notice_account_wrong_password: Wrong password
151 151 notice_account_register_done: Account was successfully created. An email containing the instructions to activate your account was sent to %{email}.
152 152 notice_account_unknown_email: Unknown user.
153 153 notice_account_not_activated_yet: You haven't activated your account yet. If you want to receive a new activation email, please <a href="%{url}">click this link</a>.
154 154 notice_account_locked: Your account is locked.
155 155 notice_can_t_change_password: This account uses an external authentication source. Impossible to change the password.
156 156 notice_account_lost_email_sent: An email with instructions to choose a new password has been sent to you.
157 157 notice_account_activated: Your account has been activated. You can now log in.
158 158 notice_successful_create: Successful creation.
159 159 notice_successful_update: Successful update.
160 160 notice_successful_delete: Successful deletion.
161 161 notice_successful_connection: Successful connection.
162 162 notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
163 163 notice_locking_conflict: Data has been updated by another user.
164 164 notice_not_authorized: You are not authorized to access this page.
165 165 notice_not_authorized_archived_project: The project you're trying to access has been archived.
166 166 notice_email_sent: "An email was sent to %{value}"
167 167 notice_email_error: "An error occurred while sending mail (%{value})"
168 168 notice_feeds_access_key_reseted: Your Atom access key was reset.
169 169 notice_api_access_key_reseted: Your API access key was reset.
170 170 notice_failed_to_save_issues: "Failed to save %{count} issue(s) on %{total} selected: %{ids}."
171 171 notice_failed_to_save_time_entries: "Failed to save %{count} time entrie(s) on %{total} selected: %{ids}."
172 172 notice_failed_to_save_members: "Failed to save member(s): %{errors}."
173 173 notice_no_issue_selected: "No issue is selected! Please, check the issues you want to edit."
174 174 notice_account_pending: "Your account was created and is now pending administrator approval."
175 175 notice_default_data_loaded: Default configuration successfully loaded.
176 176 notice_unable_delete_version: Unable to delete version.
177 177 notice_unable_delete_time_entry: Unable to delete time log entry.
178 178 notice_issue_done_ratios_updated: Issue done ratios updated.
179 179 notice_gantt_chart_truncated: "The chart was truncated because it exceeds the maximum number of items that can be displayed (%{max})"
180 180 notice_issue_successful_create: "Issue %{id} created."
181 181 notice_issue_update_conflict: "The issue has been updated by an other user while you were editing it."
182 182 notice_account_deleted: "Your account has been permanently deleted."
183 183 notice_user_successful_create: "User %{id} created."
184 184 notice_new_password_must_be_different: The new password must be different from the current password
185 185
186 186 error_can_t_load_default_data: "Default configuration could not be loaded: %{value}"
187 187 error_scm_not_found: "The entry or revision was not found in the repository."
188 188 error_scm_command_failed: "An error occurred when trying to access the repository: %{value}"
189 189 error_scm_annotate: "The entry does not exist or cannot be annotated."
190 190 error_scm_annotate_big_text_file: "The entry cannot be annotated, as it exceeds the maximum text file size."
191 191 error_issue_not_found_in_project: 'The issue was not found or does not belong to this project'
192 192 error_no_tracker_in_project: 'No tracker is associated to this project. Please check the Project settings.'
193 193 error_no_default_issue_status: 'No default issue status is defined. Please check your configuration (Go to "Administration -> Issue statuses").'
194 194 error_can_not_delete_custom_field: Unable to delete custom field
195 195 error_can_not_delete_tracker: "This tracker contains issues and cannot be deleted."
196 196 error_can_not_remove_role: "This role is in use and cannot be deleted."
197 197 error_can_not_reopen_issue_on_closed_version: 'An issue assigned to a closed version cannot be reopened'
198 198 error_can_not_archive_project: This project cannot be archived
199 199 error_issue_done_ratios_not_updated: "Issue done ratios not updated."
200 200 error_workflow_copy_source: 'Please select a source tracker or role'
201 201 error_workflow_copy_target: 'Please select target tracker(s) and role(s)'
202 202 error_unable_delete_issue_status: 'Unable to delete issue status'
203 203 error_unable_to_connect: "Unable to connect (%{value})"
204 204 error_attachment_too_big: "This file cannot be uploaded because it exceeds the maximum allowed file size (%{max_size})"
205 205 error_session_expired: "Your session has expired. Please login again."
206 206 warning_attachments_not_saved: "%{count} file(s) could not be saved."
207 207
208 208 mail_subject_lost_password: "Your %{value} password"
209 209 mail_body_lost_password: 'To change your password, click on the following link:'
210 210 mail_subject_register: "Your %{value} account activation"
211 211 mail_body_register: 'To activate your account, click on the following link:'
212 212 mail_body_account_information_external: "You can use your %{value} account to log in."
213 213 mail_body_account_information: Your account information
214 214 mail_subject_account_activation_request: "%{value} account activation request"
215 215 mail_body_account_activation_request: "A new user (%{value}) has registered. The account is pending your approval:"
216 216 mail_subject_reminder: "%{count} issue(s) due in the next %{days} days"
217 217 mail_body_reminder: "%{count} issue(s) that are assigned to you are due in the next %{days} days:"
218 218 mail_subject_wiki_content_added: "'%{id}' wiki page has been added"
219 219 mail_body_wiki_content_added: "The '%{id}' wiki page has been added by %{author}."
220 220 mail_subject_wiki_content_updated: "'%{id}' wiki page has been updated"
221 221 mail_body_wiki_content_updated: "The '%{id}' wiki page has been updated by %{author}."
222 222
223 223 field_name: Name
224 224 field_description: Description
225 225 field_summary: Summary
226 226 field_is_required: Required
227 227 field_firstname: First name
228 228 field_lastname: Last name
229 229 field_mail: Email
230 230 field_filename: File
231 231 field_filesize: Size
232 232 field_downloads: Downloads
233 233 field_author: Author
234 234 field_created_on: Created
235 235 field_updated_on: Updated
236 236 field_closed_on: Closed
237 237 field_field_format: Format
238 238 field_is_for_all: For all projects
239 239 field_possible_values: Possible values
240 240 field_regexp: Regular expression
241 241 field_min_length: Minimum length
242 242 field_max_length: Maximum length
243 243 field_value: Value
244 244 field_category: Category
245 245 field_title: Title
246 246 field_project: Project
247 247 field_issue: Issue
248 248 field_status: Status
249 249 field_notes: Notes
250 250 field_is_closed: Issue closed
251 251 field_is_default: Default value
252 252 field_tracker: Tracker
253 253 field_subject: Subject
254 254 field_due_date: Due date
255 255 field_assigned_to: Assignee
256 256 field_priority: Priority
257 257 field_fixed_version: Target version
258 258 field_user: User
259 259 field_principal: Principal
260 260 field_role: Role
261 261 field_homepage: Homepage
262 262 field_is_public: Public
263 263 field_parent: Subproject of
264 264 field_is_in_roadmap: Issues displayed in roadmap
265 265 field_login: Login
266 266 field_mail_notification: Email notifications
267 267 field_admin: Administrator
268 268 field_last_login_on: Last connection
269 269 field_language: Language
270 270 field_effective_date: Date
271 271 field_password: Password
272 272 field_new_password: New password
273 273 field_password_confirmation: Confirmation
274 274 field_version: Version
275 275 field_type: Type
276 276 field_host: Host
277 277 field_port: Port
278 278 field_account: Account
279 279 field_base_dn: Base DN
280 280 field_attr_login: Login attribute
281 281 field_attr_firstname: Firstname attribute
282 282 field_attr_lastname: Lastname attribute
283 283 field_attr_mail: Email attribute
284 284 field_onthefly: On-the-fly user creation
285 285 field_start_date: Start date
286 286 field_done_ratio: "% Done"
287 287 field_auth_source: Authentication mode
288 288 field_hide_mail: Hide my email address
289 289 field_comments: Comment
290 290 field_url: URL
291 291 field_start_page: Start page
292 292 field_subproject: Subproject
293 293 field_hours: Hours
294 294 field_activity: Activity
295 295 field_spent_on: Date
296 296 field_identifier: Identifier
297 297 field_is_filter: Used as a filter
298 298 field_issue_to: Related issue
299 299 field_delay: Delay
300 300 field_assignable: Issues can be assigned to this role
301 301 field_redirect_existing_links: Redirect existing links
302 302 field_estimated_hours: Estimated time
303 303 field_column_names: Columns
304 304 field_time_entries: Log time
305 305 field_time_zone: Time zone
306 306 field_searchable: Searchable
307 307 field_default_value: Default value
308 308 field_comments_sorting: Display comments
309 309 field_parent_title: Parent page
310 310 field_editable: Editable
311 311 field_watcher: Watcher
312 312 field_identity_url: OpenID URL
313 313 field_content: Content
314 314 field_group_by: Group results by
315 315 field_sharing: Sharing
316 316 field_parent_issue: Parent task
317 317 field_member_of_group: "Assignee's group"
318 318 field_assigned_to_role: "Assignee's role"
319 319 field_text: Text field
320 320 field_visible: Visible
321 321 field_warn_on_leaving_unsaved: "Warn me when leaving a page with unsaved text"
322 322 field_issues_visibility: Issues visibility
323 323 field_is_private: Private
324 324 field_commit_logs_encoding: Commit messages encoding
325 325 field_scm_path_encoding: Path encoding
326 326 field_path_to_repository: Path to repository
327 327 field_root_directory: Root directory
328 328 field_cvsroot: CVSROOT
329 329 field_cvs_module: Module
330 330 field_repository_is_default: Main repository
331 331 field_multiple: Multiple values
332 332 field_auth_source_ldap_filter: LDAP filter
333 333 field_core_fields: Standard fields
334 334 field_timeout: "Timeout (in seconds)"
335 335 field_board_parent: Parent forum
336 336 field_private_notes: Private notes
337 337 field_inherit_members: Inherit members
338 338 field_generate_password: Generate password
339 339 field_must_change_passwd: Must change password at next logon
340 340 field_default_status: Default status
341 341
342 342 setting_app_title: Application title
343 343 setting_app_subtitle: Application subtitle
344 344 setting_welcome_text: Welcome text
345 345 setting_default_language: Default language
346 346 setting_login_required: Authentication required
347 347 setting_self_registration: Self-registration
348 348 setting_attachment_max_size: Maximum attachment size
349 349 setting_issues_export_limit: Issues export limit
350 350 setting_mail_from: Emission email address
351 351 setting_bcc_recipients: Blind carbon copy recipients (bcc)
352 352 setting_plain_text_mail: Plain text mail (no HTML)
353 353 setting_host_name: Host name and path
354 354 setting_text_formatting: Text formatting
355 355 setting_wiki_compression: Wiki history compression
356 356 setting_feeds_limit: Maximum number of items in Atom feeds
357 357 setting_default_projects_public: New projects are public by default
358 358 setting_autofetch_changesets: Fetch commits automatically
359 359 setting_sys_api_enabled: Enable WS for repository management
360 360 setting_commit_ref_keywords: Referencing keywords
361 361 setting_commit_fix_keywords: Fixing keywords
362 362 setting_autologin: Autologin
363 363 setting_date_format: Date format
364 364 setting_time_format: Time format
365 365 setting_cross_project_issue_relations: Allow cross-project issue relations
366 366 setting_cross_project_subtasks: Allow cross-project subtasks
367 367 setting_issue_list_default_columns: Default columns displayed on the issue list
368 368 setting_repositories_encodings: Attachments and repositories encodings
369 369 setting_emails_header: Email header
370 370 setting_emails_footer: Email footer
371 371 setting_protocol: Protocol
372 372 setting_per_page_options: Objects per page options
373 373 setting_user_format: Users display format
374 374 setting_activity_days_default: Days displayed on project activity
375 375 setting_display_subprojects_issues: Display subprojects issues on main projects by default
376 376 setting_enabled_scm: Enabled SCM
377 377 setting_mail_handler_body_delimiters: "Truncate emails after one of these lines"
378 378 setting_mail_handler_api_enabled: Enable WS for incoming emails
379 379 setting_mail_handler_api_key: API key
380 380 setting_sequential_project_identifiers: Generate sequential project identifiers
381 381 setting_gravatar_enabled: Use Gravatar user icons
382 382 setting_gravatar_default: Default Gravatar image
383 383 setting_diff_max_lines_displayed: Maximum number of diff lines displayed
384 384 setting_file_max_size_displayed: Maximum size of text files displayed inline
385 385 setting_repository_log_display_limit: Maximum number of revisions displayed on file log
386 386 setting_openid: Allow OpenID login and registration
387 387 setting_password_min_length: Minimum password length
388 388 setting_new_project_user_role_id: Role given to a non-admin user who creates a project
389 389 setting_default_projects_modules: Default enabled modules for new projects
390 390 setting_issue_done_ratio: Calculate the issue done ratio with
391 391 setting_issue_done_ratio_issue_field: Use the issue field
392 392 setting_issue_done_ratio_issue_status: Use the issue status
393 393 setting_start_of_week: Start calendars on
394 394 setting_rest_api_enabled: Enable REST web service
395 395 setting_cache_formatted_text: Cache formatted text
396 396 setting_default_notification_option: Default notification option
397 397 setting_commit_logtime_enabled: Enable time logging
398 398 setting_commit_logtime_activity_id: Activity for logged time
399 399 setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
400 400 setting_issue_group_assignment: Allow issue assignment to groups
401 401 setting_default_issue_start_date_to_creation_date: Use current date as start date for new issues
402 402 setting_commit_cross_project_ref: Allow issues of all the other projects to be referenced and fixed
403 403 setting_unsubscribe: Allow users to delete their own account
404 404 setting_session_lifetime: Session maximum lifetime
405 405 setting_session_timeout: Session inactivity timeout
406 406 setting_thumbnails_enabled: Display attachment thumbnails
407 407 setting_thumbnails_size: Thumbnails size (in pixels)
408 408 setting_non_working_week_days: Non-working days
409 409 setting_jsonp_enabled: Enable JSONP support
410 410 setting_default_projects_tracker_ids: Default trackers for new projects
411 411 setting_mail_handler_excluded_filenames: Exclude attachments by name
412 412 setting_force_default_language_for_anonymous: Force default language for anonymous users
413 413 setting_force_default_language_for_loggedin: Force default language for logged-in users
414 414
415 415 permission_add_project: Create project
416 416 permission_add_subprojects: Create subprojects
417 417 permission_edit_project: Edit project
418 418 permission_close_project: Close / reopen the project
419 419 permission_select_project_modules: Select project modules
420 420 permission_manage_members: Manage members
421 421 permission_manage_project_activities: Manage project activities
422 422 permission_manage_versions: Manage versions
423 423 permission_manage_categories: Manage issue categories
424 424 permission_view_issues: View Issues
425 425 permission_add_issues: Add issues
426 426 permission_edit_issues: Edit issues
427 427 permission_manage_issue_relations: Manage issue relations
428 428 permission_set_issues_private: Set issues public or private
429 429 permission_set_own_issues_private: Set own issues public or private
430 430 permission_add_issue_notes: Add notes
431 431 permission_edit_issue_notes: Edit notes
432 432 permission_edit_own_issue_notes: Edit own notes
433 433 permission_view_private_notes: View private notes
434 434 permission_set_notes_private: Set notes as private
435 435 permission_move_issues: Move issues
436 436 permission_delete_issues: Delete issues
437 437 permission_manage_public_queries: Manage public queries
438 438 permission_save_queries: Save queries
439 439 permission_view_gantt: View gantt chart
440 440 permission_view_calendar: View calendar
441 441 permission_view_issue_watchers: View watchers list
442 442 permission_add_issue_watchers: Add watchers
443 443 permission_delete_issue_watchers: Delete watchers
444 444 permission_log_time: Log spent time
445 445 permission_view_time_entries: View spent time
446 446 permission_edit_time_entries: Edit time logs
447 447 permission_edit_own_time_entries: Edit own time logs
448 448 permission_manage_news: Manage news
449 449 permission_comment_news: Comment news
450 450 permission_view_documents: View documents
451 451 permission_add_documents: Add documents
452 452 permission_edit_documents: Edit documents
453 453 permission_delete_documents: Delete documents
454 454 permission_manage_files: Manage files
455 455 permission_view_files: View files
456 456 permission_manage_wiki: Manage wiki
457 457 permission_rename_wiki_pages: Rename wiki pages
458 458 permission_delete_wiki_pages: Delete wiki pages
459 459 permission_view_wiki_pages: View wiki
460 460 permission_view_wiki_edits: View wiki history
461 461 permission_edit_wiki_pages: Edit wiki pages
462 462 permission_delete_wiki_pages_attachments: Delete attachments
463 463 permission_protect_wiki_pages: Protect wiki pages
464 464 permission_manage_repository: Manage repository
465 465 permission_browse_repository: Browse repository
466 466 permission_view_changesets: View changesets
467 467 permission_commit_access: Commit access
468 468 permission_manage_boards: Manage forums
469 469 permission_view_messages: View messages
470 470 permission_add_messages: Post messages
471 471 permission_edit_messages: Edit messages
472 472 permission_edit_own_messages: Edit own messages
473 473 permission_delete_messages: Delete messages
474 474 permission_delete_own_messages: Delete own messages
475 475 permission_export_wiki_pages: Export wiki pages
476 476 permission_manage_subtasks: Manage subtasks
477 477 permission_manage_related_issues: Manage related issues
478 478
479 479 project_module_issue_tracking: Issue tracking
480 480 project_module_time_tracking: Time tracking
481 481 project_module_news: News
482 482 project_module_documents: Documents
483 483 project_module_files: Files
484 484 project_module_wiki: Wiki
485 485 project_module_repository: Repository
486 486 project_module_boards: Forums
487 487 project_module_calendar: Calendar
488 488 project_module_gantt: Gantt
489 489
490 490 label_user: User
491 491 label_user_plural: Users
492 492 label_user_new: New user
493 493 label_user_anonymous: Anonymous
494 494 label_project: Project
495 495 label_project_new: New project
496 496 label_project_plural: Projects
497 497 label_x_projects:
498 498 zero: no projects
499 499 one: 1 project
500 500 other: "%{count} projects"
501 501 label_project_all: All Projects
502 502 label_project_latest: Latest projects
503 503 label_issue: Issue
504 504 label_issue_new: New issue
505 505 label_issue_plural: Issues
506 506 label_issue_view_all: View all issues
507 507 label_issues_by: "Issues by %{value}"
508 508 label_issue_added: Issue added
509 509 label_issue_updated: Issue updated
510 510 label_issue_note_added: Note added
511 511 label_issue_status_updated: Status updated
512 512 label_issue_assigned_to_updated: Assignee updated
513 513 label_issue_priority_updated: Priority updated
514 514 label_document: Document
515 515 label_document_new: New document
516 516 label_document_plural: Documents
517 517 label_document_added: Document added
518 518 label_role: Role
519 519 label_role_plural: Roles
520 520 label_role_new: New role
521 521 label_role_and_permissions: Roles and permissions
522 522 label_role_anonymous: Anonymous
523 523 label_role_non_member: Non member
524 524 label_member: Member
525 525 label_member_new: New member
526 526 label_member_plural: Members
527 527 label_tracker: Tracker
528 528 label_tracker_plural: Trackers
529 529 label_tracker_new: New tracker
530 530 label_workflow: Workflow
531 531 label_issue_status: Issue status
532 532 label_issue_status_plural: Issue statuses
533 533 label_issue_status_new: New status
534 534 label_issue_category: Issue category
535 535 label_issue_category_plural: Issue categories
536 536 label_issue_category_new: New category
537 537 label_custom_field: Custom field
538 538 label_custom_field_plural: Custom fields
539 539 label_custom_field_new: New custom field
540 540 label_enumerations: Enumerations
541 541 label_enumeration_new: New value
542 542 label_information: Information
543 543 label_information_plural: Information
544 544 label_please_login: Please log in
545 545 label_register: Register
546 546 label_login_with_open_id_option: or login with OpenID
547 547 label_password_lost: Lost password
548 548 label_home: Home
549 549 label_my_page: My page
550 550 label_my_account: My account
551 551 label_my_projects: My projects
552 552 label_my_page_block: My page block
553 553 label_administration: Administration
554 554 label_login: Sign in
555 555 label_logout: Sign out
556 556 label_help: Help
557 557 label_reported_issues: Reported issues
558 558 label_assigned_to_me_issues: Issues assigned to me
559 559 label_last_login: Last connection
560 560 label_registered_on: Registered on
561 561 label_activity: Activity
562 562 label_overall_activity: Overall activity
563 563 label_user_activity: "%{value}'s activity"
564 564 label_new: New
565 565 label_logged_as: Logged in as
566 566 label_environment: Environment
567 567 label_authentication: Authentication
568 568 label_auth_source: Authentication mode
569 569 label_auth_source_new: New authentication mode
570 570 label_auth_source_plural: Authentication modes
571 571 label_subproject_plural: Subprojects
572 572 label_subproject_new: New subproject
573 573 label_and_its_subprojects: "%{value} and its subprojects"
574 574 label_min_max_length: Min - Max length
575 575 label_list: List
576 576 label_date: Date
577 577 label_integer: Integer
578 578 label_float: Float
579 579 label_boolean: Boolean
580 580 label_string: Text
581 581 label_text: Long text
582 582 label_attribute: Attribute
583 583 label_attribute_plural: Attributes
584 584 label_no_data: No data to display
585 585 label_change_status: Change status
586 586 label_history: History
587 587 label_attachment: File
588 588 label_attachment_new: New file
589 589 label_attachment_delete: Delete file
590 590 label_attachment_plural: Files
591 591 label_file_added: File added
592 592 label_report: Report
593 593 label_report_plural: Reports
594 594 label_news: News
595 595 label_news_new: Add news
596 596 label_news_plural: News
597 597 label_news_latest: Latest news
598 598 label_news_view_all: View all news
599 599 label_news_added: News added
600 600 label_news_comment_added: Comment added to a news
601 601 label_settings: Settings
602 602 label_overview: Overview
603 603 label_version: Version
604 604 label_version_new: New version
605 605 label_version_plural: Versions
606 606 label_close_versions: Close completed versions
607 607 label_confirmation: Confirmation
608 608 label_export_to: 'Also available in:'
609 609 label_read: Read...
610 610 label_public_projects: Public projects
611 611 label_open_issues: open
612 612 label_open_issues_plural: open
613 613 label_closed_issues: closed
614 614 label_closed_issues_plural: closed
615 615 label_x_open_issues_abbr_on_total:
616 616 zero: 0 open / %{total}
617 617 one: 1 open / %{total}
618 618 other: "%{count} open / %{total}"
619 619 label_x_open_issues_abbr:
620 620 zero: 0 open
621 621 one: 1 open
622 622 other: "%{count} open"
623 623 label_x_closed_issues_abbr:
624 624 zero: 0 closed
625 625 one: 1 closed
626 626 other: "%{count} closed"
627 627 label_x_issues:
628 628 zero: 0 issues
629 629 one: 1 issue
630 630 other: "%{count} issues"
631 631 label_total: Total
632 632 label_total_time: Total time
633 633 label_permissions: Permissions
634 634 label_current_status: Current status
635 635 label_new_statuses_allowed: New statuses allowed
636 636 label_all: all
637 637 label_any: any
638 638 label_none: none
639 639 label_nobody: nobody
640 640 label_next: Next
641 641 label_previous: Previous
642 642 label_used_by: Used by
643 643 label_details: Details
644 644 label_add_note: Add a note
645 645 label_per_page: Per page
646 646 label_calendar: Calendar
647 647 label_months_from: months from
648 648 label_gantt: Gantt
649 649 label_internal: Internal
650 650 label_last_changes: "last %{count} changes"
651 651 label_change_view_all: View all changes
652 652 label_personalize_page: Personalize this page
653 653 label_comment: Comment
654 654 label_comment_plural: Comments
655 655 label_x_comments:
656 656 zero: no comments
657 657 one: 1 comment
658 658 other: "%{count} comments"
659 659 label_comment_add: Add a comment
660 660 label_comment_added: Comment added
661 661 label_comment_delete: Delete comments
662 662 label_query: Custom query
663 663 label_query_plural: Custom queries
664 664 label_query_new: New query
665 665 label_my_queries: My custom queries
666 666 label_filter_add: Add filter
667 667 label_filter_plural: Filters
668 668 label_equals: is
669 669 label_not_equals: is not
670 670 label_in_less_than: in less than
671 671 label_in_more_than: in more than
672 672 label_in_the_next_days: in the next
673 673 label_in_the_past_days: in the past
674 674 label_greater_or_equal: '>='
675 675 label_less_or_equal: '<='
676 676 label_between: between
677 677 label_in: in
678 678 label_today: today
679 679 label_all_time: all time
680 680 label_yesterday: yesterday
681 681 label_this_week: this week
682 682 label_last_week: last week
683 683 label_last_n_weeks: "last %{count} weeks"
684 684 label_last_n_days: "last %{count} days"
685 685 label_this_month: this month
686 686 label_last_month: last month
687 687 label_this_year: this year
688 688 label_date_range: Date range
689 689 label_less_than_ago: less than days ago
690 690 label_more_than_ago: more than days ago
691 691 label_ago: days ago
692 692 label_contains: contains
693 693 label_not_contains: doesn't contain
694 694 label_any_issues_in_project: any issues in project
695 695 label_any_issues_not_in_project: any issues not in project
696 696 label_no_issues_in_project: no issues in project
697 697 label_day_plural: days
698 698 label_repository: Repository
699 699 label_repository_new: New repository
700 700 label_repository_plural: Repositories
701 701 label_browse: Browse
702 702 label_branch: Branch
703 703 label_tag: Tag
704 704 label_revision: Revision
705 705 label_revision_plural: Revisions
706 706 label_revision_id: "Revision %{value}"
707 707 label_associated_revisions: Associated revisions
708 708 label_added: added
709 709 label_modified: modified
710 710 label_copied: copied
711 711 label_renamed: renamed
712 712 label_deleted: deleted
713 713 label_latest_revision: Latest revision
714 714 label_latest_revision_plural: Latest revisions
715 715 label_view_revisions: View revisions
716 716 label_view_all_revisions: View all revisions
717 717 label_max_size: Maximum size
718 718 label_sort_highest: Move to top
719 719 label_sort_higher: Move up
720 720 label_sort_lower: Move down
721 721 label_sort_lowest: Move to bottom
722 722 label_roadmap: Roadmap
723 723 label_roadmap_due_in: "Due in %{value}"
724 724 label_roadmap_overdue: "%{value} late"
725 725 label_roadmap_no_issues: No issues for this version
726 726 label_search: Search
727 727 label_result_plural: Results
728 728 label_all_words: All words
729 729 label_wiki: Wiki
730 730 label_wiki_edit: Wiki edit
731 731 label_wiki_edit_plural: Wiki edits
732 732 label_wiki_page: Wiki page
733 733 label_wiki_page_plural: Wiki pages
734 734 label_index_by_title: Index by title
735 735 label_index_by_date: Index by date
736 736 label_current_version: Current version
737 737 label_preview: Preview
738 738 label_feed_plural: Feeds
739 739 label_changes_details: Details of all changes
740 740 label_issue_tracking: Issue tracking
741 741 label_spent_time: Spent time
742 742 label_overall_spent_time: Overall spent time
743 743 label_f_hour: "%{value} hour"
744 744 label_f_hour_plural: "%{value} hours"
745 745 label_time_tracking: Time tracking
746 746 label_change_plural: Changes
747 747 label_statistics: Statistics
748 748 label_commits_per_month: Commits per month
749 749 label_commits_per_author: Commits per author
750 750 label_diff: diff
751 751 label_view_diff: View differences
752 752 label_diff_inline: inline
753 753 label_diff_side_by_side: side by side
754 754 label_options: Options
755 755 label_copy_workflow_from: Copy workflow from
756 756 label_permissions_report: Permissions report
757 757 label_watched_issues: Watched issues
758 758 label_related_issues: Related issues
759 759 label_applied_status: Applied status
760 760 label_loading: Loading...
761 761 label_relation_new: New relation
762 762 label_relation_delete: Delete relation
763 763 label_relates_to: Related to
764 764 label_duplicates: Duplicates
765 765 label_duplicated_by: Duplicated by
766 766 label_blocks: Blocks
767 767 label_blocked_by: Blocked by
768 768 label_precedes: Precedes
769 769 label_follows: Follows
770 770 label_copied_to: Copied to
771 771 label_copied_from: Copied from
772 772 label_end_to_start: end to start
773 773 label_end_to_end: end to end
774 774 label_start_to_start: start to start
775 775 label_start_to_end: start to end
776 776 label_stay_logged_in: Stay logged in
777 777 label_disabled: disabled
778 778 label_show_completed_versions: Show completed versions
779 779 label_me: me
780 780 label_board: Forum
781 781 label_board_new: New forum
782 782 label_board_plural: Forums
783 783 label_board_locked: Locked
784 784 label_board_sticky: Sticky
785 785 label_topic_plural: Topics
786 786 label_message_plural: Messages
787 787 label_message_last: Last message
788 788 label_message_new: New message
789 789 label_message_posted: Message added
790 790 label_reply_plural: Replies
791 791 label_send_information: Send account information to the user
792 792 label_year: Year
793 793 label_month: Month
794 794 label_week: Week
795 795 label_date_from: From
796 796 label_date_to: To
797 797 label_language_based: Based on user's language
798 798 label_sort_by: "Sort by %{value}"
799 799 label_send_test_email: Send a test email
800 800 label_feeds_access_key: Atom access key
801 801 label_missing_feeds_access_key: Missing a Atom access key
802 802 label_feeds_access_key_created_on: "Atom access key created %{value} ago"
803 803 label_module_plural: Modules
804 804 label_added_time_by: "Added by %{author} %{age} ago"
805 805 label_updated_time_by: "Updated by %{author} %{age} ago"
806 806 label_updated_time: "Updated %{value} ago"
807 807 label_jump_to_a_project: Jump to a project...
808 808 label_file_plural: Files
809 809 label_changeset_plural: Changesets
810 810 label_default_columns: Default columns
811 811 label_no_change_option: (No change)
812 812 label_bulk_edit_selected_issues: Bulk edit selected issues
813 813 label_bulk_edit_selected_time_entries: Bulk edit selected time entries
814 814 label_theme: Theme
815 815 label_default: Default
816 816 label_search_titles_only: Search titles only
817 817 label_user_mail_option_all: "For any event on all my projects"
818 818 label_user_mail_option_selected: "For any event on the selected projects only..."
819 819 label_user_mail_option_none: "No events"
820 820 label_user_mail_option_only_my_events: "Only for things I watch or I'm involved in"
821 821 label_user_mail_option_only_assigned: "Only for things I am assigned to"
822 822 label_user_mail_option_only_owner: "Only for things I am the owner of"
823 823 label_user_mail_no_self_notified: "I don't want to be notified of changes that I make myself"
824 824 label_registration_activation_by_email: account activation by email
825 825 label_registration_manual_activation: manual account activation
826 826 label_registration_automatic_activation: automatic account activation
827 827 label_display_per_page: "Per page: %{value}"
828 828 label_age: Age
829 829 label_change_properties: Change properties
830 830 label_general: General
831 831 label_more: More
832 832 label_scm: SCM
833 833 label_plugins: Plugins
834 834 label_ldap_authentication: LDAP authentication
835 835 label_downloads_abbr: D/L
836 836 label_optional_description: Optional description
837 837 label_add_another_file: Add another file
838 838 label_preferences: Preferences
839 839 label_chronological_order: In chronological order
840 840 label_reverse_chronological_order: In reverse chronological order
841 841 label_planning: Planning
842 842 label_incoming_emails: Incoming emails
843 843 label_generate_key: Generate a key
844 844 label_issue_watchers: Watchers
845 845 label_example: Example
846 846 label_display: Display
847 847 label_sort: Sort
848 848 label_ascending: Ascending
849 849 label_descending: Descending
850 850 label_date_from_to: From %{start} to %{end}
851 851 label_wiki_content_added: Wiki page added
852 852 label_wiki_content_updated: Wiki page updated
853 853 label_group: Group
854 854 label_group_plural: Groups
855 855 label_group_new: New group
856 856 label_group_anonymous: Anonymous users
857 857 label_group_non_member: Non member users
858 858 label_time_entry_plural: Spent time
859 859 label_version_sharing_none: Not shared
860 860 label_version_sharing_descendants: With subprojects
861 861 label_version_sharing_hierarchy: With project hierarchy
862 862 label_version_sharing_tree: With project tree
863 863 label_version_sharing_system: With all projects
864 864 label_update_issue_done_ratios: Update issue done ratios
865 865 label_copy_source: Source
866 866 label_copy_target: Target
867 867 label_copy_same_as_target: Same as target
868 868 label_display_used_statuses_only: Only display statuses that are used by this tracker
869 869 label_api_access_key: API access key
870 870 label_missing_api_access_key: Missing an API access key
871 871 label_api_access_key_created_on: "API access key created %{value} ago"
872 872 label_profile: Profile
873 873 label_subtask_plural: Subtasks
874 874 label_project_copy_notifications: Send email notifications during the project copy
875 875 label_principal_search: "Search for user or group:"
876 876 label_user_search: "Search for user:"
877 877 label_additional_workflow_transitions_for_author: Additional transitions allowed when the user is the author
878 878 label_additional_workflow_transitions_for_assignee: Additional transitions allowed when the user is the assignee
879 879 label_issues_visibility_all: All issues
880 880 label_issues_visibility_public: All non private issues
881 881 label_issues_visibility_own: Issues created by or assigned to the user
882 882 label_git_report_last_commit: Report last commit for files and directories
883 883 label_parent_revision: Parent
884 884 label_child_revision: Child
885 885 label_export_options: "%{export_format} export options"
886 886 label_copy_attachments: Copy attachments
887 887 label_copy_subtasks: Copy subtasks
888 888 label_item_position: "%{position} of %{count}"
889 889 label_completed_versions: Completed versions
890 890 label_search_for_watchers: Search for watchers to add
891 891 label_session_expiration: Session expiration
892 892 label_show_closed_projects: View closed projects
893 893 label_status_transitions: Status transitions
894 894 label_fields_permissions: Fields permissions
895 895 label_readonly: Read-only
896 896 label_required: Required
897 897 label_hidden: Hidden
898 898 label_attribute_of_project: "Project's %{name}"
899 899 label_attribute_of_issue: "Issue's %{name}"
900 900 label_attribute_of_author: "Author's %{name}"
901 901 label_attribute_of_assigned_to: "Assignee's %{name}"
902 902 label_attribute_of_user: "User's %{name}"
903 903 label_attribute_of_fixed_version: "Target version's %{name}"
904 904 label_cross_project_descendants: With subprojects
905 905 label_cross_project_tree: With project tree
906 906 label_cross_project_hierarchy: With project hierarchy
907 907 label_cross_project_system: With all projects
908 908 label_gantt_progress_line: Progress line
909 909 label_visibility_private: to me only
910 910 label_visibility_roles: to these roles only
911 911 label_visibility_public: to any users
912 912 label_link: Link
913 913 label_only: only
914 914 label_drop_down_list: drop-down list
915 915 label_checkboxes: checkboxes
916 916 label_radio_buttons: radio buttons
917 917 label_link_values_to: Link values to URL
918 918 label_custom_field_select_type: Select the type of object to which the custom field is to be attached
919 919 label_check_for_updates: Check for updates
920 920 label_latest_compatible_version: Latest compatible version
921 921 label_unknown_plugin: Unknown plugin
922 922 label_add_projects: Add projects
923 923
924 924 button_login: Login
925 925 button_submit: Submit
926 926 button_save: Save
927 927 button_check_all: Check all
928 928 button_uncheck_all: Uncheck all
929 929 button_collapse_all: Collapse all
930 930 button_expand_all: Expand all
931 931 button_delete: Delete
932 932 button_create: Create
933 933 button_create_and_continue: Create and continue
934 934 button_test: Test
935 935 button_edit: Edit
936 936 button_edit_associated_wikipage: "Edit associated Wiki page: %{page_title}"
937 937 button_add: Add
938 938 button_change: Change
939 939 button_apply: Apply
940 940 button_clear: Clear
941 941 button_lock: Lock
942 942 button_unlock: Unlock
943 943 button_download: Download
944 944 button_list: List
945 945 button_view: View
946 946 button_move: Move
947 947 button_move_and_follow: Move and follow
948 948 button_back: Back
949 949 button_cancel: Cancel
950 950 button_activate: Activate
951 951 button_sort: Sort
952 952 button_log_time: Log time
953 953 button_rollback: Rollback to this version
954 954 button_watch: Watch
955 955 button_unwatch: Unwatch
956 956 button_reply: Reply
957 957 button_archive: Archive
958 958 button_unarchive: Unarchive
959 959 button_reset: Reset
960 960 button_rename: Rename
961 961 button_change_password: Change password
962 962 button_copy: Copy
963 963 button_copy_and_follow: Copy and follow
964 964 button_annotate: Annotate
965 965 button_update: Update
966 966 button_configure: Configure
967 967 button_quote: Quote
968 968 button_duplicate: Duplicate
969 969 button_show: Show
970 970 button_hide: Hide
971 971 button_edit_section: Edit this section
972 972 button_export: Export
973 973 button_delete_my_account: Delete my account
974 974 button_close: Close
975 975 button_reopen: Reopen
976 976
977 977 status_active: active
978 978 status_registered: registered
979 979 status_locked: locked
980 980
981 981 project_status_active: active
982 982 project_status_closed: closed
983 983 project_status_archived: archived
984 984
985 985 version_status_open: open
986 986 version_status_locked: locked
987 987 version_status_closed: closed
988 988
989 989 field_active: Active
990 990
991 991 text_select_mail_notifications: Select actions for which email notifications should be sent.
992 992 text_regexp_info: eg. ^[A-Z0-9]+$
993 993 text_min_max_length_info: 0 means no restriction
994 994 text_project_destroy_confirmation: Are you sure you want to delete this project and related data?
995 995 text_subprojects_destroy_warning: "Its subproject(s): %{value} will be also deleted."
996 996 text_workflow_edit: Select a role and a tracker to edit the workflow
997 997 text_are_you_sure: Are you sure?
998 998 text_journal_changed: "%{label} changed from %{old} to %{new}"
999 999 text_journal_changed_no_detail: "%{label} updated"
1000 1000 text_journal_set_to: "%{label} set to %{value}"
1001 1001 text_journal_deleted: "%{label} deleted (%{old})"
1002 1002 text_journal_added: "%{label} %{value} added"
1003 1003 text_tip_issue_begin_day: issue beginning this day
1004 1004 text_tip_issue_end_day: issue ending this day
1005 1005 text_tip_issue_begin_end_day: issue beginning and ending this day
1006 1006 text_project_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed, must start with a lower case letter.<br />Once saved, the identifier cannot be changed.'
1007 1007 text_caracters_maximum: "%{count} characters maximum."
1008 1008 text_caracters_minimum: "Must be at least %{count} characters long."
1009 1009 text_length_between: "Length between %{min} and %{max} characters."
1010 1010 text_tracker_no_workflow: No workflow defined for this tracker
1011 1011 text_unallowed_characters: Unallowed characters
1012 1012 text_comma_separated: Multiple values allowed (comma separated).
1013 1013 text_line_separated: Multiple values allowed (one line for each value).
1014 1014 text_issues_ref_in_commit_messages: Referencing and fixing issues in commit messages
1015 1015 text_issue_added: "Issue %{id} has been reported by %{author}."
1016 1016 text_issue_updated: "Issue %{id} has been updated by %{author}."
1017 1017 text_wiki_destroy_confirmation: Are you sure you want to delete this wiki and all its content?
1018 1018 text_issue_category_destroy_question: "Some issues (%{count}) are assigned to this category. What do you want to do?"
1019 1019 text_issue_category_destroy_assignments: Remove category assignments
1020 1020 text_issue_category_reassign_to: Reassign issues to this category
1021 1021 text_user_mail_option: "For unselected projects, you will only receive notifications about things you watch or you're involved in (eg. issues you're the author or assignee)."
1022 1022 text_no_configuration_data: "Roles, trackers, issue statuses and workflow have not been configured yet.\nIt is highly recommended to load the default configuration. You will be able to modify it once loaded."
1023 1023 text_load_default_configuration: Load the default configuration
1024 1024 text_status_changed_by_changeset: "Applied in changeset %{value}."
1025 1025 text_time_logged_by_changeset: "Applied in changeset %{value}."
1026 1026 text_issues_destroy_confirmation: 'Are you sure you want to delete the selected issue(s)?'
1027 1027 text_issues_destroy_descendants_confirmation: "This will also delete %{count} subtask(s)."
1028 1028 text_time_entries_destroy_confirmation: 'Are you sure you want to delete the selected time entr(y/ies)?'
1029 1029 text_select_project_modules: 'Select modules to enable for this project:'
1030 1030 text_default_administrator_account_changed: Default administrator account changed
1031 1031 text_file_repository_writable: Attachments directory writable
1032 1032 text_plugin_assets_writable: Plugin assets directory writable
1033 1033 text_rmagick_available: RMagick available (optional)
1034 1034 text_convert_available: ImageMagick convert available (optional)
1035 1035 text_destroy_time_entries_question: "%{hours} hours were reported on the issues you are about to delete. What do you want to do?"
1036 1036 text_destroy_time_entries: Delete reported hours
1037 1037 text_assign_time_entries_to_project: Assign reported hours to the project
1038 1038 text_reassign_time_entries: 'Reassign reported hours to this issue:'
1039 1039 text_user_wrote: "%{value} wrote:"
1040 1040 text_enumeration_destroy_question: "%{count} objects are assigned to this value."
1041 1041 text_enumeration_category_reassign_to: 'Reassign them to this value:'
1042 1042 text_email_delivery_not_configured: "Email delivery is not configured, and notifications are disabled.\nConfigure your SMTP server in config/configuration.yml and restart the application to enable them."
1043 1043 text_repository_usernames_mapping: "Select or update the Redmine user mapped to each username found in the repository log.\nUsers with the same Redmine and repository username or email are automatically mapped."
1044 1044 text_diff_truncated: '... This diff was truncated because it exceeds the maximum size that can be displayed.'
1045 1045 text_custom_field_possible_values_info: 'One line for each value'
1046 1046 text_wiki_page_destroy_question: "This page has %{descendants} child page(s) and descendant(s). What do you want to do?"
1047 1047 text_wiki_page_nullify_children: "Keep child pages as root pages"
1048 1048 text_wiki_page_destroy_children: "Delete child pages and all their descendants"
1049 1049 text_wiki_page_reassign_children: "Reassign child pages to this parent page"
1050 1050 text_own_membership_delete_confirmation: "You are about to remove some or all of your permissions and may no longer be able to edit this project after that.\nAre you sure you want to continue?"
1051 1051 text_zoom_in: Zoom in
1052 1052 text_zoom_out: Zoom out
1053 1053 text_warn_on_leaving_unsaved: "The current page contains unsaved text that will be lost if you leave this page."
1054 1054 text_scm_path_encoding_note: "Default: UTF-8"
1055 text_subversion_repository_note: "Examples: file:///, http://, https://, svn://, svn+[tunnelscheme]://"
1055 1056 text_git_repository_note: Repository is bare and local (e.g. /gitrepo, c:\gitrepo)
1056 1057 text_mercurial_repository_note: Local repository (e.g. /hgrepo, c:\hgrepo)
1057 1058 text_scm_command: Command
1058 1059 text_scm_command_version: Version
1059 1060 text_scm_config: You can configure your SCM commands in config/configuration.yml. Please restart the application after editing it.
1060 1061 text_scm_command_not_available: SCM command is not available. Please check settings on the administration panel.
1061 1062 text_issue_conflict_resolution_overwrite: "Apply my changes anyway (previous notes will be kept but some changes may be overwritten)"
1062 1063 text_issue_conflict_resolution_add_notes: "Add my notes and discard my other changes"
1063 1064 text_issue_conflict_resolution_cancel: "Discard all my changes and redisplay %{link}"
1064 1065 text_account_destroy_confirmation: "Are you sure you want to proceed?\nYour account will be permanently deleted, with no way to reactivate it."
1065 1066 text_session_expiration_settings: "Warning: changing these settings may expire the current sessions including yours."
1066 1067 text_project_closed: This project is closed and read-only.
1067 1068 text_turning_multiple_off: "If you disable multiple values, multiple values will be removed in order to preserve only one value per item."
1068 1069
1069 1070 default_role_manager: Manager
1070 1071 default_role_developer: Developer
1071 1072 default_role_reporter: Reporter
1072 1073 default_tracker_bug: Bug
1073 1074 default_tracker_feature: Feature
1074 1075 default_tracker_support: Support
1075 1076 default_issue_status_new: New
1076 1077 default_issue_status_in_progress: In Progress
1077 1078 default_issue_status_resolved: Resolved
1078 1079 default_issue_status_feedback: Feedback
1079 1080 default_issue_status_closed: Closed
1080 1081 default_issue_status_rejected: Rejected
1081 1082 default_doc_category_user: User documentation
1082 1083 default_doc_category_tech: Technical documentation
1083 1084 default_priority_low: Low
1084 1085 default_priority_normal: Normal
1085 1086 default_priority_high: High
1086 1087 default_priority_urgent: Urgent
1087 1088 default_priority_immediate: Immediate
1088 1089 default_activity_design: Design
1089 1090 default_activity_development: Development
1090 1091
1091 1092 enumeration_issue_priorities: Issue priorities
1092 1093 enumeration_doc_categories: Document categories
1093 1094 enumeration_activities: Activities (time tracking)
1094 1095 enumeration_system_activity: System Activity
1095 1096 description_filter: Filter
1096 1097 description_search: Searchfield
1097 1098 description_choose_project: Projects
1098 1099 description_project_scope: Search scope
1099 1100 description_notes: Notes
1100 1101 description_message_content: Message content
1101 1102 description_query_sort_criteria_attribute: Sort attribute
1102 1103 description_query_sort_criteria_direction: Sort direction
1103 1104 description_user_mail_notification: Mail notification settings
1104 1105 description_available_columns: Available Columns
1105 1106 description_selected_columns: Selected Columns
1106 1107 description_all_columns: All Columns
1107 1108 description_issue_category_reassign: Choose issue category
1108 1109 description_wiki_subpages_reassign: Choose new parent page
1109 1110 description_date_range_list: Choose range from list
1110 1111 description_date_range_interval: Choose range by selecting start and end date
1111 1112 description_date_from: Enter start date
1112 1113 description_date_to: Enter end date
1113 1114 text_repository_identifier_info: 'Only lower case letters (a-z), numbers, dashes and underscores are allowed.<br />Once saved, the identifier cannot be changed.'
@@ -1,1133 +1,1134
1 1 # French translations for Ruby on Rails
2 2 # by Christian Lescuyer (christian@flyingcoders.com)
3 3 # contributor: Sebastien Grosjean - ZenCocoon.com
4 4 # contributor: Thibaut Cuvelier - Developpez.com
5 5
6 6 fr:
7 7 direction: ltr
8 8 date:
9 9 formats:
10 10 default: "%d/%m/%Y"
11 11 short: "%e %b"
12 12 long: "%e %B %Y"
13 13 long_ordinal: "%e %B %Y"
14 14 only_day: "%e"
15 15
16 16 day_names: [dimanche, lundi, mardi, mercredi, jeudi, vendredi, samedi]
17 17 abbr_day_names: [dim, lun, mar, mer, jeu, ven, sam]
18 18
19 19 # Don't forget the nil at the beginning; there's no such thing as a 0th month
20 20 month_names: [~, janvier, fΓ©vrier, mars, avril, mai, juin, juillet, aoΓ»t, septembre, octobre, novembre, dΓ©cembre]
21 21 abbr_month_names: [~, jan., fΓ©v., mar., avr., mai, juin, juil., aoΓ»t, sept., oct., nov., dΓ©c.]
22 22 # Used in date_select and datime_select.
23 23 order:
24 24 - :day
25 25 - :month
26 26 - :year
27 27
28 28 time:
29 29 formats:
30 30 default: "%d/%m/%Y %H:%M"
31 31 time: "%H:%M"
32 32 short: "%d %b %H:%M"
33 33 long: "%A %d %B %Y %H:%M:%S %Z"
34 34 long_ordinal: "%A %d %B %Y %H:%M:%S %Z"
35 35 only_second: "%S"
36 36 am: 'am'
37 37 pm: 'pm'
38 38
39 39 datetime:
40 40 distance_in_words:
41 41 half_a_minute: "30 secondes"
42 42 less_than_x_seconds:
43 43 zero: "moins d'une seconde"
44 44 one: "moins d'uneΒ seconde"
45 45 other: "moins de %{count}Β secondes"
46 46 x_seconds:
47 47 one: "1Β seconde"
48 48 other: "%{count}Β secondes"
49 49 less_than_x_minutes:
50 50 zero: "moins d'une minute"
51 51 one: "moins d'uneΒ minute"
52 52 other: "moins de %{count}Β minutes"
53 53 x_minutes:
54 54 one: "1Β minute"
55 55 other: "%{count}Β minutes"
56 56 about_x_hours:
57 57 one: "environ une heure"
58 58 other: "environ %{count}Β heures"
59 59 x_hours:
60 60 one: "une heure"
61 61 other: "%{count}Β heures"
62 62 x_days:
63 63 one: "unΒ jour"
64 64 other: "%{count}Β jours"
65 65 about_x_months:
66 66 one: "environ un mois"
67 67 other: "environ %{count}Β mois"
68 68 x_months:
69 69 one: "unΒ mois"
70 70 other: "%{count}Β mois"
71 71 about_x_years:
72 72 one: "environ un an"
73 73 other: "environ %{count}Β ans"
74 74 over_x_years:
75 75 one: "plus d'un an"
76 76 other: "plus de %{count}Β ans"
77 77 almost_x_years:
78 78 one: "presqu'un an"
79 79 other: "presque %{count} ans"
80 80 prompts:
81 81 year: "AnnΓ©e"
82 82 month: "Mois"
83 83 day: "Jour"
84 84 hour: "Heure"
85 85 minute: "Minute"
86 86 second: "Seconde"
87 87
88 88 number:
89 89 format:
90 90 precision: 3
91 91 separator: ','
92 92 delimiter: 'Β '
93 93 currency:
94 94 format:
95 95 unit: '€'
96 96 precision: 2
97 97 format: '%nΒ %u'
98 98 human:
99 99 format:
100 100 precision: 3
101 101 storage_units:
102 102 format: "%n %u"
103 103 units:
104 104 byte:
105 105 one: "octet"
106 106 other: "octets"
107 107 kb: "ko"
108 108 mb: "Mo"
109 109 gb: "Go"
110 110 tb: "To"
111 111
112 112 support:
113 113 array:
114 114 sentence_connector: 'et'
115 115 skip_last_comma: true
116 116 word_connector: ", "
117 117 two_words_connector: " et "
118 118 last_word_connector: " et "
119 119
120 120 activerecord:
121 121 errors:
122 122 template:
123 123 header:
124 124 one: "Impossible d'enregistrer %{model} : une erreur"
125 125 other: "Impossible d'enregistrer %{model} : %{count} erreurs."
126 126 body: "Veuillez vΓ©rifier les champs suivantsΒ :"
127 127 messages:
128 128 inclusion: "n'est pas inclus(e) dans la liste"
129 129 exclusion: "n'est pas disponible"
130 130 invalid: "n'est pas valide"
131 131 confirmation: "ne concorde pas avec la confirmation"
132 132 accepted: "doit Γͺtre acceptΓ©(e)"
133 133 empty: "doit Γͺtre renseignΓ©(e)"
134 134 blank: "doit Γͺtre renseignΓ©(e)"
135 135 too_long: "est trop long (pas plus de %{count} caractères)"
136 136 too_short: "est trop court (au moins %{count} caractères)"
137 137 wrong_length: "ne fait pas la bonne longueur (doit comporter %{count} caractères)"
138 138 taken: "est dΓ©jΓ  utilisΓ©"
139 139 not_a_number: "n'est pas un nombre"
140 140 not_a_date: "n'est pas une date valide"
141 141 greater_than: "doit Γͺtre supΓ©rieur Γ  %{count}"
142 142 greater_than_or_equal_to: "doit Γͺtre supΓ©rieur ou Γ©gal Γ  %{count}"
143 143 equal_to: "doit Γͺtre Γ©gal Γ  %{count}"
144 144 less_than: "doit Γͺtre infΓ©rieur Γ  %{count}"
145 145 less_than_or_equal_to: "doit Γͺtre infΓ©rieur ou Γ©gal Γ  %{count}"
146 146 odd: "doit Γͺtre impair"
147 147 even: "doit Γͺtre pair"
148 148 greater_than_start_date: "doit Γͺtre postΓ©rieure Γ  la date de dΓ©but"
149 149 not_same_project: "n'appartient pas au mΓͺme projet"
150 150 circular_dependency: "Cette relation crΓ©erait une dΓ©pendance circulaire"
151 151 cant_link_an_issue_with_a_descendant: "Une demande ne peut pas Γͺtre liΓ©e Γ  l'une de ses sous-tΓ’ches"
152 152 earlier_than_minimum_start_date: "ne peut pas Γͺtre antΓ©rieure au %{date} Γ  cause des demandes qui prΓ©cΓ¨dent"
153 153
154 154 actionview_instancetag_blank_option: Choisir
155 155
156 156 general_text_No: 'Non'
157 157 general_text_Yes: 'Oui'
158 158 general_text_no: 'non'
159 159 general_text_yes: 'oui'
160 160 general_lang_name: 'FranΓ§ais'
161 161 general_csv_separator: ';'
162 162 general_csv_decimal_separator: ','
163 163 general_csv_encoding: ISO-8859-1
164 164 general_pdf_fontname: freesans
165 165 general_first_day_of_week: '1'
166 166
167 167 notice_account_updated: Le compte a été mis à jour avec succès.
168 168 notice_account_invalid_creditentials: Identifiant ou mot de passe invalide.
169 169 notice_account_password_updated: Mot de passe mis à jour avec succès.
170 170 notice_account_wrong_password: Mot de passe incorrect
171 171 notice_account_register_done: Un message contenant les instructions pour activer votre compte vous a Γ©tΓ© envoyΓ© Γ  l'adresse %{email}.
172 172 notice_account_unknown_email: Aucun compte ne correspond Γ  cette adresse.
173 173 notice_account_not_activated_yet: Vous n'avez pas encore activΓ© votre compte. Si vous voulez recevoir un nouveau message d'activation, veuillez <a href="%{url}">cliquer sur ce lien</a>.
174 174 notice_account_locked: Votre compte est verrouillΓ©.
175 175 notice_can_t_change_password: Ce compte utilise une authentification externe. Impossible de changer le mot de passe.
176 176 notice_account_lost_email_sent: Un message contenant les instructions pour choisir un nouveau mot de passe vous a Γ©tΓ© envoyΓ©.
177 177 notice_account_activated: Votre compte a Γ©tΓ© activΓ©. Vous pouvez Γ  prΓ©sent vous connecter.
178 178 notice_successful_create: Création effectuée avec succès.
179 179 notice_successful_update: Mise à jour effectuée avec succès.
180 180 notice_successful_delete: Suppression effectuée avec succès.
181 181 notice_successful_connection: Connexion rΓ©ussie.
182 182 notice_file_not_found: "La page Γ  laquelle vous souhaitez accΓ©der n'existe pas ou a Γ©tΓ© supprimΓ©e."
183 183 notice_locking_conflict: Les donnΓ©es ont Γ©tΓ© mises Γ  jour par un autre utilisateur. Mise Γ  jour impossible.
184 184 notice_not_authorized: "Vous n'Γͺtes pas autorisΓ© Γ  accΓ©der Γ  cette page."
185 185 notice_not_authorized_archived_project: Le projet auquel vous tentez d'accΓ©der a Γ©tΓ© archivΓ©.
186 186 notice_email_sent: "Un email a Γ©tΓ© envoyΓ© Γ  %{value}"
187 187 notice_email_error: "Erreur lors de l'envoi de l'email (%{value})"
188 188 notice_feeds_access_key_reseted: "Votre clé d'accès aux flux Atom a été réinitialisée."
189 189 notice_api_access_key_reseted: Votre clé d'accès API a été réinitialisée.
190 190 notice_failed_to_save_issues: "%{count} demande(s) sur les %{total} sΓ©lectionnΓ©es n'ont pas pu Γͺtre mise(s) Γ  jour : %{ids}."
191 191 notice_failed_to_save_time_entries: "%{count} temps passΓ©(s) sur les %{total} sΓ©lectionnΓ©s n'ont pas pu Γͺtre mis Γ  jour: %{ids}."
192 192 notice_failed_to_save_members: "Erreur lors de la sauvegarde des membres: %{errors}."
193 193 notice_no_issue_selected: "Aucune demande sΓ©lectionnΓ©e ! Cochez les demandes que vous voulez mettre Γ  jour."
194 194 notice_account_pending: "Votre compte a été créé et attend l'approbation de l'administrateur."
195 195 notice_default_data_loaded: Paramétrage par défaut chargé avec succès.
196 196 notice_unable_delete_version: Impossible de supprimer cette version.
197 197 notice_unable_delete_time_entry: Impossible de supprimer le temps passΓ©.
198 198 notice_issue_done_ratios_updated: L'avancement des demandes a Γ©tΓ© mis Γ  jour.
199 199 notice_gantt_chart_truncated: "Le diagramme a Γ©tΓ© tronquΓ© car il excΓ¨de le nombre maximal d'Γ©lΓ©ments pouvant Γͺtre affichΓ©s (%{max})"
200 200 notice_issue_successful_create: "Demande %{id} créée."
201 201 notice_issue_update_conflict: "La demande a Γ©tΓ© mise Γ  jour par un autre utilisateur pendant que vous la modifiez."
202 202 notice_account_deleted: "Votre compte a Γ©tΓ© dΓ©finitivement supprimΓ©."
203 203 notice_user_successful_create: "Utilisateur %{id} créé."
204 204 notice_new_password_must_be_different: Votre nouveau mot de passe doit Γͺtre diffΓ©rent de votre mot de passe actuel
205 205
206 206 error_can_t_load_default_data: "Une erreur s'est produite lors du chargement du paramΓ©trage : %{value}"
207 207 error_scm_not_found: "L'entrΓ©e et/ou la rΓ©vision demandΓ©e n'existe pas dans le dΓ©pΓ΄t."
208 208 error_scm_command_failed: "Une erreur s'est produite lors de l'accès au dépôt : %{value}"
209 209 error_scm_annotate: "L'entrΓ©e n'existe pas ou ne peut pas Γͺtre annotΓ©e."
210 210 error_scm_annotate_big_text_file: Cette entrΓ©e ne peut pas Γͺtre annotΓ©e car elle excΓ¨de la taille maximale.
211 211 error_issue_not_found_in_project: "La demande n'existe pas ou n'appartient pas Γ  ce projet"
212 212 error_no_tracker_in_project: "Aucun tracker n'est associΓ© Γ  ce projet. VΓ©rifier la configuration du projet."
213 213 error_no_default_issue_status: "Aucun statut de demande n'est dΓ©fini par dΓ©faut. VΓ©rifier votre configuration (Administration -> Statuts de demandes)."
214 214 error_can_not_delete_custom_field: Impossible de supprimer le champ personnalisΓ©
215 215 error_can_not_delete_tracker: Ce tracker contient des demandes et ne peut pas Γͺtre supprimΓ©.
216 216 error_can_not_remove_role: Ce rΓ΄le est utilisΓ© et ne peut pas Γͺtre supprimΓ©.
217 217 error_can_not_reopen_issue_on_closed_version: 'Une demande assignΓ©e Γ  une version fermΓ©e ne peut pas Γͺtre rΓ©ouverte'
218 218 error_can_not_archive_project: "Ce projet ne peut pas Γͺtre archivΓ©"
219 219 error_issue_done_ratios_not_updated: L'avancement des demandes n'a pas pu Γͺtre mis Γ  jour.
220 220 error_workflow_copy_source: 'Veuillez sΓ©lectionner un tracker et/ou un rΓ΄le source'
221 221 error_workflow_copy_target: 'Veuillez sΓ©lectionner les trackers et rΓ΄les cibles'
222 222 error_unable_delete_issue_status: Impossible de supprimer le statut de demande
223 223 error_unable_to_connect: Connexion impossible (%{value})
224 224 error_attachment_too_big: Ce fichier ne peut pas Γͺtre attachΓ© car il excΓ¨de la taille maximale autorisΓ©e (%{max_size})
225 225 error_session_expired: "Votre session a expirΓ©. Veuillez vous reconnecter."
226 226 warning_attachments_not_saved: "%{count} fichier(s) n'ont pas pu Γͺtre sauvegardΓ©s."
227 227
228 228 mail_subject_lost_password: "Votre mot de passe %{value}"
229 229 mail_body_lost_password: 'Pour changer votre mot de passe, cliquez sur le lien suivant :'
230 230 mail_subject_register: "Activation de votre compte %{value}"
231 231 mail_body_register: 'Pour activer votre compte, cliquez sur le lien suivant :'
232 232 mail_body_account_information_external: "Vous pouvez utiliser votre compte %{value} pour vous connecter."
233 233 mail_body_account_information: Paramètres de connexion de votre compte
234 234 mail_subject_account_activation_request: "Demande d'activation d'un compte %{value}"
235 235 mail_body_account_activation_request: "Un nouvel utilisateur (%{value}) s'est inscrit. Son compte nΓ©cessite votre approbation :"
236 236 mail_subject_reminder: "%{count} demande(s) arrivent Γ  Γ©chΓ©ance (%{days})"
237 237 mail_body_reminder: "%{count} demande(s) qui vous sont assignΓ©es arrivent Γ  Γ©chΓ©ance dans les %{days} prochains jours :"
238 238 mail_subject_wiki_content_added: "Page wiki '%{id}' ajoutΓ©e"
239 239 mail_body_wiki_content_added: "La page wiki '%{id}' a Γ©tΓ© ajoutΓ©e par %{author}."
240 240 mail_subject_wiki_content_updated: "Page wiki '%{id}' mise Γ  jour"
241 241 mail_body_wiki_content_updated: "La page wiki '%{id}' a Γ©tΓ© mise Γ  jour par %{author}."
242 242
243 243 field_name: Nom
244 244 field_description: Description
245 245 field_summary: RΓ©sumΓ©
246 246 field_is_required: Obligatoire
247 247 field_firstname: PrΓ©nom
248 248 field_lastname: Nom
249 249 field_mail: Email
250 250 field_filename: Fichier
251 251 field_filesize: Taille
252 252 field_downloads: TΓ©lΓ©chargements
253 253 field_author: Auteur
254 254 field_created_on: Créé
255 255 field_updated_on: Mis-Γ -jour
256 256 field_closed_on: FermΓ©
257 257 field_field_format: Format
258 258 field_is_for_all: Pour tous les projets
259 259 field_possible_values: Valeurs possibles
260 260 field_regexp: Expression régulière
261 261 field_min_length: Longueur minimum
262 262 field_max_length: Longueur maximum
263 263 field_value: Valeur
264 264 field_category: CatΓ©gorie
265 265 field_title: Titre
266 266 field_project: Projet
267 267 field_issue: Demande
268 268 field_status: Statut
269 269 field_notes: Notes
270 270 field_is_closed: Demande fermΓ©e
271 271 field_is_default: Valeur par dΓ©faut
272 272 field_tracker: Tracker
273 273 field_subject: Sujet
274 274 field_due_date: EchΓ©ance
275 275 field_assigned_to: AssignΓ© Γ 
276 276 field_priority: PrioritΓ©
277 277 field_fixed_version: Version cible
278 278 field_user: Utilisateur
279 279 field_principal: Principal
280 280 field_role: RΓ΄le
281 281 field_homepage: Site web
282 282 field_is_public: Public
283 283 field_parent: Sous-projet de
284 284 field_is_in_roadmap: Demandes affichΓ©es dans la roadmap
285 285 field_login: Identifiant
286 286 field_mail_notification: Notifications par mail
287 287 field_admin: Administrateur
288 288 field_last_login_on: Dernière connexion
289 289 field_language: Langue
290 290 field_effective_date: Date
291 291 field_password: Mot de passe
292 292 field_new_password: Nouveau mot de passe
293 293 field_password_confirmation: Confirmation
294 294 field_version: Version
295 295 field_type: Type
296 296 field_host: HΓ΄te
297 297 field_port: Port
298 298 field_account: Compte
299 299 field_base_dn: Base DN
300 300 field_attr_login: Attribut Identifiant
301 301 field_attr_firstname: Attribut PrΓ©nom
302 302 field_attr_lastname: Attribut Nom
303 303 field_attr_mail: Attribut Email
304 304 field_onthefly: CrΓ©ation des utilisateurs Γ  la volΓ©e
305 305 field_start_date: DΓ©but
306 306 field_done_ratio: "% rΓ©alisΓ©"
307 307 field_auth_source: Mode d'authentification
308 308 field_hide_mail: Cacher mon adresse mail
309 309 field_comments: Commentaire
310 310 field_url: URL
311 311 field_start_page: Page de dΓ©marrage
312 312 field_subproject: Sous-projet
313 313 field_hours: Heures
314 314 field_activity: ActivitΓ©
315 315 field_spent_on: Date
316 316 field_identifier: Identifiant
317 317 field_is_filter: UtilisΓ© comme filtre
318 318 field_issue_to: Demande liΓ©e
319 319 field_delay: Retard
320 320 field_assignable: Demandes assignables Γ  ce rΓ΄le
321 321 field_redirect_existing_links: Rediriger les liens existants
322 322 field_estimated_hours: Temps estimΓ©
323 323 field_column_names: Colonnes
324 324 field_time_entries: Temps passΓ©
325 325 field_time_zone: Fuseau horaire
326 326 field_searchable: UtilisΓ© pour les recherches
327 327 field_default_value: Valeur par dΓ©faut
328 328 field_comments_sorting: Afficher les commentaires
329 329 field_parent_title: Page parent
330 330 field_editable: Modifiable
331 331 field_watcher: Observateur
332 332 field_identity_url: URL OpenID
333 333 field_content: Contenu
334 334 field_group_by: Grouper par
335 335 field_sharing: Partage
336 336 field_parent_issue: TΓ’che parente
337 337 field_member_of_group: Groupe de l'assignΓ©
338 338 field_assigned_to_role: RΓ΄le de l'assignΓ©
339 339 field_text: Champ texte
340 340 field_visible: Visible
341 341 field_warn_on_leaving_unsaved: "M'avertir lorsque je quitte une page contenant du texte non sauvegardΓ©"
342 342 field_issues_visibility: VisibilitΓ© des demandes
343 343 field_is_private: PrivΓ©e
344 344 field_commit_logs_encoding: Encodage des messages de commit
345 345 field_scm_path_encoding: Encodage des chemins
346 346 field_path_to_repository: Chemin du dΓ©pΓ΄t
347 347 field_root_directory: RΓ©pertoire racine
348 348 field_cvsroot: CVSROOT
349 349 field_cvs_module: Module
350 350 field_repository_is_default: DΓ©pΓ΄t principal
351 351 field_multiple: Valeurs multiples
352 352 field_auth_source_ldap_filter: Filtre LDAP
353 353 field_core_fields: Champs standards
354 354 field_timeout: "Timeout (en secondes)"
355 355 field_board_parent: Forum parent
356 356 field_private_notes: Notes privΓ©es
357 357 field_inherit_members: HΓ©riter les membres
358 358 field_generate_password: GΓ©nΓ©rer un mot de passe
359 359 field_must_change_passwd: Doit changer de mot de passe Γ  la prochaine connexion
360 360 field_default_status: Statut par dΓ©faut
361 361
362 362 setting_app_title: Titre de l'application
363 363 setting_app_subtitle: Sous-titre de l'application
364 364 setting_welcome_text: Texte d'accueil
365 365 setting_default_language: Langue par dΓ©faut
366 366 setting_login_required: Authentification obligatoire
367 367 setting_self_registration: Inscription des nouveaux utilisateurs
368 368 setting_attachment_max_size: Taille maximale des fichiers
369 369 setting_issues_export_limit: Limite d'exportation des demandes
370 370 setting_mail_from: Adresse d'Γ©mission
371 371 setting_bcc_recipients: Destinataires en copie cachΓ©e (cci)
372 372 setting_plain_text_mail: Mail en texte brut (non HTML)
373 373 setting_host_name: Nom d'hΓ΄te et chemin
374 374 setting_text_formatting: Formatage du texte
375 375 setting_wiki_compression: Compression de l'historique des pages wiki
376 376 setting_feeds_limit: Nombre maximal d'Γ©lΓ©ments dans les flux Atom
377 377 setting_default_projects_public: DΓ©finir les nouveaux projets comme publics par dΓ©faut
378 378 setting_autofetch_changesets: RΓ©cupΓ©ration automatique des commits
379 379 setting_sys_api_enabled: Activer les WS pour la gestion des dΓ©pΓ΄ts
380 380 setting_commit_ref_keywords: Mots-clΓ©s de rΓ©fΓ©rencement
381 381 setting_commit_fix_keywords: Mots-clΓ©s de rΓ©solution
382 382 setting_autologin: DurΓ©e maximale de connexion automatique
383 383 setting_date_format: Format de date
384 384 setting_time_format: Format d'heure
385 385 setting_cross_project_issue_relations: Autoriser les relations entre demandes de diffΓ©rents projets
386 386 setting_cross_project_subtasks: Autoriser les sous-tΓ’ches dans des projets diffΓ©rents
387 387 setting_issue_list_default_columns: Colonnes affichΓ©es par dΓ©faut sur la liste des demandes
388 388 setting_repositories_encodings: Encodages des fichiers et des dΓ©pΓ΄ts
389 389 setting_emails_header: En-tΓͺte des emails
390 390 setting_emails_footer: Pied-de-page des emails
391 391 setting_protocol: Protocole
392 392 setting_per_page_options: Options d'objets affichΓ©s par page
393 393 setting_user_format: Format d'affichage des utilisateurs
394 394 setting_activity_days_default: Nombre de jours affichΓ©s sur l'activitΓ© des projets
395 395 setting_display_subprojects_issues: Afficher par dΓ©faut les demandes des sous-projets sur les projets principaux
396 396 setting_enabled_scm: SCM activΓ©s
397 397 setting_mail_handler_body_delimiters: "Tronquer les emails après l'une de ces lignes"
398 398 setting_mail_handler_api_enabled: "Activer le WS pour la rΓ©ception d'emails"
399 399 setting_mail_handler_api_key: ClΓ© de protection de l'API
400 400 setting_sequential_project_identifiers: GΓ©nΓ©rer des identifiants de projet sΓ©quentiels
401 401 setting_gravatar_enabled: Afficher les Gravatar des utilisateurs
402 402 setting_gravatar_default: Image Gravatar par dΓ©faut
403 403 setting_diff_max_lines_displayed: Nombre maximum de lignes de diff affichΓ©es
404 404 setting_file_max_size_displayed: Taille maximum des fichiers texte affichΓ©s en ligne
405 405 setting_repository_log_display_limit: "Nombre maximum de rΓ©visions affichΓ©es sur l'historique d'un fichier"
406 406 setting_openid: "Autoriser l'authentification et l'enregistrement OpenID"
407 407 setting_password_min_length: Longueur minimum des mots de passe
408 408 setting_new_project_user_role_id: RΓ΄le donnΓ© Γ  un utilisateur non-administrateur qui crΓ©e un projet
409 409 setting_default_projects_modules: Modules activΓ©s par dΓ©faut pour les nouveaux projets
410 410 setting_issue_done_ratio: Calcul de l'avancement des demandes
411 411 setting_issue_done_ratio_issue_field: 'Utiliser le champ % effectuΓ©'
412 412 setting_issue_done_ratio_issue_status: Utiliser le statut
413 413 setting_start_of_week: Jour de dΓ©but des calendriers
414 414 setting_rest_api_enabled: Activer l'API REST
415 415 setting_cache_formatted_text: Mettre en cache le texte formatΓ©
416 416 setting_default_notification_option: Option de notification par dΓ©faut
417 417 setting_commit_logtime_enabled: Permettre la saisie de temps
418 418 setting_commit_logtime_activity_id: ActivitΓ© pour le temps saisi
419 419 setting_gantt_items_limit: Nombre maximum d'Γ©lΓ©ments affichΓ©s sur le gantt
420 420 setting_issue_group_assignment: Permettre l'assignement des demandes aux groupes
421 421 setting_default_issue_start_date_to_creation_date: Donner Γ  la date de dΓ©but d'une nouvelle demande la valeur de la date du jour
422 422 setting_commit_cross_project_ref: Permettre le rΓ©fΓ©rencement et la rΓ©solution des demandes de tous les autres projets
423 423 setting_unsubscribe: Permettre aux utilisateurs de supprimer leur propre compte
424 424 setting_session_lifetime: DurΓ©e de vie maximale des sessions
425 425 setting_session_timeout: DurΓ©e maximale d'inactivitΓ©
426 426 setting_thumbnails_enabled: Afficher les vignettes des images
427 427 setting_thumbnails_size: Taille des vignettes (en pixels)
428 428 setting_non_working_week_days: Jours non travaillΓ©s
429 429 setting_jsonp_enabled: Activer le support JSONP
430 430 setting_default_projects_tracker_ids: Trackers par dΓ©faut pour les nouveaux projets
431 431 setting_mail_handler_excluded_filenames: Exclure les fichiers attachΓ©s par leur nom
432 432 setting_force_default_language_for_anonymous: Forcer la langue par dΓ©fault pour les utilisateurs anonymes
433 433 setting_force_default_language_for_loggedin: Forcer la langue par dΓ©fault pour les utilisateurs identifiΓ©s
434 434
435 435 permission_add_project: CrΓ©er un projet
436 436 permission_add_subprojects: CrΓ©er des sous-projets
437 437 permission_edit_project: Modifier le projet
438 438 permission_close_project: Fermer / rΓ©ouvrir le projet
439 439 permission_select_project_modules: Choisir les modules
440 440 permission_manage_members: GΓ©rer les membres
441 441 permission_manage_project_activities: GΓ©rer les activitΓ©s
442 442 permission_manage_versions: GΓ©rer les versions
443 443 permission_manage_categories: GΓ©rer les catΓ©gories de demandes
444 444 permission_view_issues: Voir les demandes
445 445 permission_add_issues: CrΓ©er des demandes
446 446 permission_edit_issues: Modifier les demandes
447 447 permission_manage_issue_relations: GΓ©rer les relations
448 448 permission_set_issues_private: Rendre les demandes publiques ou privΓ©es
449 449 permission_set_own_issues_private: Rendre ses propres demandes publiques ou privΓ©es
450 450 permission_add_issue_notes: Ajouter des notes
451 451 permission_edit_issue_notes: Modifier les notes
452 452 permission_edit_own_issue_notes: Modifier ses propres notes
453 453 permission_view_private_notes: Voir les notes privΓ©es
454 454 permission_set_notes_private: Rendre les notes privΓ©es
455 455 permission_move_issues: DΓ©placer les demandes
456 456 permission_delete_issues: Supprimer les demandes
457 457 permission_manage_public_queries: GΓ©rer les requΓͺtes publiques
458 458 permission_save_queries: Sauvegarder les requΓͺtes
459 459 permission_view_gantt: Voir le gantt
460 460 permission_view_calendar: Voir le calendrier
461 461 permission_view_issue_watchers: Voir la liste des observateurs
462 462 permission_add_issue_watchers: Ajouter des observateurs
463 463 permission_delete_issue_watchers: Supprimer des observateurs
464 464 permission_log_time: Saisir le temps passΓ©
465 465 permission_view_time_entries: Voir le temps passΓ©
466 466 permission_edit_time_entries: Modifier les temps passΓ©s
467 467 permission_edit_own_time_entries: Modifier son propre temps passΓ©
468 468 permission_manage_news: GΓ©rer les annonces
469 469 permission_comment_news: Commenter les annonces
470 470 permission_view_documents: Voir les documents
471 471 permission_add_documents: Ajouter des documents
472 472 permission_edit_documents: Modifier les documents
473 473 permission_delete_documents: Supprimer les documents
474 474 permission_manage_files: GΓ©rer les fichiers
475 475 permission_view_files: Voir les fichiers
476 476 permission_manage_wiki: GΓ©rer le wiki
477 477 permission_rename_wiki_pages: Renommer les pages
478 478 permission_delete_wiki_pages: Supprimer les pages
479 479 permission_view_wiki_pages: Voir le wiki
480 480 permission_view_wiki_edits: "Voir l'historique des modifications"
481 481 permission_edit_wiki_pages: Modifier les pages
482 482 permission_delete_wiki_pages_attachments: Supprimer les fichiers joints
483 483 permission_protect_wiki_pages: ProtΓ©ger les pages
484 484 permission_manage_repository: GΓ©rer le dΓ©pΓ΄t de sources
485 485 permission_browse_repository: Parcourir les sources
486 486 permission_view_changesets: Voir les rΓ©visions
487 487 permission_commit_access: Droit de commit
488 488 permission_manage_boards: GΓ©rer les forums
489 489 permission_view_messages: Voir les messages
490 490 permission_add_messages: Poster un message
491 491 permission_edit_messages: Modifier les messages
492 492 permission_edit_own_messages: Modifier ses propres messages
493 493 permission_delete_messages: Supprimer les messages
494 494 permission_delete_own_messages: Supprimer ses propres messages
495 495 permission_export_wiki_pages: Exporter les pages
496 496 permission_manage_subtasks: GΓ©rer les sous-tΓ’ches
497 497 permission_manage_related_issues: GΓ©rer les demandes associΓ©es
498 498
499 499 project_module_issue_tracking: Suivi des demandes
500 500 project_module_time_tracking: Suivi du temps passΓ©
501 501 project_module_news: Publication d'annonces
502 502 project_module_documents: Publication de documents
503 503 project_module_files: Publication de fichiers
504 504 project_module_wiki: Wiki
505 505 project_module_repository: DΓ©pΓ΄t de sources
506 506 project_module_boards: Forums de discussion
507 507 project_module_calendar: Calendrier
508 508 project_module_gantt: Gantt
509 509
510 510 label_user: Utilisateur
511 511 label_user_plural: Utilisateurs
512 512 label_user_new: Nouvel utilisateur
513 513 label_user_anonymous: Anonyme
514 514 label_project: Projet
515 515 label_project_new: Nouveau projet
516 516 label_project_plural: Projets
517 517 label_x_projects:
518 518 zero: aucun projet
519 519 one: un projet
520 520 other: "%{count} projets"
521 521 label_project_all: Tous les projets
522 522 label_project_latest: Derniers projets
523 523 label_issue: Demande
524 524 label_issue_new: Nouvelle demande
525 525 label_issue_plural: Demandes
526 526 label_issue_view_all: Voir toutes les demandes
527 527 label_issues_by: "Demandes par %{value}"
528 528 label_issue_added: Demande ajoutΓ©e
529 529 label_issue_updated: Demande mise Γ  jour
530 530 label_issue_note_added: Note ajoutΓ©e
531 531 label_issue_status_updated: Statut changΓ©
532 532 label_issue_assigned_to_updated: AssignΓ© changΓ©
533 533 label_issue_priority_updated: PrioritΓ© changΓ©e
534 534 label_document: Document
535 535 label_document_new: Nouveau document
536 536 label_document_plural: Documents
537 537 label_document_added: Document ajoutΓ©
538 538 label_role: RΓ΄le
539 539 label_role_plural: RΓ΄les
540 540 label_role_new: Nouveau rΓ΄le
541 541 label_role_and_permissions: RΓ΄les et permissions
542 542 label_role_anonymous: Anonyme
543 543 label_role_non_member: Non membre
544 544 label_member: Membre
545 545 label_member_new: Nouveau membre
546 546 label_member_plural: Membres
547 547 label_tracker: Tracker
548 548 label_tracker_plural: Trackers
549 549 label_tracker_new: Nouveau tracker
550 550 label_workflow: Workflow
551 551 label_issue_status: Statut de demandes
552 552 label_issue_status_plural: Statuts de demandes
553 553 label_issue_status_new: Nouveau statut
554 554 label_issue_category: CatΓ©gorie de demandes
555 555 label_issue_category_plural: CatΓ©gories de demandes
556 556 label_issue_category_new: Nouvelle catΓ©gorie
557 557 label_custom_field: Champ personnalisΓ©
558 558 label_custom_field_plural: Champs personnalisΓ©s
559 559 label_custom_field_new: Nouveau champ personnalisΓ©
560 560 label_enumerations: Listes de valeurs
561 561 label_enumeration_new: Nouvelle valeur
562 562 label_information: Information
563 563 label_information_plural: Informations
564 564 label_please_login: Identification
565 565 label_register: S'enregistrer
566 566 label_login_with_open_id_option: S'authentifier avec OpenID
567 567 label_password_lost: Mot de passe perdu
568 568 label_home: Accueil
569 569 label_my_page: Ma page
570 570 label_my_account: Mon compte
571 571 label_my_projects: Mes projets
572 572 label_my_page_block: Blocs disponibles
573 573 label_administration: Administration
574 574 label_login: Connexion
575 575 label_logout: DΓ©connexion
576 576 label_help: Aide
577 577 label_reported_issues: Demandes soumises
578 578 label_assigned_to_me_issues: Demandes qui me sont assignΓ©es
579 579 label_last_login: Dernière connexion
580 580 label_registered_on: Inscrit le
581 581 label_activity: ActivitΓ©
582 582 label_overall_activity: ActivitΓ© globale
583 583 label_user_activity: "ActivitΓ© de %{value}"
584 584 label_new: Nouveau
585 585 label_logged_as: ConnectΓ© en tant que
586 586 label_environment: Environnement
587 587 label_authentication: Authentification
588 588 label_auth_source: Mode d'authentification
589 589 label_auth_source_new: Nouveau mode d'authentification
590 590 label_auth_source_plural: Modes d'authentification
591 591 label_subproject_plural: Sous-projets
592 592 label_subproject_new: Nouveau sous-projet
593 593 label_and_its_subprojects: "%{value} et ses sous-projets"
594 594 label_min_max_length: Longueurs mini - maxi
595 595 label_list: Liste
596 596 label_date: Date
597 597 label_integer: Entier
598 598 label_float: Nombre dΓ©cimal
599 599 label_boolean: BoolΓ©en
600 600 label_string: Texte
601 601 label_text: Texte long
602 602 label_attribute: Attribut
603 603 label_attribute_plural: Attributs
604 604 label_no_data: Aucune donnΓ©e Γ  afficher
605 605 label_change_status: Changer le statut
606 606 label_history: Historique
607 607 label_attachment: Fichier
608 608 label_attachment_new: Nouveau fichier
609 609 label_attachment_delete: Supprimer le fichier
610 610 label_attachment_plural: Fichiers
611 611 label_file_added: Fichier ajoutΓ©
612 612 label_report: Rapport
613 613 label_report_plural: Rapports
614 614 label_news: Annonce
615 615 label_news_new: Nouvelle annonce
616 616 label_news_plural: Annonces
617 617 label_news_latest: Dernières annonces
618 618 label_news_view_all: Voir toutes les annonces
619 619 label_news_added: Annonce ajoutΓ©e
620 620 label_news_comment_added: Commentaire ajoutΓ© Γ  une annonce
621 621 label_settings: Configuration
622 622 label_overview: AperΓ§u
623 623 label_version: Version
624 624 label_version_new: Nouvelle version
625 625 label_version_plural: Versions
626 626 label_close_versions: Fermer les versions terminΓ©es
627 627 label_confirmation: Confirmation
628 628 label_export_to: 'Formats disponibles :'
629 629 label_read: Lire...
630 630 label_public_projects: Projets publics
631 631 label_open_issues: ouvert
632 632 label_open_issues_plural: ouverts
633 633 label_closed_issues: fermΓ©
634 634 label_closed_issues_plural: fermΓ©s
635 635 label_x_open_issues_abbr_on_total:
636 636 zero: 0 ouverte sur %{total}
637 637 one: 1 ouverte sur %{total}
638 638 other: "%{count} ouvertes sur %{total}"
639 639 label_x_open_issues_abbr:
640 640 zero: 0 ouverte
641 641 one: 1 ouverte
642 642 other: "%{count} ouvertes"
643 643 label_x_closed_issues_abbr:
644 644 zero: 0 fermΓ©e
645 645 one: 1 fermΓ©e
646 646 other: "%{count} fermΓ©es"
647 647 label_x_issues:
648 648 zero: 0 demande
649 649 one: 1 demande
650 650 other: "%{count} demandes"
651 651 label_total: Total
652 652 label_total_time: Temps total
653 653 label_permissions: Permissions
654 654 label_current_status: Statut actuel
655 655 label_new_statuses_allowed: Nouveaux statuts autorisΓ©s
656 656 label_all: tous
657 657 label_any: tous
658 658 label_none: aucun
659 659 label_nobody: personne
660 660 label_next: Suivant
661 661 label_previous: PrΓ©cΓ©dent
662 662 label_used_by: UtilisΓ© par
663 663 label_details: DΓ©tails
664 664 label_add_note: Ajouter une note
665 665 label_per_page: Par page
666 666 label_calendar: Calendrier
667 667 label_months_from: mois depuis
668 668 label_gantt: Gantt
669 669 label_internal: Interne
670 670 label_last_changes: "%{count} derniers changements"
671 671 label_change_view_all: Voir tous les changements
672 672 label_personalize_page: Personnaliser cette page
673 673 label_comment: Commentaire
674 674 label_comment_plural: Commentaires
675 675 label_x_comments:
676 676 zero: aucun commentaire
677 677 one: un commentaire
678 678 other: "%{count} commentaires"
679 679 label_comment_add: Ajouter un commentaire
680 680 label_comment_added: Commentaire ajoutΓ©
681 681 label_comment_delete: Supprimer les commentaires
682 682 label_query: Rapport personnalisΓ©
683 683 label_query_plural: Rapports personnalisΓ©s
684 684 label_query_new: Nouveau rapport
685 685 label_my_queries: Mes rapports personnalisΓ©s
686 686 label_filter_add: Ajouter le filtre
687 687 label_filter_plural: Filtres
688 688 label_equals: Γ©gal
689 689 label_not_equals: diffΓ©rent
690 690 label_in_less_than: dans moins de
691 691 label_in_more_than: dans plus de
692 692 label_in_the_next_days: dans les prochains jours
693 693 label_in_the_past_days: dans les derniers jours
694 694 label_greater_or_equal: '>='
695 695 label_less_or_equal: '<='
696 696 label_between: entre
697 697 label_in: dans
698 698 label_today: aujourd'hui
699 699 label_all_time: toute la pΓ©riode
700 700 label_yesterday: hier
701 701 label_this_week: cette semaine
702 702 label_last_week: la semaine dernière
703 703 label_last_n_weeks: "les %{count} dernières semaines"
704 704 label_last_n_days: "les %{count} derniers jours"
705 705 label_this_month: ce mois-ci
706 706 label_last_month: le mois dernier
707 707 label_this_year: cette annΓ©e
708 708 label_date_range: PΓ©riode
709 709 label_less_than_ago: il y a moins de
710 710 label_more_than_ago: il y a plus de
711 711 label_ago: il y a
712 712 label_contains: contient
713 713 label_not_contains: ne contient pas
714 714 label_any_issues_in_project: une demande du projet
715 715 label_any_issues_not_in_project: une demande hors du projet
716 716 label_no_issues_in_project: aucune demande du projet
717 717 label_day_plural: jours
718 718 label_repository: DΓ©pΓ΄t
719 719 label_repository_new: Nouveau dΓ©pΓ΄t
720 720 label_repository_plural: DΓ©pΓ΄ts
721 721 label_browse: Parcourir
722 722 label_branch: Branche
723 723 label_tag: Tag
724 724 label_revision: RΓ©vision
725 725 label_revision_plural: RΓ©visions
726 726 label_revision_id: "RΓ©vision %{value}"
727 727 label_associated_revisions: RΓ©visions associΓ©es
728 728 label_added: ajoutΓ©
729 729 label_modified: modifiΓ©
730 730 label_copied: copiΓ©
731 731 label_renamed: renommΓ©
732 732 label_deleted: supprimΓ©
733 733 label_latest_revision: Dernière révision
734 734 label_latest_revision_plural: Dernières révisions
735 735 label_view_revisions: Voir les rΓ©visions
736 736 label_view_all_revisions: Voir toutes les rΓ©visions
737 737 label_max_size: Taille maximale
738 738 label_sort_highest: Remonter en premier
739 739 label_sort_higher: Remonter
740 740 label_sort_lower: Descendre
741 741 label_sort_lowest: Descendre en dernier
742 742 label_roadmap: Roadmap
743 743 label_roadmap_due_in: "Γ‰chΓ©ance dans %{value}"
744 744 label_roadmap_overdue: "En retard de %{value}"
745 745 label_roadmap_no_issues: Aucune demande pour cette version
746 746 label_search: Recherche
747 747 label_result_plural: RΓ©sultats
748 748 label_all_words: Tous les mots
749 749 label_wiki: Wiki
750 750 label_wiki_edit: RΓ©vision wiki
751 751 label_wiki_edit_plural: RΓ©visions wiki
752 752 label_wiki_page: Page wiki
753 753 label_wiki_page_plural: Pages wiki
754 754 label_index_by_title: Index par titre
755 755 label_index_by_date: Index par date
756 756 label_current_version: Version actuelle
757 757 label_preview: PrΓ©visualisation
758 758 label_feed_plural: Flux Atom
759 759 label_changes_details: DΓ©tails de tous les changements
760 760 label_issue_tracking: Suivi des demandes
761 761 label_spent_time: Temps passΓ©
762 762 label_overall_spent_time: Temps passΓ© global
763 763 label_f_hour: "%{value} heure"
764 764 label_f_hour_plural: "%{value} heures"
765 765 label_time_tracking: Suivi du temps
766 766 label_change_plural: Changements
767 767 label_statistics: Statistiques
768 768 label_commits_per_month: Commits par mois
769 769 label_commits_per_author: Commits par auteur
770 770 label_diff: diff
771 771 label_view_diff: Voir les diffΓ©rences
772 772 label_diff_inline: en ligne
773 773 label_diff_side_by_side: cΓ΄te Γ  cΓ΄te
774 774 label_options: Options
775 775 label_copy_workflow_from: Copier le workflow de
776 776 label_permissions_report: Synthèse des permissions
777 777 label_watched_issues: Demandes surveillΓ©es
778 778 label_related_issues: Demandes liΓ©es
779 779 label_applied_status: Statut appliquΓ©
780 780 label_loading: Chargement...
781 781 label_relation_new: Nouvelle relation
782 782 label_relation_delete: Supprimer la relation
783 783 label_relates_to: LiΓ© Γ 
784 784 label_duplicates: Duplique
785 785 label_duplicated_by: DupliquΓ© par
786 786 label_blocks: Bloque
787 787 label_blocked_by: BloquΓ© par
788 788 label_precedes: Précède
789 789 label_follows: Suit
790 790 label_copied_to: CopiΓ© vers
791 791 label_copied_from: CopiΓ© depuis
792 792 label_end_to_start: fin Γ  dΓ©but
793 793 label_end_to_end: fin Γ  fin
794 794 label_start_to_start: dΓ©but Γ  dΓ©but
795 795 label_start_to_end: dΓ©but Γ  fin
796 796 label_stay_logged_in: Rester connectΓ©
797 797 label_disabled: dΓ©sactivΓ©
798 798 label_show_completed_versions: Voir les versions passΓ©es
799 799 label_me: moi
800 800 label_board: Forum
801 801 label_board_new: Nouveau forum
802 802 label_board_plural: Forums
803 803 label_board_locked: VerrouillΓ©
804 804 label_board_sticky: Sticky
805 805 label_topic_plural: Discussions
806 806 label_message_plural: Messages
807 807 label_message_last: Dernier message
808 808 label_message_new: Nouveau message
809 809 label_message_posted: Message ajoutΓ©
810 810 label_reply_plural: RΓ©ponses
811 811 label_send_information: Envoyer les informations Γ  l'utilisateur
812 812 label_year: AnnΓ©e
813 813 label_month: Mois
814 814 label_week: Semaine
815 815 label_date_from: Du
816 816 label_date_to: Au
817 817 label_language_based: BasΓ© sur la langue de l'utilisateur
818 818 label_sort_by: "Trier par %{value}"
819 819 label_send_test_email: Envoyer un email de test
820 820 label_feeds_access_key: Clé d'accès Atom
821 821 label_missing_feeds_access_key: Clé d'accès Atom manquante
822 822 label_feeds_access_key_created_on: "Clé d'accès Atom créée il y a %{value}"
823 823 label_module_plural: Modules
824 824 label_added_time_by: "AjoutΓ© par %{author} il y a %{age}"
825 825 label_updated_time_by: "Mis Γ  jour par %{author} il y a %{age}"
826 826 label_updated_time: "Mis Γ  jour il y a %{value}"
827 827 label_jump_to_a_project: Aller Γ  un projet...
828 828 label_file_plural: Fichiers
829 829 label_changeset_plural: RΓ©visions
830 830 label_default_columns: Colonnes par dΓ©faut
831 831 label_no_change_option: (Pas de changement)
832 832 label_bulk_edit_selected_issues: Modifier les demandes sΓ©lectionnΓ©es
833 833 label_bulk_edit_selected_time_entries: Modifier les temps passΓ©s sΓ©lectionnΓ©s
834 834 label_theme: Thème
835 835 label_default: DΓ©faut
836 836 label_search_titles_only: Uniquement dans les titres
837 837 label_user_mail_option_all: "Pour tous les Γ©vΓ©nements de tous mes projets"
838 838 label_user_mail_option_selected: "Pour tous les Γ©vΓ©nements des projets sΓ©lectionnΓ©s..."
839 839 label_user_mail_option_none: Aucune notification
840 840 label_user_mail_option_only_my_events: Seulement pour ce que je surveille
841 841 label_user_mail_option_only_assigned: Seulement pour ce qui m'est assignΓ©
842 842 label_user_mail_option_only_owner: Seulement pour ce que j'ai créé
843 843 label_user_mail_no_self_notified: "Je ne veux pas Γͺtre notifiΓ© des changements que j'effectue"
844 844 label_registration_activation_by_email: activation du compte par email
845 845 label_registration_manual_activation: activation manuelle du compte
846 846 label_registration_automatic_activation: activation automatique du compte
847 847 label_display_per_page: "Par page : %{value}"
848 848 label_age: Γ‚ge
849 849 label_change_properties: Changer les propriΓ©tΓ©s
850 850 label_general: GΓ©nΓ©ral
851 851 label_more: Plus
852 852 label_scm: SCM
853 853 label_plugins: Plugins
854 854 label_ldap_authentication: Authentification LDAP
855 855 label_downloads_abbr: D/L
856 856 label_optional_description: Description facultative
857 857 label_add_another_file: Ajouter un autre fichier
858 858 label_preferences: PrΓ©fΓ©rences
859 859 label_chronological_order: Dans l'ordre chronologique
860 860 label_reverse_chronological_order: Dans l'ordre chronologique inverse
861 861 label_planning: Planning
862 862 label_incoming_emails: Emails entrants
863 863 label_generate_key: GΓ©nΓ©rer une clΓ©
864 864 label_issue_watchers: Observateurs
865 865 label_example: Exemple
866 866 label_display: Affichage
867 867 label_sort: Tri
868 868 label_ascending: Croissant
869 869 label_descending: DΓ©croissant
870 870 label_date_from_to: Du %{start} au %{end}
871 871 label_wiki_content_added: Page wiki ajoutΓ©e
872 872 label_wiki_content_updated: Page wiki mise Γ  jour
873 873 label_group: Groupe
874 874 label_group_plural: Groupes
875 875 label_group_new: Nouveau groupe
876 876 label_group_anonymous: Utilisateurs anonymes
877 877 label_group_non_member: Utilisateurs non membres
878 878 label_time_entry_plural: Temps passΓ©
879 879 label_version_sharing_none: Non partagΓ©
880 880 label_version_sharing_descendants: Avec les sous-projets
881 881 label_version_sharing_hierarchy: Avec toute la hiΓ©rarchie
882 882 label_version_sharing_tree: Avec tout l'arbre
883 883 label_version_sharing_system: Avec tous les projets
884 884 label_update_issue_done_ratios: Mettre Γ  jour l'avancement des demandes
885 885 label_copy_source: Source
886 886 label_copy_target: Cible
887 887 label_copy_same_as_target: Comme la cible
888 888 label_display_used_statuses_only: N'afficher que les statuts utilisΓ©s dans ce tracker
889 889 label_api_access_key: Clé d'accès API
890 890 label_missing_api_access_key: Clé d'accès API manquante
891 891 label_api_access_key_created_on: Clé d'accès API créée il y a %{value}
892 892 label_profile: Profil
893 893 label_subtask_plural: Sous-tΓ’ches
894 894 label_project_copy_notifications: Envoyer les notifications durant la copie du projet
895 895 label_principal_search: "Rechercher un utilisateur ou un groupe :"
896 896 label_user_search: "Rechercher un utilisateur :"
897 897 label_additional_workflow_transitions_for_author: Autorisations supplémentaires lorsque l'utilisateur a créé la demande
898 898 label_additional_workflow_transitions_for_assignee: Autorisations supplΓ©mentaires lorsque la demande est assignΓ©e Γ  l'utilisateur
899 899 label_issues_visibility_all: Toutes les demandes
900 900 label_issues_visibility_public: Toutes les demandes non privΓ©es
901 901 label_issues_visibility_own: Demandes créées par ou assignées à l'utilisateur
902 902 label_git_report_last_commit: Afficher le dernier commit des fichiers et rΓ©pertoires
903 903 label_parent_revision: Parent
904 904 label_child_revision: Enfant
905 905 label_export_options: Options d'exportation %{export_format}
906 906 label_copy_attachments: Copier les fichiers
907 907 label_copy_subtasks: Copier les sous-tΓ’ches
908 908 label_item_position: "%{position} sur %{count}"
909 909 label_completed_versions: Versions passΓ©es
910 910 label_search_for_watchers: Rechercher des observateurs
911 911 label_session_expiration: Expiration des sessions
912 912 label_show_closed_projects: Voir les projets fermΓ©s
913 913 label_status_transitions: Changements de statut
914 914 label_fields_permissions: Permissions sur les champs
915 915 label_readonly: Lecture
916 916 label_required: Obligatoire
917 917 label_hidden: CachΓ©
918 918 label_attribute_of_project: "%{name} du projet"
919 919 label_attribute_of_issue: "%{name} de la demande"
920 920 label_attribute_of_author: "%{name} de l'auteur"
921 921 label_attribute_of_assigned_to: "%{name} de l'assignΓ©"
922 922 label_attribute_of_user: "%{name} de l'utilisateur"
923 923 label_attribute_of_fixed_version: "%{name} de la version cible"
924 924 label_cross_project_descendants: Avec les sous-projets
925 925 label_cross_project_tree: Avec tout l'arbre
926 926 label_cross_project_hierarchy: Avec toute la hiΓ©rarchie
927 927 label_cross_project_system: Avec tous les projets
928 928 label_gantt_progress_line: Ligne de progression
929 929 label_visibility_private: par moi uniquement
930 930 label_visibility_roles: par ces rΓ΄les uniquement
931 931 label_visibility_public: par tout le monde
932 932 label_link: Lien
933 933 label_only: seulement
934 934 label_drop_down_list: liste dΓ©roulante
935 935 label_checkboxes: cases Γ  cocher
936 936 label_radio_buttons: boutons radio
937 937 label_link_values_to: Lier les valeurs vers l'URL
938 938 label_custom_field_select_type: Selectionner le type d'objet auquel attacher le champ personnalisΓ©
939 939 label_check_for_updates: VΓ©rifier les mises Γ  jour
940 940 label_latest_compatible_version: Dernière version compatible
941 941 label_unknown_plugin: Plugin inconnu
942 942 label_add_projects: Ajouter des projets
943 943
944 944 button_login: Connexion
945 945 button_submit: Soumettre
946 946 button_save: Sauvegarder
947 947 button_check_all: Tout cocher
948 948 button_uncheck_all: Tout dΓ©cocher
949 949 button_collapse_all: Plier tout
950 950 button_expand_all: DΓ©plier tout
951 951 button_delete: Supprimer
952 952 button_create: CrΓ©er
953 953 button_create_and_continue: CrΓ©er et continuer
954 954 button_test: Tester
955 955 button_edit: Modifier
956 956 button_edit_associated_wikipage: "Modifier la page wiki associΓ©e: %{page_title}"
957 957 button_add: Ajouter
958 958 button_change: Changer
959 959 button_apply: Appliquer
960 960 button_clear: Effacer
961 961 button_lock: Verrouiller
962 962 button_unlock: DΓ©verrouiller
963 963 button_download: TΓ©lΓ©charger
964 964 button_list: Lister
965 965 button_view: Voir
966 966 button_move: DΓ©placer
967 967 button_move_and_follow: DΓ©placer et suivre
968 968 button_back: Retour
969 969 button_cancel: Annuler
970 970 button_activate: Activer
971 971 button_sort: Trier
972 972 button_log_time: Saisir temps
973 973 button_rollback: Revenir Γ  cette version
974 974 button_watch: Surveiller
975 975 button_unwatch: Ne plus surveiller
976 976 button_reply: RΓ©pondre
977 977 button_archive: Archiver
978 978 button_unarchive: DΓ©sarchiver
979 979 button_reset: RΓ©initialiser
980 980 button_rename: Renommer
981 981 button_change_password: Changer de mot de passe
982 982 button_copy: Copier
983 983 button_copy_and_follow: Copier et suivre
984 984 button_annotate: Annoter
985 985 button_update: Mettre Γ  jour
986 986 button_configure: Configurer
987 987 button_quote: Citer
988 988 button_duplicate: Dupliquer
989 989 button_show: Afficher
990 990 button_hide: Cacher
991 991 button_edit_section: Modifier cette section
992 992 button_export: Exporter
993 993 button_delete_my_account: Supprimer mon compte
994 994 button_close: Fermer
995 995 button_reopen: RΓ©ouvrir
996 996
997 997 status_active: actif
998 998 status_registered: enregistrΓ©
999 999 status_locked: verrouillΓ©
1000 1000
1001 1001 project_status_active: actif
1002 1002 project_status_closed: fermΓ©
1003 1003 project_status_archived: archivΓ©
1004 1004
1005 1005 version_status_open: ouvert
1006 1006 version_status_locked: verrouillΓ©
1007 1007 version_status_closed: fermΓ©
1008 1008
1009 1009 field_active: Actif
1010 1010
1011 1011 text_select_mail_notifications: Actions pour lesquelles une notification par e-mail est envoyΓ©e
1012 1012 text_regexp_info: ex. ^[A-Z0-9]+$
1013 1013 text_min_max_length_info: 0 pour aucune restriction
1014 1014 text_project_destroy_confirmation: Êtes-vous sûr de vouloir supprimer ce projet et toutes ses données ?
1015 1015 text_subprojects_destroy_warning: "Ses sous-projets : %{value} seront Γ©galement supprimΓ©s."
1016 1016 text_workflow_edit: SΓ©lectionner un tracker et un rΓ΄le pour Γ©diter le workflow
1017 1017 text_are_you_sure: Êtes-vous sûr ?
1018 1018 text_journal_changed: "%{label} changΓ© de %{old} Γ  %{new}"
1019 1019 text_journal_changed_no_detail: "%{label} mis Γ  jour"
1020 1020 text_journal_set_to: "%{label} mis Γ  %{value}"
1021 1021 text_journal_deleted: "%{label} %{old} supprimΓ©"
1022 1022 text_journal_added: "%{label} %{value} ajoutΓ©"
1023 1023 text_tip_issue_begin_day: tΓ’che commenΓ§ant ce jour
1024 1024 text_tip_issue_end_day: tΓ’che finissant ce jour
1025 1025 text_tip_issue_begin_end_day: tΓ’che commenΓ§ant et finissant ce jour
1026 1026 text_project_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et tirets bas sont autorisΓ©s, doit commencer par une minuscule.<br />Un fois sauvegardΓ©, l''identifiant ne pourra plus Γͺtre modifiΓ©.'
1027 1027 text_caracters_maximum: "%{count} caractères maximum."
1028 1028 text_caracters_minimum: "%{count} caractères minimum."
1029 1029 text_length_between: "Longueur comprise entre %{min} et %{max} caractères."
1030 1030 text_tracker_no_workflow: Aucun worflow n'est dΓ©fini pour ce tracker
1031 1031 text_unallowed_characters: Caractères non autorisés
1032 1032 text_comma_separated: Plusieurs valeurs possibles (sΓ©parΓ©es par des virgules).
1033 1033 text_line_separated: Plusieurs valeurs possibles (une valeur par ligne).
1034 1034 text_issues_ref_in_commit_messages: RΓ©fΓ©rencement et rΓ©solution des demandes dans les commentaires de commits
1035 1035 text_issue_added: "La demande %{id} a Γ©tΓ© soumise par %{author}."
1036 1036 text_issue_updated: "La demande %{id} a Γ©tΓ© mise Γ  jour par %{author}."
1037 1037 text_wiki_destroy_confirmation: Etes-vous sΓ»r de vouloir supprimer ce wiki et tout son contenu ?
1038 1038 text_issue_category_destroy_question: "%{count} demandes sont affectΓ©es Γ  cette catΓ©gorie. Que voulez-vous faire ?"
1039 1039 text_issue_category_destroy_assignments: N'affecter les demandes Γ  aucune autre catΓ©gorie
1040 1040 text_issue_category_reassign_to: RΓ©affecter les demandes Γ  cette catΓ©gorie
1041 1041 text_user_mail_option: "Pour les projets non sΓ©lectionnΓ©s, vous recevrez seulement des notifications pour ce que vous surveillez ou Γ  quoi vous participez (exemple: demandes dont vous Γͺtes l'auteur ou la personne assignΓ©e)."
1042 1042 text_no_configuration_data: "Les rΓ΄les, trackers, statuts et le workflow ne sont pas encore paramΓ©trΓ©s.\nIl est vivement recommandΓ© de charger le paramΓ©trage par defaut. Vous pourrez le modifier une fois chargΓ©."
1043 1043 text_load_default_configuration: Charger le paramΓ©trage par dΓ©faut
1044 1044 text_status_changed_by_changeset: "AppliquΓ© par commit %{value}."
1045 1045 text_time_logged_by_changeset: "AppliquΓ© par commit %{value}"
1046 1046 text_issues_destroy_confirmation: 'Êtes-vous sûr de vouloir supprimer la ou les demandes(s) selectionnée(s) ?'
1047 1047 text_issues_destroy_descendants_confirmation: "Cela entrainera Γ©galement la suppression de %{count} sous-tΓ’che(s)."
1048 1048 text_time_entries_destroy_confirmation: "Etes-vous sΓ»r de vouloir supprimer les temps passΓ©s sΓ©lectionnΓ©s ?"
1049 1049 text_select_project_modules: 'SΓ©lectionner les modules Γ  activer pour ce projet :'
1050 1050 text_default_administrator_account_changed: Compte administrateur par dΓ©faut changΓ©
1051 1051 text_file_repository_writable: RΓ©pertoire de stockage des fichiers accessible en Γ©criture
1052 1052 text_plugin_assets_writable: RΓ©pertoire public des plugins accessible en Γ©criture
1053 1053 text_rmagick_available: Bibliothèque RMagick présente (optionnelle)
1054 1054 text_convert_available: Binaire convert de ImageMagick prΓ©sent (optionel)
1055 1055 text_destroy_time_entries_question: "%{hours} heures ont Γ©tΓ© enregistrΓ©es sur les demandes Γ  supprimer. Que voulez-vous faire ?"
1056 1056 text_destroy_time_entries: Supprimer les heures
1057 1057 text_assign_time_entries_to_project: Reporter les heures sur le projet
1058 1058 text_reassign_time_entries: 'Reporter les heures sur cette demande:'
1059 1059 text_user_wrote: "%{value} a Γ©crit :"
1060 1060 text_enumeration_destroy_question: "Cette valeur est affectΓ©e Γ  %{count} objets."
1061 1061 text_enumeration_category_reassign_to: 'RΓ©affecter les objets Γ  cette valeur:'
1062 1062 text_email_delivery_not_configured: "L'envoi de mail n'est pas configurΓ©, les notifications sont dΓ©sactivΓ©es.\nConfigurez votre serveur SMTP dans config/configuration.yml et redΓ©marrez l'application pour les activer."
1063 1063 text_repository_usernames_mapping: "Vous pouvez sΓ©lectionner ou modifier l'utilisateur Redmine associΓ© Γ  chaque nom d'utilisateur figurant dans l'historique du dΓ©pΓ΄t.\nLes utilisateurs avec le mΓͺme identifiant ou la mΓͺme adresse mail seront automatiquement associΓ©s."
1064 1064 text_diff_truncated: '... Ce diffΓ©rentiel a Γ©tΓ© tronquΓ© car il excΓ¨de la taille maximale pouvant Γͺtre affichΓ©e.'
1065 1065 text_custom_field_possible_values_info: 'Une ligne par valeur'
1066 1066 text_wiki_page_destroy_question: "Cette page possède %{descendants} sous-page(s) et descendante(s). Que voulez-vous faire ?"
1067 1067 text_wiki_page_nullify_children: "Conserver les sous-pages en tant que pages racines"
1068 1068 text_wiki_page_destroy_children: "Supprimer les sous-pages et toutes leurs descedantes"
1069 1069 text_wiki_page_reassign_children: "RΓ©affecter les sous-pages Γ  cette page"
1070 1070 text_own_membership_delete_confirmation: "Vous allez supprimer tout ou partie de vos permissions sur ce projet et ne serez peut-Γͺtre plus autorisΓ© Γ  modifier ce projet.\nEtes-vous sΓ»r de vouloir continuer ?"
1071 1071 text_zoom_in: Zoom avant
1072 1072 text_zoom_out: Zoom arrière
1073 1073 text_warn_on_leaving_unsaved: "Cette page contient du texte non sauvegardΓ© qui sera perdu si vous quittez la page."
1074 1074 text_scm_path_encoding_note: "DΓ©faut : UTF-8"
1075 text_git_repository_note: "Le dΓ©pΓ΄t est vide et local (exemples : /gitrepo, c:\\gitrepo)"
1076 text_mercurial_repository_note: "DΓ©pΓ΄t local (exemples : /hgrepo, c:\\hgrepo)"
1075 text_subversion_repository_note: "Exemples (en fonction des protocoles supportΓ©s) : file:///, http://, https://, svn://, svn+[tunnelscheme]://"
1076 text_git_repository_note: "Chemin vers un dΓ©pΓ΄t vide et local (exemples : /gitrepo, c:\\gitrepo)"
1077 text_mercurial_repository_note: "Chemin vers un dΓ©pΓ΄t local (exemples : /hgrepo, c:\\hgrepo)"
1077 1078 text_scm_command: Commande
1078 1079 text_scm_command_version: Version
1079 1080 text_scm_config: Vous pouvez configurer les commandes des SCM dans config/configuration.yml. Redémarrer l'application après modification.
1080 1081 text_scm_command_not_available: Ce SCM n'est pas disponible. Vérifier les paramètres dans la section administration.
1081 1082 text_issue_conflict_resolution_overwrite: "Appliquer quand mΓͺme ma mise Γ  jour (les notes prΓ©cΓ©dentes seront conservΓ©es mais des changements pourront Γͺtre Γ©crasΓ©s)"
1082 1083 text_issue_conflict_resolution_add_notes: "Ajouter mes notes et ignorer mes autres changements"
1083 1084 text_issue_conflict_resolution_cancel: "Annuler ma mise Γ  jour et rΓ©afficher %{link}"
1084 1085 text_account_destroy_confirmation: "Êtes-vous sûr de vouloir continuer ?\nVotre compte sera définitivement supprimé, sans aucune possibilité de le réactiver."
1085 1086 text_session_expiration_settings: "Attention : le changement de ces paramètres peut entrainer l'expiration des sessions utilisateurs en cours, y compris la vôtre."
1086 1087 text_project_closed: Ce projet est fermΓ© et accessible en lecture seule.
1087 1088 text_turning_multiple_off: "Si vous dΓ©sactivez les valeurs multiples, les valeurs multiples seront supprimΓ©es pour n'en conserver qu'une par objet."
1088 1089
1089 1090 default_role_manager: Manager
1090 1091 default_role_developer: DΓ©veloppeur
1091 1092 default_role_reporter: Rapporteur
1092 1093 default_tracker_bug: Anomalie
1093 1094 default_tracker_feature: Evolution
1094 1095 default_tracker_support: Assistance
1095 1096 default_issue_status_new: Nouveau
1096 1097 default_issue_status_in_progress: En cours
1097 1098 default_issue_status_resolved: RΓ©solu
1098 1099 default_issue_status_feedback: Commentaire
1099 1100 default_issue_status_closed: FermΓ©
1100 1101 default_issue_status_rejected: RejetΓ©
1101 1102 default_doc_category_user: Documentation utilisateur
1102 1103 default_doc_category_tech: Documentation technique
1103 1104 default_priority_low: Bas
1104 1105 default_priority_normal: Normal
1105 1106 default_priority_high: Haut
1106 1107 default_priority_urgent: Urgent
1107 1108 default_priority_immediate: ImmΓ©diat
1108 1109 default_activity_design: Conception
1109 1110 default_activity_development: DΓ©veloppement
1110 1111
1111 1112 enumeration_issue_priorities: PrioritΓ©s des demandes
1112 1113 enumeration_doc_categories: CatΓ©gories des documents
1113 1114 enumeration_activities: ActivitΓ©s (suivi du temps)
1114 1115 enumeration_system_activity: Activité système
1115 1116 description_filter: Filtre
1116 1117 description_search: Champ de recherche
1117 1118 description_choose_project: Projets
1118 1119 description_project_scope: Périmètre de recherche
1119 1120 description_notes: Notes
1120 1121 description_message_content: Contenu du message
1121 1122 description_query_sort_criteria_attribute: Critère de tri
1122 1123 description_query_sort_criteria_direction: Ordre de tri
1123 1124 description_user_mail_notification: Option de notification
1124 1125 description_available_columns: Colonnes disponibles
1125 1126 description_selected_columns: Colonnes sΓ©lectionnΓ©es
1126 1127 description_all_columns: Toutes les colonnes
1127 1128 description_issue_category_reassign: Choisir une catΓ©gorie
1128 1129 description_wiki_subpages_reassign: Choisir une nouvelle page parent
1129 1130 description_date_range_list: Choisir une pΓ©riode prΓ©dΓ©finie
1130 1131 description_date_range_interval: Choisir une pΓ©riode
1131 1132 description_date_from: Date de dΓ©but
1132 1133 description_date_to: Date de fin
1133 1134 text_repository_identifier_info: 'Seuls les lettres minuscules (a-z), chiffres, tirets et tirets bas sont autorisΓ©s.<br />Un fois sauvegardΓ©, l''identifiant ne pourra plus Γͺtre modifiΓ©.'
@@ -1,117 +1,132
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 module Redmine
19 19 module Configuration
20 20
21 21 # Configuration default values
22 22 @defaults = {
23 23 'email_delivery' => nil,
24 24 'max_concurrent_ajax_uploads' => 2
25 25 }
26 26
27 27 @config = nil
28 28
29 29 class << self
30 30 # Loads the Redmine configuration file
31 31 # Valid options:
32 32 # * <tt>:file</tt>: the configuration file to load (default: config/configuration.yml)
33 33 # * <tt>:env</tt>: the environment to load the configuration for (default: Rails.env)
34 34 def load(options={})
35 35 filename = options[:file] || File.join(Rails.root, 'config', 'configuration.yml')
36 36 env = options[:env] || Rails.env
37 37
38 38 @config = @defaults.dup
39 39
40 40 load_deprecated_email_configuration(env)
41 41 if File.file?(filename)
42 42 @config.merge!(load_from_yaml(filename, env))
43 43 end
44 44
45 45 # Compatibility mode for those who copy email.yml over configuration.yml
46 46 %w(delivery_method smtp_settings sendmail_settings).each do |key|
47 47 if value = @config.delete(key)
48 48 @config['email_delivery'] ||= {}
49 49 @config['email_delivery'][key] = value
50 50 end
51 51 end
52 52
53 53 if @config['email_delivery']
54 54 ActionMailer::Base.perform_deliveries = true
55 55 @config['email_delivery'].each do |k, v|
56 56 v.symbolize_keys! if v.respond_to?(:symbolize_keys!)
57 57 ActionMailer::Base.send("#{k}=", v)
58 58 end
59 59 end
60 60
61 check_regular_expressions
61 62 @config
62 63 end
63 64
64 65 # Returns a configuration setting
65 66 def [](name)
66 67 load unless @config
67 68 @config[name]
68 69 end
69 70
70 71 # Yields a block with the specified hash configuration settings
71 72 def with(settings)
72 73 settings.stringify_keys!
73 74 load unless @config
74 75 was = settings.keys.inject({}) {|h,v| h[v] = @config[v]; h}
75 76 @config.merge! settings
76 77 yield if block_given?
77 78 @config.merge! was
78 79 end
79 80
80 81 private
81 82
82 83 def load_from_yaml(filename, env)
83 84 yaml = nil
84 85 begin
85 86 yaml = YAML::load(ERB.new(File.read(filename)).result)
86 87 rescue ArgumentError
87 88 $stderr.puts "Your Redmine configuration file located at #{filename} is not a valid YAML file and could not be loaded."
88 89 exit 1
89 90 rescue SyntaxError => e
90 91 $stderr.puts "A syntax error occurred when parsing your Redmine configuration file located at #{filename} with ERB:\n#{e.message}"
91 92 exit 1
92 93 end
93 94 conf = {}
94 95 if yaml.is_a?(Hash)
95 96 if yaml['default']
96 97 conf.merge!(yaml['default'])
97 98 end
98 99 if yaml[env]
99 100 conf.merge!(yaml[env])
100 101 end
101 102 else
102 103 $stderr.puts "Your Redmine configuration file located at #{filename} is not a valid Redmine configuration file."
103 104 exit 1
104 105 end
105 106 conf
106 107 end
107 108
108 109 def load_deprecated_email_configuration(env)
109 110 deprecated_email_conf = File.join(Rails.root, 'config', 'email.yml')
110 111 if File.file?(deprecated_email_conf)
111 112 warn "Storing outgoing emails configuration in config/email.yml is deprecated. You should now store it in config/configuration.yml using the email_delivery setting."
112 113 @config.merge!({'email_delivery' => load_from_yaml(deprecated_email_conf, env)})
113 114 end
114 115 end
116
117 # Checks the validness of regular expressions set for repository paths at startup
118 def check_regular_expressions
119 @config.each do |name, value|
120 if value.present? && name =~ /^scm_.+_path_regexp$/
121 begin
122 Regexp.new value.to_s.strip
123 rescue => e
124 $stderr.puts "Invalid regular expression set as #{name} setting in your Redmine configuration file:\n#{e.message}"
125 exit 1
126 end
127 end
128 end
129 end
115 130 end
116 131 end
117 132 end
@@ -1,241 +1,259
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19 require 'pp'
20 20 class RepositoryCvsTest < ActiveSupport::TestCase
21 21 fixtures :projects
22 22
23 23 include Redmine::I18n
24 24
25 25 REPOSITORY_PATH = repository_path('cvs')
26 26 REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
27 27 # CVS module
28 28 MODULE_NAME = 'test'
29 29 CHANGESETS_NUM = 7
30 30
31 31 def setup
32 32 @project = Project.find(3)
33 33 @repository = Repository::Cvs.create(:project => @project,
34 34 :root_url => REPOSITORY_PATH,
35 35 :url => MODULE_NAME,
36 36 :log_encoding => 'UTF-8')
37 37 assert @repository
38 38 end
39 39
40 40 def test_blank_module_error_message
41 41 set_language_if_valid 'en'
42 42 repo = Repository::Cvs.new(
43 43 :project => @project,
44 44 :identifier => 'test',
45 45 :log_encoding => 'UTF-8',
46 46 :root_url => REPOSITORY_PATH
47 47 )
48 48 assert !repo.save
49 49 assert_include "Module can't be blank",
50 50 repo.errors.full_messages
51 51 end
52 52
53 53 def test_blank_module_error_message_fr
54 54 set_language_if_valid 'fr'
55 55 str = "Module doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8')
56 56 repo = Repository::Cvs.new(
57 57 :project => @project,
58 58 :identifier => 'test',
59 59 :log_encoding => 'UTF-8',
60 60 :path_encoding => '',
61 61 :url => '',
62 62 :root_url => REPOSITORY_PATH
63 63 )
64 64 assert !repo.save
65 65 assert_include str, repo.errors.full_messages
66 66 end
67 67
68 68 def test_blank_cvsroot_error_message
69 69 set_language_if_valid 'en'
70 70 repo = Repository::Cvs.new(
71 71 :project => @project,
72 72 :identifier => 'test',
73 73 :log_encoding => 'UTF-8',
74 74 :url => MODULE_NAME
75 75 )
76 76 assert !repo.save
77 77 assert_include "CVSROOT can't be blank",
78 78 repo.errors.full_messages
79 79 end
80 80
81 81 def test_blank_cvsroot_error_message_fr
82 82 set_language_if_valid 'fr'
83 83 str = "CVSROOT doit \xc3\xaatre renseign\xc3\xa9(e)".force_encoding('UTF-8')
84 84 repo = Repository::Cvs.new(
85 85 :project => @project,
86 86 :identifier => 'test',
87 87 :log_encoding => 'UTF-8',
88 88 :path_encoding => '',
89 89 :url => MODULE_NAME,
90 90 :root_url => ''
91 91 )
92 92 assert !repo.save
93 93 assert_include str, repo.errors.full_messages
94 94 end
95 95
96 def test_root_url_should_be_validated_against_regexp_set_in_configuration
97 Redmine::Configuration.with 'scm_cvs_path_regexp' => '/cvspath/[a-z]+' do
98 repo = Repository::Cvs.new(
99 :project => @project,
100 :identifier => 'test',
101 :log_encoding => 'UTF-8',
102 :path_encoding => '',
103 :url => MODULE_NAME
104 )
105 repo.root_url = '/wrong_path'
106 assert !repo.valid?
107 assert repo.errors[:root_url].present?
108
109 repo.root_url = '/cvspath/foo'
110 assert repo.valid?
111 end
112 end
113
96 114 if File.directory?(REPOSITORY_PATH)
97 115 def test_fetch_changesets_from_scratch
98 116 assert_equal 0, @repository.changesets.count
99 117 @repository.fetch_changesets
100 118 @project.reload
101 119
102 120 assert_equal CHANGESETS_NUM, @repository.changesets.count
103 121 assert_equal 16, @repository.filechanges.count
104 122 assert_not_nil @repository.changesets.find_by_comments('Two files changed')
105 123
106 124 r2 = @repository.changesets.find_by_revision('2')
107 125 assert_equal 'v1-20071213-162510', r2.scmid
108 126 end
109 127
110 128 def test_fetch_changesets_incremental
111 129 assert_equal 0, @repository.changesets.count
112 130 @repository.fetch_changesets
113 131 @project.reload
114 132 assert_equal CHANGESETS_NUM, @repository.changesets.count
115 133
116 134 # Remove changesets with revision > 3
117 135 @repository.changesets.each {|c| c.destroy if c.revision.to_i > 3}
118 136 @project.reload
119 137 @repository.reload
120 138 assert_equal 3, @repository.changesets.count
121 139 assert_equal %w|3 2 1|, @repository.changesets.collect(&:revision)
122 140
123 141 rev3_commit = @repository.changesets.reorder('committed_on DESC').first
124 142 assert_equal '3', rev3_commit.revision
125 143 # 2007-12-14 01:27:22 +0900
126 144 rev3_committed_on = Time.gm(2007, 12, 13, 16, 27, 22)
127 145 assert_equal 'HEAD-20071213-162722', rev3_commit.scmid
128 146 assert_equal rev3_committed_on, rev3_commit.committed_on
129 147 latest_rev = @repository.latest_changeset
130 148 assert_equal rev3_committed_on, latest_rev.committed_on
131 149
132 150 @repository.fetch_changesets
133 151 @project.reload
134 152 @repository.reload
135 153 assert_equal CHANGESETS_NUM, @repository.changesets.count
136 154 assert_equal %w|7 6 5 4 3 2 1|, @repository.changesets.collect(&:revision)
137 155 rev5_commit = @repository.changesets.find_by_revision('5')
138 156 assert_equal 'HEAD-20071213-163001', rev5_commit.scmid
139 157 # 2007-12-14 01:30:01 +0900
140 158 rev5_committed_on = Time.gm(2007, 12, 13, 16, 30, 1)
141 159 assert_equal rev5_committed_on, rev5_commit.committed_on
142 160 end
143 161
144 162 def test_deleted_files_should_not_be_listed
145 163 assert_equal 0, @repository.changesets.count
146 164 @repository.fetch_changesets
147 165 @project.reload
148 166 assert_equal CHANGESETS_NUM, @repository.changesets.count
149 167
150 168 entries = @repository.entries('sources')
151 169 assert entries.detect {|e| e.name == 'watchers_controller.rb'}
152 170 assert_nil entries.detect {|e| e.name == 'welcome_controller.rb'}
153 171 end
154 172
155 173 def test_entries_rev3
156 174 assert_equal 0, @repository.changesets.count
157 175 @repository.fetch_changesets
158 176 @project.reload
159 177 assert_equal CHANGESETS_NUM, @repository.changesets.count
160 178 entries = @repository.entries('', '3')
161 179 assert_kind_of Redmine::Scm::Adapters::Entries, entries
162 180 assert_equal 3, entries.size
163 181 assert_equal entries[2].name, "README"
164 182 assert_equal entries[2].lastrev.time, Time.gm(2007, 12, 13, 16, 27, 22)
165 183 assert_equal entries[2].lastrev.identifier, '3'
166 184 assert_equal entries[2].lastrev.revision, '3'
167 185 assert_equal entries[2].lastrev.author, 'LANG'
168 186 end
169 187
170 188 def test_entries_invalid_path
171 189 assert_equal 0, @repository.changesets.count
172 190 @repository.fetch_changesets
173 191 @project.reload
174 192 assert_equal CHANGESETS_NUM, @repository.changesets.count
175 193 assert_nil @repository.entries('missing')
176 194 assert_nil @repository.entries('missing', '3')
177 195 end
178 196
179 197 def test_entries_invalid_revision
180 198 assert_equal 0, @repository.changesets.count
181 199 @repository.fetch_changesets
182 200 @project.reload
183 201 assert_equal CHANGESETS_NUM, @repository.changesets.count
184 202 assert_nil @repository.entries('', '123')
185 203 end
186 204
187 205 def test_cat
188 206 assert_equal 0, @repository.changesets.count
189 207 @repository.fetch_changesets
190 208 @project.reload
191 209 assert_equal CHANGESETS_NUM, @repository.changesets.count
192 210 buf = @repository.cat('README')
193 211 assert buf
194 212 lines = buf.split("\n")
195 213 assert_equal 3, lines.length
196 214 buf = lines[1].gsub(/\r$/, "")
197 215 assert_equal 'with one change', buf
198 216 buf = @repository.cat('README', '1')
199 217 assert buf
200 218 lines = buf.split("\n")
201 219 assert_equal 1, lines.length
202 220 buf = lines[0].gsub(/\r$/, "")
203 221 assert_equal 'CVS test repository', buf
204 222 assert_nil @repository.cat('missing.rb')
205 223
206 224 # sources/welcome_controller.rb is removed at revision 5.
207 225 assert @repository.cat('sources/welcome_controller.rb', '4')
208 226 assert @repository.cat('sources/welcome_controller.rb', '5').blank?
209 227
210 228 # invalid revision
211 229 assert @repository.cat('README', '123').blank?
212 230 end
213 231
214 232 def test_annotate
215 233 assert_equal 0, @repository.changesets.count
216 234 @repository.fetch_changesets
217 235 @project.reload
218 236 assert_equal CHANGESETS_NUM, @repository.changesets.count
219 237 ann = @repository.annotate('README')
220 238 assert ann
221 239 assert_equal 3, ann.revisions.length
222 240 assert_equal '1.2', ann.revisions[1].revision
223 241 assert_equal 'LANG', ann.revisions[1].author
224 242 assert_equal 'with one change', ann.lines[1]
225 243
226 244 ann = @repository.annotate('README', '1')
227 245 assert ann
228 246 assert_equal 1, ann.revisions.length
229 247 assert_equal '1.1', ann.revisions[0].revision
230 248 assert_equal 'LANG', ann.revisions[0].author
231 249 assert_equal 'CVS test repository', ann.lines[0]
232 250
233 251 # invalid revision
234 252 assert_nil @repository.annotate('README', '123')
235 253 end
236 254
237 255 else
238 256 puts "CVS test repository NOT FOUND. Skipping unit tests !!!"
239 257 def test_fake; assert true end
240 258 end
241 259 end
@@ -1,254 +1,285
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../test_helper', __FILE__)
19 19
20 20 class RepositorySubversionTest < ActiveSupport::TestCase
21 21 fixtures :projects, :repositories, :enabled_modules, :users, :roles
22 22
23 23 include Redmine::I18n
24 24
25 25 NUM_REV = 11
26 26
27 27 def setup
28 28 @project = Project.find(3)
29 29 @repository = Repository::Subversion.create(:project => @project,
30 30 :url => self.class.subversion_repository_url)
31 31 assert @repository
32 32 end
33 33
34 34 def test_invalid_url
35 35 set_language_if_valid 'en'
36 36 ['invalid', 'http://', 'svn://', 'svn+ssh://', 'file://'].each do |url|
37 37 repo = Repository::Subversion.new(
38 38 :project => @project,
39 39 :identifier => 'test',
40 40 :url => url
41 41 )
42 42 assert !repo.save
43 43 assert_equal ["is invalid"], repo.errors[:url]
44 44 end
45 45 end
46 46
47 47 def test_valid_url
48 48 ['http://valid', 'svn://valid', 'svn+ssh://valid', 'file://valid'].each do |url|
49 49 repo = Repository::Subversion.new(
50 50 :project => @project,
51 51 :identifier => 'test',
52 52 :url => url
53 53 )
54 54 assert repo.save
55 55 assert_equal [], repo.errors[:url]
56 56 assert repo.destroy
57 57 end
58 58 end
59 59
60 def test_url_should_be_validated_against_regexp_set_in_configuration
61 Redmine::Configuration.with 'scm_subversion_path_regexp' => 'file:///svnpath/[a-z]+' do
62 repo = Repository::Subversion.new(:project => @project, :identifier => 'test')
63 repo.url = 'http://foo'
64 assert !repo.valid?
65 assert repo.errors[:url].present?
66
67 repo.url = 'file:///svnpath/foo/bar'
68 assert !repo.valid?
69 assert repo.errors[:url].present?
70
71 repo.url = 'file:///svnpath/foo'
72 assert repo.valid?
73 end
74 end
75
76 def test_url_should_be_validated_against_regexp_set_in_configuration_with_project_identifier
77 Redmine::Configuration.with 'scm_subversion_path_regexp' => 'file:///svnpath/%project%(\.[a-z]+)?' do
78 repo = Repository::Subversion.new(:project => @project, :identifier => 'test')
79 repo.url = 'file:///svnpath/invalid'
80 assert !repo.valid?
81 assert repo.errors[:url].present?
82
83 repo.url = 'file:///svnpath/subproject1'
84 assert repo.valid?
85
86 repo.url = 'file:///svnpath/subproject1.foo'
87 assert repo.valid?
88 end
89 end
90
60 91 if repository_configured?('subversion')
61 92 def test_fetch_changesets_from_scratch
62 93 assert_equal 0, @repository.changesets.count
63 94 @repository.fetch_changesets
64 95 @project.reload
65 96
66 97 assert_equal NUM_REV, @repository.changesets.count
67 98 assert_equal 20, @repository.filechanges.count
68 99 assert_equal 'Initial import.', @repository.changesets.find_by_revision('1').comments
69 100 end
70 101
71 102 def test_fetch_changesets_incremental
72 103 assert_equal 0, @repository.changesets.count
73 104 @repository.fetch_changesets
74 105 @project.reload
75 106 assert_equal NUM_REV, @repository.changesets.count
76 107
77 108 # Remove changesets with revision > 5
78 109 @repository.changesets.each {|c| c.destroy if c.revision.to_i > 5}
79 110 @project.reload
80 111 @repository.reload
81 112 assert_equal 5, @repository.changesets.count
82 113
83 114 @repository.fetch_changesets
84 115 @project.reload
85 116 assert_equal NUM_REV, @repository.changesets.count
86 117 end
87 118
88 119 def test_entries
89 120 entries = @repository.entries
90 121 assert_kind_of Redmine::Scm::Adapters::Entries, entries
91 122 end
92 123
93 124 def test_entries_for_invalid_path_should_return_nil
94 125 entries = @repository.entries('invalid_path')
95 126 assert_nil entries
96 127 end
97 128
98 129 def test_latest_changesets
99 130 assert_equal 0, @repository.changesets.count
100 131 @repository.fetch_changesets
101 132 @project.reload
102 133 assert_equal NUM_REV, @repository.changesets.count
103 134
104 135 # with limit
105 136 changesets = @repository.latest_changesets('', nil, 2)
106 137 assert_equal 2, changesets.size
107 138 assert_equal @repository.latest_changesets('', nil).slice(0,2), changesets
108 139
109 140 # with path
110 141 changesets = @repository.latest_changesets('subversion_test/folder', nil)
111 142 assert_equal ["10", "9", "7", "6", "5", "2"], changesets.collect(&:revision)
112 143
113 144 # with path and revision
114 145 changesets = @repository.latest_changesets('subversion_test/folder', 8)
115 146 assert_equal ["7", "6", "5", "2"], changesets.collect(&:revision)
116 147 end
117 148
118 149 def test_directory_listing_with_square_brackets_in_path
119 150 assert_equal 0, @repository.changesets.count
120 151 @repository.fetch_changesets
121 152 @project.reload
122 153 assert_equal NUM_REV, @repository.changesets.count
123 154
124 155 entries = @repository.entries('subversion_test/[folder_with_brackets]')
125 156 assert_not_nil entries, 'Expect to find entries in folder_with_brackets'
126 157 assert_equal 1, entries.size, 'Expect one entry in folder_with_brackets'
127 158 assert_equal 'README.txt', entries.first.name
128 159 end
129 160
130 161 def test_directory_listing_with_square_brackets_in_base
131 162 @project = Project.find(3)
132 163 @repository = Repository::Subversion.create(
133 164 :project => @project,
134 165 :url => "file:///#{self.class.repository_path('subversion')}/subversion_test/[folder_with_brackets]")
135 166
136 167 assert_equal 0, @repository.changesets.count
137 168 @repository.fetch_changesets
138 169 @project.reload
139 170
140 171 assert_equal 1, @repository.changesets.count, 'Expected to see 1 revision'
141 172 assert_equal 2, @repository.filechanges.count, 'Expected to see 2 changes, dir add and file add'
142 173
143 174 entries = @repository.entries('')
144 175 assert_not_nil entries, 'Expect to find entries'
145 176 assert_equal 1, entries.size, 'Expect a single entry'
146 177 assert_equal 'README.txt', entries.first.name
147 178 end
148 179
149 180 def test_identifier
150 181 assert_equal 0, @repository.changesets.count
151 182 @repository.fetch_changesets
152 183 @project.reload
153 184 assert_equal NUM_REV, @repository.changesets.count
154 185 c = @repository.changesets.find_by_revision('1')
155 186 assert_equal c.revision, c.identifier
156 187 end
157 188
158 189 def test_find_changeset_by_empty_name
159 190 assert_equal 0, @repository.changesets.count
160 191 @repository.fetch_changesets
161 192 @project.reload
162 193 assert_equal NUM_REV, @repository.changesets.count
163 194 ['', ' ', nil].each do |r|
164 195 assert_nil @repository.find_changeset_by_name(r)
165 196 end
166 197 end
167 198
168 199 def test_identifier_nine_digit
169 200 c = Changeset.new(:repository => @repository, :committed_on => Time.now,
170 201 :revision => '123456789', :comments => 'test')
171 202 assert_equal c.identifier, c.revision
172 203 end
173 204
174 205 def test_format_identifier
175 206 assert_equal 0, @repository.changesets.count
176 207 @repository.fetch_changesets
177 208 @project.reload
178 209 assert_equal NUM_REV, @repository.changesets.count
179 210 c = @repository.changesets.find_by_revision('1')
180 211 assert_equal c.format_identifier, c.revision
181 212 end
182 213
183 214 def test_format_identifier_nine_digit
184 215 c = Changeset.new(:repository => @repository, :committed_on => Time.now,
185 216 :revision => '123456789', :comments => 'test')
186 217 assert_equal c.format_identifier, c.revision
187 218 end
188 219
189 220 def test_activities
190 221 c = Changeset.new(:repository => @repository, :committed_on => Time.now,
191 222 :revision => '1', :comments => 'test')
192 223 assert c.event_title.include?('1:')
193 224 assert_equal '1', c.event_url[:rev]
194 225 end
195 226
196 227 def test_activities_nine_digit
197 228 c = Changeset.new(:repository => @repository, :committed_on => Time.now,
198 229 :revision => '123456789', :comments => 'test')
199 230 assert c.event_title.include?('123456789:')
200 231 assert_equal '123456789', c.event_url[:rev]
201 232 end
202 233
203 234 def test_log_encoding_ignore_setting
204 235 with_settings :commit_logs_encoding => 'windows-1252' do
205 236 s2 = "\xc3\x82\xc2\x80".force_encoding('UTF-8')
206 237 c = Changeset.new(:repository => @repository,
207 238 :comments => s2,
208 239 :revision => '123',
209 240 :committed_on => Time.now)
210 241 assert c.save
211 242 assert_equal s2, c.comments
212 243 end
213 244 end
214 245
215 246 def test_previous
216 247 assert_equal 0, @repository.changesets.count
217 248 @repository.fetch_changesets
218 249 @project.reload
219 250 assert_equal NUM_REV, @repository.changesets.count
220 251 changeset = @repository.find_changeset_by_name('3')
221 252 assert_equal @repository.find_changeset_by_name('2'), changeset.previous
222 253 end
223 254
224 255 def test_previous_nil
225 256 assert_equal 0, @repository.changesets.count
226 257 @repository.fetch_changesets
227 258 @project.reload
228 259 assert_equal NUM_REV, @repository.changesets.count
229 260 changeset = @repository.find_changeset_by_name('1')
230 261 assert_nil changeset.previous
231 262 end
232 263
233 264 def test_next
234 265 assert_equal 0, @repository.changesets.count
235 266 @repository.fetch_changesets
236 267 @project.reload
237 268 assert_equal NUM_REV, @repository.changesets.count
238 269 changeset = @repository.find_changeset_by_name('2')
239 270 assert_equal @repository.find_changeset_by_name('3'), changeset.next
240 271 end
241 272
242 273 def test_next_nil
243 274 assert_equal 0, @repository.changesets.count
244 275 @repository.fetch_changesets
245 276 @project.reload
246 277 assert_equal NUM_REV, @repository.changesets.count
247 278 changeset = @repository.find_changeset_by_name('11')
248 279 assert_nil changeset.next
249 280 end
250 281 else
251 282 puts "Subversion test repository NOT FOUND. Skipping unit tests !!!"
252 283 def test_fake; assert true end
253 284 end
254 285 end
General Comments 0
You need to be logged in to leave comments. Login now