Revision 1298:4f746d8966dd .svn/pristine/32

View differences:

.svn/pristine/32/326a62adc02ab48e12d9e9d717fea2e84b8c44cf.svn-base
1
# Redmine - project management software
2
# Copyright (C) 2006-2013  Jean-Philippe Lang
3
#
4
# This program is free software; you can redistribute it and/or
5
# modify it under the terms of the GNU General Public License
6
# as published by the Free Software Foundation; either version 2
7
# of the License, or (at your option) any later version.
8
#
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
# GNU General Public License for more details.
13
#
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17

  
18
require File.expand_path('../../test_helper', __FILE__)
19

  
20
class RepositoryGitTest < ActiveSupport::TestCase
21
  fixtures :projects, :repositories, :enabled_modules, :users, :roles
22

  
23
  include Redmine::I18n
24

  
25
  REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
26
  REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
27

  
28
  NUM_REV = 28
29
  NUM_HEAD = 6
30

  
31
  FELIX_HEX  = "Felix Sch\xC3\xA4fer"
32
  CHAR_1_HEX = "\xc3\x9c"
33

  
34
  ## Git, Mercurial and CVS path encodings are binary.
35
  ## Subversion supports URL encoding for path.
36
  ## Redmine Mercurial adapter and extension use URL encoding.
37
  ## Git accepts only binary path in command line parameter.
38
  ## So, there is no way to use binary command line parameter in JRuby.
39
  JRUBY_SKIP     = (RUBY_PLATFORM == 'java')
40
  JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
41

  
42
  def setup
43
    @project = Project.find(3)
44
    @repository = Repository::Git.create(
45
                        :project       => @project,
46
                        :url           => REPOSITORY_PATH,
47
                        :path_encoding => 'ISO-8859-1'
48
                        )
49
    assert @repository
50
    @char_1        = CHAR_1_HEX.dup
51
    if @char_1.respond_to?(:force_encoding)
52
      @char_1.force_encoding('UTF-8')
53
    end
54
  end
55

  
56
  def test_blank_path_to_repository_error_message
57
    set_language_if_valid 'en'
58
    repo = Repository::Git.new(
59
                          :project      => @project,
60
                          :identifier   => 'test'
61
                        )
62
    assert !repo.save
63
    assert_include "Path to repository can't be blank",
64
                   repo.errors.full_messages
65
  end
66

  
67
  def test_blank_path_to_repository_error_message_fr
68
    set_language_if_valid 'fr'
69
    str = "Chemin du d\xc3\xa9p\xc3\xb4t doit \xc3\xaatre renseign\xc3\xa9(e)"
70
    str.force_encoding('UTF-8') if str.respond_to?(:force_encoding)
71
    repo = Repository::Git.new(
72
                          :project      => @project,
73
                          :url          => "",
74
                          :identifier   => 'test',
75
                          :path_encoding => ''
76
                        )
77
    assert !repo.save
78
    assert_include str, repo.errors.full_messages
79
  end
80

  
81
  if File.directory?(REPOSITORY_PATH)
82
    ## Ruby uses ANSI api to fork a process on Windows.
83
    ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
84
    ## and these are incompatible with ASCII.
85
    ## Git for Windows (msysGit) changed internal API from ANSI to Unicode in 1.7.10
86
    ## http://code.google.com/p/msysgit/issues/detail?id=80
87
    ## So, Latin-1 path tests fail on Japanese Windows
88
    WINDOWS_PASS = (Redmine::Platform.mswin? &&
89
                         Redmine::Scm::Adapters::GitAdapter.client_version_above?([1, 7, 10]))
90
    WINDOWS_SKIP_STR = "TODO: This test fails in Git for Windows above 1.7.10"
91

  
92
    def test_scm_available
93
      klass = Repository::Git
94
      assert_equal "Git", klass.scm_name
95
      assert klass.scm_adapter_class
96
      assert_not_equal "", klass.scm_command
97
      assert_equal true, klass.scm_available
98
    end
99

  
100
    def test_entries
101
      entries = @repository.entries
102
      assert_kind_of Redmine::Scm::Adapters::Entries, entries
103
    end
104

  
105
    def test_fetch_changesets_from_scratch
106
      assert_nil @repository.extra_info
107

  
108
      assert_equal 0, @repository.changesets.count
109
      @repository.fetch_changesets
110
      @project.reload
111

  
112
      assert_equal NUM_REV, @repository.changesets.count
113
      assert_equal 39, @repository.filechanges.count
114

  
115
      commit = @repository.changesets.find_by_revision("7234cb2750b63f47bff735edc50a1c0a433c2518")
116
      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518", commit.scmid
117
      assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments
118
      assert_equal "jsmith <jsmith@foo.bar>", commit.committer
119
      assert_equal User.find_by_login('jsmith'), commit.user
120
      # TODO: add a commit with commit time <> author time to the test repository
121
      assert_equal "2007-12-14 09:22:52".to_time, commit.committed_on
122
      assert_equal "2007-12-14".to_date, commit.commit_date
123
      assert_equal 3, commit.filechanges.count
124
      change = commit.filechanges.sort_by(&:path).first
125
      assert_equal "README", change.path
126
      assert_equal nil, change.from_path
127
      assert_equal "A", change.action
128

  
129
      assert_equal NUM_HEAD, @repository.extra_info["heads"].size
130
    end
131

  
132
    def test_fetch_changesets_incremental
133
      assert_equal 0, @repository.changesets.count
134
      @repository.fetch_changesets
135
      @project.reload
136
      assert_equal NUM_REV, @repository.changesets.count
137
      extra_info_heads = @repository.extra_info["heads"].dup
138
      assert_equal NUM_HEAD, extra_info_heads.size
139
      extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
140
      assert_equal 4, extra_info_heads.size
141

  
142
      del_revs = [
143
          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
144
          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
145
          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
146
          "deff712f05a90d96edbd70facc47d944be5897e3",
147
          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
148
          "7e61ac704deecde634b51e59daa8110435dcb3da",
149
         ]
150
      @repository.changesets.each do |rev|
151
        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
152
      end
153
      @project.reload
154
      cs1 = @repository.changesets
155
      assert_equal NUM_REV - 6, cs1.count
156
      extra_info_heads << "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
157
      h = {}
158
      h["heads"] = extra_info_heads
159
      @repository.merge_extra_info(h)
160
      @repository.save
161
      @project.reload
162
      assert @repository.extra_info["heads"].index("4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8")
163
      @repository.fetch_changesets
164
      @project.reload
165
      assert_equal NUM_REV, @repository.changesets.count
166
      assert_equal NUM_HEAD, @repository.extra_info["heads"].size
167
      assert @repository.extra_info["heads"].index("83ca5fd546063a3c7dc2e568ba3355661a9e2b2c")
168
    end
169

  
170
    def test_fetch_changesets_history_editing
171
      assert_equal 0, @repository.changesets.count
172
      @repository.fetch_changesets
173
      @project.reload
174
      assert_equal NUM_REV, @repository.changesets.count
175
      extra_info_heads = @repository.extra_info["heads"].dup
176
      assert_equal NUM_HEAD, extra_info_heads.size
177
      extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
178
      assert_equal 4, extra_info_heads.size
179

  
180
      del_revs = [
181
          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
182
          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
183
          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
184
          "deff712f05a90d96edbd70facc47d944be5897e3",
185
          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
186
          "7e61ac704deecde634b51e59daa8110435dcb3da",
187
         ]
188
      @repository.changesets.each do |rev|
189
        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
190
      end
191
      @project.reload
192
      assert_equal NUM_REV - 6, @repository.changesets.count
193

  
194
      c = Changeset.new(:repository   => @repository,
195
                        :committed_on => Time.now,
196
                        :revision     => "abcd1234efgh",
197
                        :scmid        => "abcd1234efgh",
198
                        :comments     => 'test')
199
      assert c.save
200
      @project.reload
201
      assert_equal NUM_REV - 5, @repository.changesets.count
202

  
203
      extra_info_heads << "1234abcd5678"
204
      h = {}
205
      h["heads"] = extra_info_heads
206
      @repository.merge_extra_info(h)
207
      @repository.save
208
      @project.reload
209
      h1 = @repository.extra_info["heads"].dup
210
      assert h1.index("1234abcd5678")
211
      assert_equal 5, h1.size
212

  
213
      @repository.fetch_changesets
214
      @project.reload
215
      assert_equal NUM_REV - 5, @repository.changesets.count
216
      h2 = @repository.extra_info["heads"].dup
217
      assert_equal h1, h2
218
    end
219

  
220
    def test_keep_extra_report_last_commit_in_clear_changesets
221
      assert_nil @repository.extra_info
222
      h = {}
223
      h["extra_report_last_commit"] = "1"
224
      @repository.merge_extra_info(h)
225
      @repository.save
226
      @project.reload
227

  
228
      assert_equal 0, @repository.changesets.count
229
      @repository.fetch_changesets
230
      @project.reload
231

  
232
      assert_equal NUM_REV, @repository.changesets.count
233
      @repository.send(:clear_changesets)
234
      assert_equal 1, @repository.extra_info.size
235
      assert_equal "1", @repository.extra_info["extra_report_last_commit"]
236
    end
237

  
238
    def test_refetch_after_clear_changesets
239
      assert_nil @repository.extra_info
240
      assert_equal 0, @repository.changesets.count
241
      @repository.fetch_changesets
242
      @project.reload
243
      assert_equal NUM_REV, @repository.changesets.count
244

  
245
      @repository.send(:clear_changesets)
246
      @project.reload
247
      assert_equal 0, @repository.changesets.count
248

  
249
      @repository.fetch_changesets
250
      @project.reload
251
      assert_equal NUM_REV, @repository.changesets.count
252
    end
253

  
254
    def test_parents
255
      assert_equal 0, @repository.changesets.count
256
      @repository.fetch_changesets
257
      @project.reload
258
      assert_equal NUM_REV, @repository.changesets.count
259
      r1 = @repository.find_changeset_by_name("7234cb2750b63")
260
      assert_equal [], r1.parents
261
      r2 = @repository.find_changeset_by_name("899a15dba03a3")
262
      assert_equal 1, r2.parents.length
263
      assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
264
                   r2.parents[0].identifier
265
      r3 = @repository.find_changeset_by_name("32ae898b720c2")
266
      assert_equal 2, r3.parents.length
267
      r4 = [r3.parents[0].identifier, r3.parents[1].identifier].sort
268
      assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", r4[0]
269
      assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da", r4[1]
270
    end
271

  
272
    def test_db_consistent_ordering_init
273
      assert_nil @repository.extra_info
274
      assert_equal 0, @repository.changesets.count
275
      @repository.fetch_changesets
276
      @project.reload
277
      assert_equal 1, @repository.extra_info["db_consistent"]["ordering"]
278
    end
279

  
280
    def test_db_consistent_ordering_before_1_2
281
      assert_nil @repository.extra_info
282
      assert_equal 0, @repository.changesets.count
283
      @repository.fetch_changesets
284
      @project.reload
285
      assert_equal NUM_REV, @repository.changesets.count
286
      assert_not_nil @repository.extra_info
287
      h = {}
288
      h["heads"] = []
289
      h["branches"] = {}
290
      h["db_consistent"] = {}
291
      @repository.merge_extra_info(h)
292
      @repository.save
293
      assert_equal NUM_REV, @repository.changesets.count
294
      @repository.fetch_changesets
295
      @project.reload
296
      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
297

  
298
      extra_info_heads = @repository.extra_info["heads"].dup
299
      extra_info_heads.delete_if { |x| x == "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c" }
300
      del_revs = [
301
          "83ca5fd546063a3c7dc2e568ba3355661a9e2b2c",
302
          "ed5bb786bbda2dee66a2d50faf51429dbc043a7b",
303
          "4f26664364207fa8b1af9f8722647ab2d4ac5d43",
304
          "deff712f05a90d96edbd70facc47d944be5897e3",
305
          "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
306
          "7e61ac704deecde634b51e59daa8110435dcb3da",
307
         ]
308
      @repository.changesets.each do |rev|
309
        rev.destroy if del_revs.detect {|r| r == rev.scmid.to_s }
310
      end
311
      @project.reload
312
      cs1 = @repository.changesets
313
      assert_equal NUM_REV - 6, cs1.count
314
      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
315

  
316
      extra_info_heads << "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8"
317
      h = {}
318
      h["heads"] = extra_info_heads
319
      @repository.merge_extra_info(h)
320
      @repository.save
321
      @project.reload
322
      assert @repository.extra_info["heads"].index("4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8")
323
      @repository.fetch_changesets
324
      @project.reload
325
      assert_equal NUM_REV, @repository.changesets.count
326
      assert_equal NUM_HEAD, @repository.extra_info["heads"].size
327

  
328
      assert_equal 0, @repository.extra_info["db_consistent"]["ordering"]
329
    end
330

  
331
    def test_heads_from_branches_hash
332
      assert_nil @repository.extra_info
333
      assert_equal 0, @repository.changesets.count
334
      assert_equal [], @repository.heads_from_branches_hash
335
      h = {}
336
      h["branches"] = {}
337
      h["branches"]["test1"] = {}
338
      h["branches"]["test1"]["last_scmid"] = "1234abcd"
339
      h["branches"]["test2"] = {}
340
      h["branches"]["test2"]["last_scmid"] = "abcd1234"
341
      @repository.merge_extra_info(h)
342
      @repository.save
343
      @project.reload
344
      assert_equal ["1234abcd", "abcd1234"], @repository.heads_from_branches_hash.sort
345
    end
346

  
347
    def test_latest_changesets
348
      assert_equal 0, @repository.changesets.count
349
      @repository.fetch_changesets
350
      @project.reload
351
      assert_equal NUM_REV, @repository.changesets.count
352
      # with limit
353
      changesets = @repository.latest_changesets('', 'master', 2)
354
      assert_equal 2, changesets.size
355

  
356
      # with path
357
      changesets = @repository.latest_changesets('images', 'master')
358
      assert_equal [
359
              'deff712f05a90d96edbd70facc47d944be5897e3',
360
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
361
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
362
          ], changesets.collect(&:revision)
363

  
364
      changesets = @repository.latest_changesets('README', nil)
365
      assert_equal [
366
              '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf',
367
              '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8',
368
              '713f4944648826f558cf548222f813dabe7cbb04',
369
              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
370
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
371
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
372
          ], changesets.collect(&:revision)
373

  
374
      # with path, revision and limit
375
      changesets = @repository.latest_changesets('images', '899a15dba')
376
      assert_equal [
377
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
378
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
379
          ], changesets.collect(&:revision)
380

  
381
      changesets = @repository.latest_changesets('images', '899a15dba', 1)
382
      assert_equal [
383
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
384
          ], changesets.collect(&:revision)
385

  
386
      changesets = @repository.latest_changesets('README', '899a15dba')
387
      assert_equal [
388
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
389
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
390
          ], changesets.collect(&:revision)
391

  
392
      changesets = @repository.latest_changesets('README', '899a15dba', 1)
393
      assert_equal [
394
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
395
          ], changesets.collect(&:revision)
396

  
397
      # with path, tag and limit
398
      changesets = @repository.latest_changesets('images', 'tag01.annotated')
399
      assert_equal [
400
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
401
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
402
          ], changesets.collect(&:revision)
403

  
404
      changesets = @repository.latest_changesets('images', 'tag01.annotated', 1)
405
      assert_equal [
406
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
407
          ], changesets.collect(&:revision)
408

  
409
      changesets = @repository.latest_changesets('README', 'tag01.annotated')
410
      assert_equal [
411
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
412
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
413
          ], changesets.collect(&:revision)
414

  
415
      changesets = @repository.latest_changesets('README', 'tag01.annotated', 1)
416
      assert_equal [
417
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
418
          ], changesets.collect(&:revision)
419

  
420
      # with path, branch and limit
421
      changesets = @repository.latest_changesets('images', 'test_branch')
422
      assert_equal [
423
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
424
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
425
          ], changesets.collect(&:revision)
426

  
427
      changesets = @repository.latest_changesets('images', 'test_branch', 1)
428
      assert_equal [
429
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
430
          ], changesets.collect(&:revision)
431

  
432
      changesets = @repository.latest_changesets('README', 'test_branch')
433
      assert_equal [
434
              '713f4944648826f558cf548222f813dabe7cbb04',
435
              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
436
              '899a15dba03a3b350b89c3f537e4bbe02a03cdc9',
437
              '7234cb2750b63f47bff735edc50a1c0a433c2518',
438
          ], changesets.collect(&:revision)
439

  
440
      changesets = @repository.latest_changesets('README', 'test_branch', 2)
441
      assert_equal [
442
              '713f4944648826f558cf548222f813dabe7cbb04',
443
              '61b685fbe55ab05b5ac68402d5720c1a6ac973d1',
444
          ], changesets.collect(&:revision)
445

  
446
      if WINDOWS_PASS
447
        puts WINDOWS_SKIP_STR
448
      elsif JRUBY_SKIP
449
        puts JRUBY_SKIP_STR
450
      else
451
        # latin-1 encoding path
452
        changesets = @repository.latest_changesets(
453
                      "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89')
454
        assert_equal [
455
              '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
456
              '4fc55c43bf3d3dc2efb66145365ddc17639ce81e',
457
          ], changesets.collect(&:revision)
458

  
459
        changesets = @repository.latest_changesets(
460
                    "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1)
461
        assert_equal [
462
              '64f1f3e89ad1cb57976ff0ad99a107012ba3481d',
463
          ], changesets.collect(&:revision)
464
      end
465
    end
466

  
467
    def test_latest_changesets_latin_1_dir
468
      if WINDOWS_PASS
469
        puts WINDOWS_SKIP_STR
470
      elsif JRUBY_SKIP
471
        puts JRUBY_SKIP_STR
472
      else
473
        assert_equal 0, @repository.changesets.count
474
        @repository.fetch_changesets
475
        @project.reload
476
        assert_equal NUM_REV, @repository.changesets.count
477
        changesets = @repository.latest_changesets(
478
                    "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed')
479
        assert_equal [
480
              '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127',
481
          ], changesets.collect(&:revision)
482
      end
483
    end
484

  
485
    def test_find_changeset_by_name
486
      assert_equal 0, @repository.changesets.count
487
      @repository.fetch_changesets
488
      @project.reload
489
      assert_equal NUM_REV, @repository.changesets.count
490
      ['7234cb2750b63f47bff735edc50a1c0a433c2518', '7234cb2750b'].each do |r|
491
        assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518',
492
                     @repository.find_changeset_by_name(r).revision
493
      end
494
    end
495

  
496
    def test_find_changeset_by_empty_name
497
      assert_equal 0, @repository.changesets.count
498
      @repository.fetch_changesets
499
      @project.reload
500
      assert_equal NUM_REV, @repository.changesets.count
501
      ['', ' ', nil].each do |r|
502
        assert_nil @repository.find_changeset_by_name(r)
503
      end
504
    end
505

  
506
    def test_identifier
507
      assert_equal 0, @repository.changesets.count
508
      @repository.fetch_changesets
509
      @project.reload
510
      assert_equal NUM_REV, @repository.changesets.count
511
      c = @repository.changesets.find_by_revision(
512
                          '7234cb2750b63f47bff735edc50a1c0a433c2518')
513
      assert_equal c.scmid, c.identifier
514
    end
515

  
516
    def test_format_identifier
517
      assert_equal 0, @repository.changesets.count
518
      @repository.fetch_changesets
519
      @project.reload
520
      assert_equal NUM_REV, @repository.changesets.count
521
      c = @repository.changesets.find_by_revision(
522
                          '7234cb2750b63f47bff735edc50a1c0a433c2518')
523
      assert_equal '7234cb27', c.format_identifier
524
    end
525

  
526
    def test_activities
527
      c = Changeset.new(:repository => @repository,
528
                        :committed_on => Time.now,
529
                        :revision => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
530
                        :scmid    => 'abc7234cb2750b63f47bff735edc50a1c0a433c2',
531
                        :comments => 'test')
532
      assert c.event_title.include?('abc7234c:')
533
      assert_equal 'abc7234cb2750b63f47bff735edc50a1c0a433c2', c.event_url[:rev]
534
    end
535

  
536
    def test_log_utf8
537
      assert_equal 0, @repository.changesets.count
538
      @repository.fetch_changesets
539
      @project.reload
540
      assert_equal NUM_REV, @repository.changesets.count
541
      str_felix_hex  = FELIX_HEX.dup
542
      if str_felix_hex.respond_to?(:force_encoding)
543
          str_felix_hex.force_encoding('UTF-8')
544
      end
545
      c = @repository.changesets.find_by_revision(
546
                        'ed5bb786bbda2dee66a2d50faf51429dbc043a7b')
547
      assert_equal "#{str_felix_hex} <felix@fachschaften.org>", c.committer
548
    end
549

  
550
    def test_previous
551
      assert_equal 0, @repository.changesets.count
552
      @repository.fetch_changesets
553
      @project.reload
554
      assert_equal NUM_REV, @repository.changesets.count
555
      %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
556
        changeset = @repository.find_changeset_by_name(r1)
557
        %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
558
          assert_equal @repository.find_changeset_by_name(r2), changeset.previous
559
        end
560
      end
561
    end
562

  
563
    def test_previous_nil
564
      assert_equal 0, @repository.changesets.count
565
      @repository.fetch_changesets
566
      @project.reload
567
      assert_equal NUM_REV, @repository.changesets.count
568
      %w|7234cb2750b63f47bff735edc50a1c0a433c2518 7234cb275|.each do |r1|
569
        changeset = @repository.find_changeset_by_name(r1)
570
        assert_nil changeset.previous
571
      end
572
    end
573

  
574
    def test_next
575
      assert_equal 0, @repository.changesets.count
576
      @repository.fetch_changesets
577
      @project.reload
578
      assert_equal NUM_REV, @repository.changesets.count
579
      %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2|
580
        changeset = @repository.find_changeset_by_name(r2)
581
        %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1|
582
        assert_equal @repository.find_changeset_by_name(r1), changeset.next
583
        end
584
      end
585
    end
586

  
587
    def test_next_nil
588
      assert_equal 0, @repository.changesets.count
589
      @repository.fetch_changesets
590
      @project.reload
591
      assert_equal NUM_REV, @repository.changesets.count
592
      %w|2a682156a3b6e77a8bf9cd4590e8db757f3c6c78 2a682156a3b6e77a|.each do |r1|
593
        changeset = @repository.find_changeset_by_name(r1)
594
        assert_nil changeset.next
595
      end
596
    end
597
  else
598
    puts "Git test repository NOT FOUND. Skipping unit tests !!!"
599
    def test_fake; assert true end
600
  end
601
end
.svn/pristine/32/326ec63d3dde535244f38884da87eca7ff6e8ba3.svn-base
1
# German translations for Ruby on Rails
2
# by Clemens Kofler (clemens@railway.at)
3
# additions for Redmine 1.2 by Jens Martsch (jmartsch@gmail.com)
4

  
5
de:
6
  direction: ltr
7
  date:
8
    formats:
9
      # Use the strftime parameters for formats.
10
      # When no format has been given, it uses default.
11
      # You can provide other formats here if you like!
12
      default: "%d.%m.%Y"
13
      short: "%e. %b"
14
      long: "%e. %B %Y"
15

  
16
    day_names: [Sonntag, Montag, Dienstag, Mittwoch, Donnerstag, Freitag, Samstag]
17
    abbr_day_names: [So, Mo, Di, Mi, Do, Fr, Sa]
18

  
19
    # Don't forget the nil at the beginning; there's no such thing as a 0th month
20
    month_names: [~, Januar, Februar, März, April, Mai, Juni, Juli, August, September, Oktober, November, Dezember]
21
    abbr_month_names: [~, Jan, Feb, Mär, Apr, Mai, Jun, Jul, Aug, Sep, Okt, Nov, Dez]
22
    # Used in date_select and datime_select.
23
    order:
24
      - :day
25
      - :month
26
      - :year
27

  
28
  time:
29
    formats:
30
      default: "%d.%m.%Y %H:%M"
31
      time: "%H:%M"
32
      short: "%e. %b %H:%M"
33
      long: "%A, %e. %B %Y, %H:%M Uhr"
34
    am: "vormittags"
35
    pm: "nachmittags"
36

  
37
  datetime:
38
    distance_in_words:
39
      half_a_minute: 'eine halbe Minute'
40
      less_than_x_seconds:
41
        one: 'weniger als 1 Sekunde'
42
        other: 'weniger als %{count} Sekunden'
43
      x_seconds:
44
        one: '1 Sekunde'
45
        other: '%{count} Sekunden'
46
      less_than_x_minutes:
47
        one: 'weniger als 1 Minute'
48
        other: 'weniger als %{count} Minuten'
49
      x_minutes:
50
        one: '1 Minute'
51
        other: '%{count} Minuten'
52
      about_x_hours:
53
        one: 'etwa 1 Stunde'
54
        other: 'etwa %{count} Stunden'
55
      x_hours:
56
        one:   "1 Stunde"
57
        other: "%{count} Stunden"
58
      x_days:
59
        one: '1 Tag'
60
        other: '%{count} Tagen'
61
      about_x_months:
62
        one: 'etwa 1 Monat'
63
        other: 'etwa %{count} Monaten'
64
      x_months:
65
        one: '1 Monat'
66
        other: '%{count} Monaten'
67
      about_x_years:
68
        one: 'etwa 1 Jahr'
69
        other: 'etwa %{count} Jahren'
70
      over_x_years:
71
        one: 'mehr als 1 Jahr'
72
        other: 'mehr als %{count} Jahren'
73
      almost_x_years:
74
        one:   "fast 1 Jahr"
75
        other: "fast %{count} Jahren"
76

  
77
  number:
78
    # Default format for numbers
79
    format:
80
      separator: ','
81
      delimiter: '.'
82
      precision: 2
83
    currency:
84
      format:
85
        unit: '€'
86
        format: '%n %u'
87
        delimiter: ''
88
    percentage:
89
      format:
90
        delimiter: ""
91
    precision:
92
      format:
93
        delimiter: ""
94
    human:
95
      format:
96
        delimiter: ""
97
        precision: 3
98
      storage_units:
99
        format: "%n %u"
100
        units:
101
          byte:
102
            one: "Byte"
103
            other: "Bytes"
104
          kb: "KB"
105
          mb: "MB"
106
          gb: "GB"
107
          tb: "TB"
108

  
109
# Used in array.to_sentence.
110
  support:
111
    array:
112
      sentence_connector: "und"
113
      skip_last_comma: true
114

  
115
  activerecord:
116
    errors:
117
      template:
118
        header:
119
          one:    "Dieses %{model}-Objekt konnte nicht gespeichert werden: %{count} Fehler."
120
          other:  "Dieses %{model}-Objekt konnte nicht gespeichert werden: %{count} Fehler."
121
        body: "Bitte überprüfen Sie die folgenden Felder:"
122

  
123
      messages:
124
        inclusion: "ist kein gültiger Wert"
125
        exclusion: "ist nicht verfügbar"
126
        invalid: "ist nicht gültig"
127
        confirmation: "stimmt nicht mit der Bestätigung überein"
128
        accepted: "muss akzeptiert werden"
129
        empty: "muss ausgefüllt werden"
130
        blank: "muss ausgefüllt werden"
131
        too_long: "ist zu lang (nicht mehr als %{count} Zeichen)"
132
        too_short: "ist zu kurz (nicht weniger als %{count} Zeichen)"
133
        wrong_length: "hat die falsche Länge (muss genau %{count} Zeichen haben)"
134
        taken: "ist bereits vergeben"
135
        not_a_number: "ist keine Zahl"
136
        not_a_date: "is kein gültiges Datum"
137
        greater_than: "muss größer als %{count} sein"
138
        greater_than_or_equal_to: "muss größer oder gleich %{count} sein"
139
        equal_to: "muss genau %{count} sein"
140
        less_than: "muss kleiner als %{count} sein"
141
        less_than_or_equal_to: "muss kleiner oder gleich %{count} sein"
142
        odd: "muss ungerade sein"
143
        even: "muss gerade sein"
144
        greater_than_start_date: "muss größer als Anfangsdatum sein"
145
        not_same_project: "gehört nicht zum selben Projekt"
146
        circular_dependency: "Diese Beziehung würde eine zyklische Abhängigkeit erzeugen"
147
        cant_link_an_issue_with_a_descendant: "Ein Ticket kann nicht mit einer Ihrer Unteraufgaben verlinkt werden"
148

  
149
  actionview_instancetag_blank_option: Bitte auswählen
150

  
151
  button_activate: Aktivieren
152
  button_add: Hinzufügen
153
  button_annotate: Annotieren
154
  button_apply: Anwenden
155
  button_archive: Archivieren
156
  button_back: Zurück
157
  button_cancel: Abbrechen
158
  button_change: Wechseln
159
  button_change_password: Kennwort ändern
160
  button_check_all: Alles auswählen
161
  button_clear: Zurücksetzen
162
  button_close: Schließen
163
  button_collapse_all: Alle einklappen
164
  button_configure: Konfigurieren
165
  button_copy: Kopieren
166
  button_copy_and_follow: Kopieren und Ticket anzeigen
167
  button_create: Anlegen
168
  button_create_and_continue: Anlegen und weiter
169
  button_delete: Löschen
170
  button_delete_my_account: Mein Benutzerkonto löschen 
171
  button_download: Download
172
  button_duplicate: Duplizieren
173
  button_edit: Bearbeiten
174
  button_edit_associated_wikipage: "Zugehörige Wikiseite bearbeiten: %{page_title}"
175
  button_edit_section: Diesen Bereich bearbeiten
176
  button_expand_all: Alle ausklappen
177
  button_export: Exportieren
178
  button_hide: Verstecken
179
  button_list: Liste
180
  button_lock: Sperren
181
  button_log_time: Aufwand buchen
182
  button_login: Anmelden
183
  button_move: Verschieben
184
  button_move_and_follow: Verschieben und Ticket anzeigen
185
  button_quote: Zitieren
186
  button_rename: Umbenennen
187
  button_reopen: Öffnen
188
  button_reply: Antworten
189
  button_reset: Zurücksetzen
190
  button_rollback: Auf diese Version zurücksetzen
191
  button_save: Speichern
192
  button_show: Anzeigen
193
  button_sort: Sortieren
194
  button_submit: OK
195
  button_test: Testen
196
  button_unarchive: Entarchivieren
197
  button_uncheck_all: Alles abwählen
198
  button_unlock: Entsperren
199
  button_unwatch: Nicht beobachten
200
  button_update: Bearbeiten
201
  button_view: Anzeigen
202
  button_watch: Beobachten
203

  
204
  default_activity_design: Design
205
  default_activity_development: Entwicklung
206
  default_doc_category_tech: Technische Dokumentation
207
  default_doc_category_user: Benutzerdokumentation
208
  default_issue_status_closed: Erledigt
209
  default_issue_status_feedback: Feedback
210
  default_issue_status_in_progress: In Bearbeitung
211
  default_issue_status_new: Neu
212
  default_issue_status_rejected: Abgewiesen
213
  default_issue_status_resolved: Gelöst
214
  default_priority_high: Hoch
215
  default_priority_immediate: Sofort
216
  default_priority_low: Niedrig
217
  default_priority_normal: Normal
218
  default_priority_urgent: Dringend
219
  default_role_developer: Entwickler
220
  default_role_manager: Manager
221
  default_role_reporter: Reporter
222
  default_tracker_bug: Fehler
223
  default_tracker_feature: Feature
224
  default_tracker_support: Unterstützung
225

  
226
  description_all_columns: Alle Spalten
227
  description_available_columns: Verfügbare Spalten
228
  description_choose_project: Projekte
229
  description_date_from: Startdatum eintragen
230
  description_date_range_interval: Zeitraum durch Start- und Enddatum festlegen
231
  description_date_range_list: Zeitraum aus einer Liste wählen
232
  description_date_to: Enddatum eintragen
233
  description_filter: Filter
234
  description_issue_category_reassign: Neue Kategorie wählen
235
  description_message_content: Nachrichteninhalt
236
  description_notes: Kommentare
237
  description_project_scope: Suchbereich
238
  description_query_sort_criteria_attribute: Sortierattribut
239
  description_query_sort_criteria_direction: Sortierrichtung
240
  description_search: Suchfeld
241
  description_selected_columns: Ausgewählte Spalten
242
  description_user_mail_notification: Mailbenachrichtigungseinstellung
243
  description_wiki_subpages_reassign: Neue Elternseite wählen
244

  
245
  enumeration_activities: Aktivitäten (Zeiterfassung)
246
  enumeration_doc_categories: Dokumentenkategorien
247
  enumeration_issue_priorities: Ticket-Prioritäten
248
  enumeration_system_activity: System-Aktivität
249

  
250
  error_attachment_too_big: Diese Datei kann nicht hochgeladen werden, da sie die maximale Dateigröße von (%{max_size}) überschreitet.
251
  error_can_not_archive_project: Dieses Projekt kann nicht archiviert werden.
252
  error_can_not_delete_custom_field: Kann das benutzerdefinierte Feld nicht löschen.
253
  error_can_not_delete_tracker: Dieser Tracker enthält Tickets und kann nicht gelöscht werden.
254
  error_can_not_remove_role: Diese Rolle wird verwendet und kann nicht gelöscht werden.
255
  error_can_not_reopen_issue_on_closed_version: Das Ticket ist einer abgeschlossenen Version zugeordnet und kann daher nicht wieder geöffnet werden.
256
  error_can_t_load_default_data: "Die Standard-Konfiguration konnte nicht geladen werden: %{value}"
257
  error_issue_done_ratios_not_updated: Der Ticket-Fortschritt wurde nicht aktualisiert.
258
  error_issue_not_found_in_project: 'Das Ticket wurde nicht gefunden oder gehört nicht zu diesem Projekt.'
259
  error_no_default_issue_status: Es ist kein Status als Standard definiert. Bitte überprüfen Sie Ihre Konfiguration (unter "Administration -> Ticket-Status").
260
  error_no_tracker_in_project: Diesem Projekt ist kein Tracker zugeordnet. Bitte überprüfen Sie die Projekteinstellungen.
261
  error_scm_annotate: "Der Eintrag existiert nicht oder kann nicht annotiert werden."
262
  error_scm_annotate_big_text_file: Der Eintrag kann nicht umgesetzt werden, da er die maximale Textlänge überschreitet.
263
  error_scm_command_failed: "Beim Zugriff auf das Projektarchiv ist ein Fehler aufgetreten: %{value}"
264
  error_scm_not_found: Eintrag und/oder Revision existiert nicht im Projektarchiv.
265
  error_session_expired: Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an.
266
  error_unable_delete_issue_status: "Der Ticket-Status konnte nicht gelöscht werden."
267
  error_unable_to_connect: Fehler beim Verbinden (%{value})
268
  error_workflow_copy_source: Bitte wählen Sie einen Quell-Tracker und eine Quell-Rolle.
269
  error_workflow_copy_target: Bitte wählen Sie die Ziel-Tracker und -Rollen.
270

  
271
  field_account: Konto
272
  field_active: Aktiv
273
  field_activity: Aktivität
274
  field_admin: Administrator
275
  field_assignable: Tickets können dieser Rolle zugewiesen werden
276
  field_assigned_to: Zugewiesen an
277
  field_assigned_to_role: Zuständigkeitsrolle
278
  field_attr_firstname: Vorname-Attribut
279
  field_attr_lastname: Name-Attribut
280
  field_attr_login: Mitgliedsname-Attribut
281
  field_attr_mail: E-Mail-Attribut
282
  field_auth_source: Authentifizierungs-Modus
283
  field_auth_source_ldap_filter: LDAP-Filter
284
  field_author: Autor
285
  field_base_dn: Base DN
286
  field_board_parent: Übergeordnetes Forum
287
  field_category: Kategorie
288
  field_column_names: Spalten
289
  field_closed_on: Geschlossen am
290
  field_comments: Kommentar
291
  field_comments_sorting: Kommentare anzeigen
292
  field_commit_logs_encoding: Kodierung der Commit-Log-Meldungen
293
  field_content: Inhalt
294
  field_core_fields: Standardwerte
295
  field_created_on: Angelegt
296
  field_cvs_module: Modul
297
  field_cvsroot: CVSROOT
298
  field_default_value: Standardwert
299
  field_delay: Pufferzeit
300
  field_description: Beschreibung
301
  field_done_ratio: "% erledigt"
302
  field_downloads: Downloads
303
  field_due_date: Abgabedatum
304
  field_editable: Bearbeitbar
305
  field_effective_date: Datum
306
  field_estimated_hours: Geschätzter Aufwand
307
  field_field_format: Format
308
  field_filename: Datei
309
  field_filesize: Größe
310
  field_firstname: Vorname
311
  field_fixed_version: Zielversion
312
  field_group_by: Gruppiere Ergebnisse nach
313
  field_hide_mail: E-Mail-Adresse nicht anzeigen
314
  field_homepage: Projekt-Homepage
315
  field_host: Host
316
  field_hours: Stunden
317
  field_identifier: Kennung
318
  field_identity_url: OpenID-URL
319
  field_inherit_members: Benutzer vererben
320
  field_is_closed: Ticket geschlossen
321
  field_is_default: Standardeinstellung
322
  field_is_filter: Als Filter benutzen
323
  field_is_for_all: Für alle Projekte
324
  field_is_in_roadmap: In der Roadmap anzeigen
325
  field_is_private: Privat
326
  field_is_public: Öffentlich
327
  field_is_required: Erforderlich
328
  field_issue: Ticket
329
  field_issue_to: Zugehöriges Ticket
330
  field_issues_visibility: Ticket Sichtbarkeit
331
  field_language: Sprache
332
  field_last_login_on: Letzte Anmeldung
333
  field_lastname: Nachname
334
  field_login: Mitgliedsname
335
  field_mail: E-Mail
336
  field_mail_notification: Mailbenachrichtigung
337
  field_max_length: Maximale Länge
338
  field_member_of_group: Zuständigkeitsgruppe
339
  field_min_length: Minimale Länge
340
  field_multiple: Mehrere Werte
341
  field_name: Name
342
  field_new_password: Neues Kennwort
343
  field_notes: Kommentare
344
  field_onthefly: On-the-fly-Benutzererstellung
345
  field_parent: Unterprojekt von
346
  field_parent_issue: Übergeordnete Aufgabe
347
  field_parent_title: Übergeordnete Seite
348
  field_password: Kennwort
349
  field_password_confirmation: Bestätigung
350
  field_path_to_repository: Pfad zum Repository
351
  field_port: Port
352
  field_possible_values: Mögliche Werte
353
  field_principal: Auftraggeber
354
  field_priority: Priorität
355
  field_private_notes: Privater Kommentar
356
  field_project: Projekt
357
  field_redirect_existing_links: Existierende Links umleiten
358
  field_regexp: Regulärer Ausdruck
359
  field_repository_is_default: Haupt-Repository
360
  field_role: Rolle
361
  field_root_directory: Wurzelverzeichnis
362
  field_scm_path_encoding: Pfad-Kodierung
363
  field_searchable: Durchsuchbar
364
  field_sharing: Gemeinsame Verwendung
365
  field_spent_on: Datum
366
  field_start_date: Beginn
367
  field_start_page: Hauptseite
368
  field_status: Status
369
  field_subject: Thema
370
  field_subproject: Unterprojekt von
371
  field_summary: Zusammenfassung
372
  field_text: Textfeld
373
  field_time_entries: Logzeit
374
  field_time_zone: Zeitzone
375
  field_timeout: Auszeit (in Sekunden)
376
  field_title: Titel
377
  field_tracker: Tracker
378
  field_type: Typ
379
  field_updated_on: Aktualisiert
380
  field_url: URL
381
  field_user: Benutzer
382
  field_value: Wert
383
  field_version: Version
384
  field_visible: Sichtbar
385
  field_warn_on_leaving_unsaved: Vor dem Verlassen einer Seite mit ungesichertem Text im Editor warnen
386
  field_watcher: Beobachter
387

  
388
  general_csv_decimal_separator: ','
389
  general_csv_encoding: ISO-8859-1
390
  general_csv_separator: ';'
391
  general_first_day_of_week: '1'
392
  general_lang_name: 'Deutsch'
393
  general_pdf_encoding: UTF-8
394
  general_text_No: 'Nein'
395
  general_text_Yes: 'Ja'
396
  general_text_no: 'nein'
397
  general_text_yes: 'ja'
398

  
399
  label_activity: Aktivität
400
  label_add_another_file: Eine weitere Datei hinzufügen
401
  label_add_note: Kommentar hinzufügen
402
  label_added: hinzugefügt
403
  label_added_time_by: "Von %{author} vor %{age} hinzugefügt"
404
  label_additional_workflow_transitions_for_assignee: Zusätzliche Berechtigungen wenn der Benutzer der Zugewiesene ist
405
  label_additional_workflow_transitions_for_author: Zusätzliche Berechtigungen wenn der Benutzer der Autor ist
406
  label_administration: Administration
407
  label_age: Geändert vor
408
  label_ago: vor
409
  label_all: alle
410
  label_all_time: gesamter Zeitraum
411
  label_all_words: Alle Wörter
412
  label_and_its_subprojects: "%{value} und dessen Unterprojekte"
413
  label_any: alle
414
  label_any_issues_in_project: irgendein Ticket im Projekt
415
  label_any_issues_not_in_project: irgendein Ticket nicht im Projekt
416
  label_api_access_key: API-Zugriffsschlüssel
417
  label_api_access_key_created_on: Der API-Zugriffsschlüssel wurde vor %{value} erstellt
418
  label_applied_status: Zugewiesener Status
419
  label_ascending: Aufsteigend
420
  label_assigned_to_me_issues: Mir zugewiesene Tickets
421
  label_associated_revisions: Zugehörige Revisionen
422
  label_attachment: Datei
423
  label_attachment_delete: Anhang löschen
424
  label_attachment_new: Neue Datei
425
  label_attachment_plural: Dateien
426
  label_attribute: Attribut
427
  label_attribute_of_assigned_to: "%{name} des Bearbeiters"
428
  label_attribute_of_author: "%{name} des Autors"
429
  label_attribute_of_fixed_version: "%{name} der Zielversion"
430
  label_attribute_of_issue: "%{name} des Tickets"
431
  label_attribute_of_project: "%{name} des Projekts"
432
  label_attribute_of_user: "%{name} des Benutzers"
433
  label_attribute_plural: Attribute
434
  label_auth_source: Authentifizierungs-Modus
435
  label_auth_source_new: Neuer Authentifizierungs-Modus
436
  label_auth_source_plural: Authentifizierungs-Arten
437
  label_authentication: Authentifizierung
438
  label_between: zwischen
439
  label_blocked_by: Blockiert durch
440
  label_blocks: Blockiert
441
  label_board: Forum
442
  label_board_locked: Gesperrt
443
  label_board_new: Neues Forum
444
  label_board_plural: Foren
445
  label_board_sticky: Wichtig (immer oben)
446
  label_boolean: Boolean
447
  label_branch: Zweig
448
  label_browse: Codebrowser
449
  label_bulk_edit_selected_issues: Alle ausgewählten Tickets bearbeiten
450
  label_bulk_edit_selected_time_entries: Ausgewählte Zeitaufwände bearbeiten
451
  label_calendar: Kalender
452
  label_change_plural: Änderungen
453
  label_change_properties: Eigenschaften ändern
454
  label_change_status: Statuswechsel
455
  label_change_view_all: Alle Änderungen anzeigen
456
  label_changes_details: Details aller Änderungen
457
  label_changeset_plural: Changesets
458
  label_child_revision: Nachfolger
459
  label_chronological_order: in zeitlicher Reihenfolge
460
  label_close_versions: Vollständige Versionen schließen
461
  label_closed_issues: geschlossen
462
  label_closed_issues_plural: geschlossen
463
  label_comment: Kommentar
464
  label_comment_add: Kommentar hinzufügen
465
  label_comment_added: Kommentar hinzugefügt
466
  label_comment_delete: Kommentar löschen
467
  label_comment_plural: Kommentare
468
  label_commits_per_author: Übertragungen pro Autor
469
  label_commits_per_month: Übertragungen pro Monat
470
  label_completed_versions: Abgeschlossene Versionen
471
  label_confirmation: Bestätigung
472
  label_contains: enthält
473
  label_copied: kopiert
474
  label_copied_from: Kopiert von
475
  label_copied_to: Kopiert nach
476
  label_copy_attachments: Anhänge kopieren
477
  label_copy_same_as_target: So wie das Ziel
478
  label_copy_source: Quelle
479
  label_copy_subtasks: Unteraufgaben kopieren
480
  label_copy_target: Ziel
481
  label_copy_workflow_from: Workflow kopieren von
482
  label_cross_project_descendants: Mit Unterprojekten
483
  label_cross_project_hierarchy: Mit Projekthierarchie
484
  label_cross_project_system: Mit allen Projekten
485
  label_cross_project_tree: Mit Projektbaum
486
  label_current_status: Gegenwärtiger Status
487
  label_current_version: Gegenwärtige Version
488
  label_custom_field: Benutzerdefiniertes Feld
489
  label_custom_field_new: Neues Feld
490
  label_custom_field_plural: Benutzerdefinierte Felder
491
  label_date: Datum
492
  label_date_from: Von
493
  label_date_from_to: von %{start} bis %{end}
494
  label_date_range: Zeitraum
495
  label_date_to: Bis
496
  label_day_plural: Tage
497
  label_default: Standard
498
  label_default_columns: Standard-Spalten
499
  label_deleted: gelöscht
500
  label_descending: Absteigend
501
  label_details: Details
502
  label_diff: diff
503
  label_diff_inline: einspaltig
504
  label_diff_side_by_side: nebeneinander
505
  label_disabled: gesperrt
506
  label_display: Anzeige
507
  label_display_per_page: "Pro Seite: %{value}"
508
  label_display_used_statuses_only: Zeige nur Status an, die von diesem Tracker verwendet werden
509
  label_document: Dokument
510
  label_document_added: Dokument hinzugefügt
511
  label_document_new: Neues Dokument
512
  label_document_plural: Dokumente
513
  label_downloads_abbr: D/L
514
  label_duplicated_by: Dupliziert durch
515
  label_duplicates: Duplikat von
516
  label_end_to_end: Ende - Ende
517
  label_end_to_start: Ende - Anfang
518
  label_enumeration_new: Neuer Wert
519
  label_enumerations: Aufzählungen
520
  label_environment: Umgebung
521
  label_equals: ist
522
  label_example: Beispiel
523
  label_export_options: "%{export_format} Export-Eigenschaften"
524
  label_export_to: "Auch abrufbar als:"
525
  label_f_hour: "%{value} Stunde"
526
  label_f_hour_plural: "%{value} Stunden"
527
  label_feed_plural: Feeds
528
  label_feeds_access_key: Atom-Zugriffsschlüssel
529
  label_feeds_access_key_created_on: "Atom-Zugriffsschlüssel vor %{value} erstellt"
530
  label_fields_permissions: Feldberechtigungen
531
  label_file_added: Datei hinzugefügt
532
  label_file_plural: Dateien
533
  label_filter_add: Filter hinzufügen
534
  label_filter_plural: Filter
535
  label_float: Fließkommazahl
536
  label_follows: Nachfolger von
537
  label_gantt: Gantt-Diagramm
538
  label_gantt_progress_line: Fortschrittslinie
539
  label_general: Allgemein
540
  label_generate_key: Generieren
541
  label_git_report_last_commit: Bericht des letzten Commits für Dateien und Verzeichnisse
542
  label_greater_or_equal: ">="
543
  label_group: Gruppe
544
  label_group_new: Neue Gruppe
545
  label_group_plural: Gruppen
546
  label_help: Hilfe
547
  label_history: Historie
548
  label_home: Hauptseite
549
  label_in: in
550
  label_in_less_than: in weniger als
551
  label_in_more_than: in mehr als
552
  label_in_the_next_days: in den nächsten
553
  label_in_the_past_days: in den letzten
554
  label_incoming_emails: Eingehende E-Mails
555
  label_index_by_date: Seiten nach Datum sortiert
556
  label_index_by_title: Seiten nach Titel sortiert
557
  label_information: Information
558
  label_information_plural: Informationen
559
  label_integer: Zahl
560
  label_internal: Intern
561
  label_issue: Ticket
562
  label_issue_added: Ticket hinzugefügt
563
  label_issue_category: Ticket-Kategorie
564
  label_issue_category_new: Neue Kategorie
565
  label_issue_category_plural: Ticket-Kategorien
566
  label_issue_new: Neues Ticket
567
  label_issue_note_added: Notiz hinzugefügt
568
  label_issue_plural: Tickets
569
  label_issue_priority_updated: Priorität aktualisiert
570
  label_issue_status: Ticket-Status
571
  label_issue_status_new: Neuer Status
572
  label_issue_status_plural: Ticket-Status
573
  label_issue_status_updated: Status aktualisiert
574
  label_issue_tracking: Tickets
575
  label_issue_updated: Ticket aktualisiert
576
  label_issue_view_all: Alle Tickets anzeigen
577
  label_issue_watchers: Beobachter
578
  label_issues_by: "Tickets pro %{value}"
579
  label_issues_visibility_all: Alle Tickets
580
  label_issues_visibility_own: Tickets die folgender Benutzer erstellt hat oder die ihm zugewiesen sind
581
  label_issues_visibility_public: Alle öffentlichen Tickets
582
  label_item_position: "%{position}/%{count}"
583
  label_jump_to_a_project: Zu einem Projekt springen...
584
  label_language_based: Sprachabhängig
585
  label_last_changes: "%{count} letzte Änderungen"
586
  label_last_login: Letzte Anmeldung
587
  label_last_month: voriger Monat
588
  label_last_n_days: "die letzten %{count} Tage"
589
  label_last_n_weeks: letzte %{count} Wochen
590
  label_last_week: vorige Woche
591
  label_latest_revision: Aktuellste Revision
592
  label_latest_revision_plural: Aktuellste Revisionen
593
  label_ldap_authentication: LDAP-Authentifizierung
594
  label_less_or_equal: "<="
595
  label_less_than_ago: vor weniger als
596
  label_list: Liste
597
  label_loading: Lade...
598
  label_logged_as: Angemeldet als
599
  label_login: Anmelden
600
  label_login_with_open_id_option: oder mit OpenID anmelden
601
  label_logout: Abmelden
602
  label_max_size: Maximale Größe
603
  label_me: ich
604
  label_member: Mitglied
605
  label_member_new: Neues Mitglied
606
  label_member_plural: Mitglieder
607
  label_message_last: Letzter Forenbeitrag
608
  label_message_new: Neues Thema
609
  label_message_plural: Forenbeiträge
610
  label_message_posted: Forenbeitrag hinzugefügt
611
  label_min_max_length: Länge (Min. - Max.)
612
  label_missing_api_access_key: Der API-Zugriffsschlüssel fehlt.
613
  label_missing_feeds_access_key: Der Atom-Zugriffsschlüssel fehlt.
614
  label_modified: geändert
615
  label_module_plural: Module
616
  label_month: Monat
617
  label_months_from: Monate ab
618
  label_more: Mehr
619
  label_more_than_ago: vor mehr als
620
  label_my_account: Mein Konto
621
  label_my_page: Meine Seite
622
  label_my_page_block: Verfügbare Widgets
623
  label_my_projects: Meine Projekte
624
  label_my_queries: Meine eigenen Abfragen
625
  label_new: Neu
626
  label_new_statuses_allowed: Neue Berechtigungen
627
  label_news: News
628
  label_news_added: News hinzugefügt
629
  label_news_comment_added: Kommentar zu einer News hinzugefügt
630
  label_news_latest: Letzte News
631
  label_news_new: News hinzufügen
632
  label_news_plural: News
633
  label_news_view_all: Alle News anzeigen
634
  label_next: Weiter
635
  label_no_change_option: (Keine Änderung)
636
  label_no_data: Nichts anzuzeigen
637
  label_no_issues_in_project: keine Tickets im Projekt
638
  label_nobody: Niemand
639
  label_none: kein
640
  label_not_contains: enthält nicht
641
  label_not_equals: ist nicht
642
  label_open_issues: offen
643
  label_open_issues_plural: offen
644
  label_optional_description: Beschreibung (optional)
645
  label_options: Optionen
646
  label_overall_activity: Aktivitäten aller Projekte anzeigen
647
  label_overall_spent_time: Aufgewendete Zeit aller Projekte anzeigen
648
  label_overview: Übersicht
649
  label_parent_revision: Vorgänger
650
  label_password_lost: Kennwort vergessen
651
  label_per_page: Pro Seite
652
  label_permissions: Berechtigungen
653
  label_permissions_report: Berechtigungsübersicht
654
  label_personalize_page: Diese Seite anpassen
655
  label_planning: Terminplanung
656
  label_please_login: Anmelden
657
  label_plugins: Plugins
658
  label_precedes: Vorgänger von
659
  label_preferences: Präferenzen
660
  label_preview: Vorschau
661
  label_previous: Zurück
662
  label_principal_search: "Nach Benutzer oder Gruppe suchen:"
663
  label_profile: Profil
664
  label_project: Projekt
665
  label_project_all: Alle Projekte
666
  label_project_copy_notifications: Sende Mailbenachrichtigungen beim Kopieren des Projekts.
667
  label_project_latest: Neueste Projekte
668
  label_project_new: Neues Projekt
669
  label_project_plural: Projekte
670
  label_public_projects: Öffentliche Projekte
671
  label_query: Benutzerdefinierte Abfrage
672
  label_query_new: Neue Abfrage
673
  label_query_plural: Benutzerdefinierte Abfragen
674
  label_read: Lesen...
675
  label_readonly: Nur-Lese-Zugriff
676
  label_register: Registrieren
677
  label_registered_on: Angemeldet am
678
  label_registration_activation_by_email: Kontoaktivierung durch E-Mail
679
  label_registration_automatic_activation: Automatische Kontoaktivierung
680
  label_registration_manual_activation: Manuelle Kontoaktivierung
681
  label_related_issues: Zugehörige Tickets
682
  label_relates_to: Beziehung mit
683
  label_relation_delete: Beziehung löschen
684
  label_relation_new: Neue Beziehung
685
  label_renamed: umbenannt
686
  label_reply_plural: Antworten
687
  label_report: Bericht
688
  label_report_plural: Berichte
689
  label_reported_issues: Erstellte Tickets
690
  label_repository: Projektarchiv
691
  label_repository_new: Neues Repository
692
  label_repository_plural: Projektarchive
693
  label_required: Erforderlich
694
  label_result_plural: Resultate
695
  label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge
696
  label_revision: Revision
697
  label_revision_id: Revision %{value}
698
  label_revision_plural: Revisionen
699
  label_roadmap: Roadmap
700
  label_roadmap_due_in: "Fällig in %{value}"
701
  label_roadmap_no_issues: Keine Tickets für diese Version
702
  label_roadmap_overdue: "%{value} verspätet"
703
  label_role: Rolle
704
  label_role_and_permissions: Rollen und Rechte
705
  label_role_anonymous: Anonymous
706
  label_role_new: Neue Rolle
707
  label_role_non_member: Nichtmitglied
708
  label_role_plural: Rollen
709
  label_scm: Versionskontrollsystem
710
  label_search: Suche
711
  label_search_for_watchers: Nach hinzufügbaren Beobachtern suchen
712
  label_search_titles_only: Nur Titel durchsuchen
713
  label_send_information: Sende Kontoinformationen an Benutzer
714
  label_send_test_email: Test-E-Mail senden
715
  label_session_expiration: Ende einer Sitzung
716
  label_settings: Konfiguration
717
  label_show_closed_projects: Geschlossene Projekte anzeigen
718
  label_show_completed_versions: Abgeschlossene Versionen anzeigen
719
  label_sort: Sortierung
720
  label_sort_by: "Sortiert nach %{value}"
721
  label_sort_higher: Eins höher
722
  label_sort_highest: An den Anfang
723
  label_sort_lower: Eins tiefer
724
  label_sort_lowest: Ans Ende
725
  label_spent_time: Aufgewendete Zeit
726
  label_start_to_end: Anfang - Ende
727
  label_start_to_start: Anfang - Anfang
728
  label_statistics: Statistiken
729
  label_status_transitions: Statusänderungen
730
  label_stay_logged_in: Angemeldet bleiben
731
  label_string: Text
732
  label_subproject_new: Neues Unterprojekt
733
  label_subproject_plural: Unterprojekte
734
  label_subtask_plural: Unteraufgaben
735
  label_tag: Markierung
736
  label_text: Langer Text
737
  label_theme: Stil
738
  label_this_month: aktueller Monat
739
  label_this_week: aktuelle Woche
740
  label_this_year: aktuelles Jahr
741
  label_time_entry_plural: Benötigte Zeit
742
  label_time_tracking: Zeiterfassung
743
  label_today: heute
744
  label_topic_plural: Themen
745
  label_total: Gesamtzahl
746
  label_tracker: Tracker
747
  label_tracker_new: Neuer Tracker
748
  label_tracker_plural: Tracker
749
  label_update_issue_done_ratios: Ticket-Fortschritt aktualisieren
750
  label_updated_time: "Vor %{value} aktualisiert"
751
  label_updated_time_by: "Von %{author} vor %{age} aktualisiert"
752
  label_used_by: Benutzt von
753
  label_user: Benutzer
754
  label_user_activity: "Aktivität von %{value}"
755
  label_user_anonymous: Anonym
756
  label_user_mail_no_self_notified: "Ich möchte nicht über Änderungen benachrichtigt werden, die ich selbst durchführe."
757
  label_user_mail_option_all: "Für alle Ereignisse in all meinen Projekten"
758
  label_user_mail_option_none: Keine Ereignisse
759
  label_user_mail_option_only_assigned: Nur für Aufgaben für die ich zuständig bin
760
  label_user_mail_option_only_my_events: Nur für Aufgaben die ich beobachte oder an welchen ich mitarbeite
761
  label_user_mail_option_only_owner: Nur für Aufgaben die ich angelegt habe
762
  label_user_mail_option_selected: "Für alle Ereignisse in den ausgewählten Projekten..."
763
  label_user_new: Neuer Benutzer
764
  label_user_plural: Benutzer
765
  label_user_search: "Nach Benutzer suchen:"
766
  label_version: Version
767
  label_version_new: Neue Version
768
  label_version_plural: Versionen
769
  label_version_sharing_descendants: Mit Unterprojekten
770
  label_version_sharing_hierarchy: Mit Projekthierarchie
771
  label_version_sharing_none: Nicht gemeinsam verwenden
772
  label_version_sharing_system: Mit allen Projekten
773
  label_version_sharing_tree: Mit Projektbaum
774
  label_view_all_revisions: Alle Revisionen anzeigen
775
  label_view_diff: Unterschiede anzeigen
776
  label_view_revisions: Revisionen anzeigen
777
  label_watched_issues: Beobachtete Tickets
778
  label_week: Woche
779
  label_wiki: Wiki
780
  label_wiki_content_added: Wiki-Seite hinzugefügt
781
  label_wiki_content_updated: Wiki-Seite aktualisiert
782
  label_wiki_edit: Wiki-Bearbeitung
783
  label_wiki_edit_plural: Wiki-Bearbeitungen
784
  label_wiki_page: Wiki-Seite
785
  label_wiki_page_plural: Wiki-Seiten
786
  label_workflow: Workflow
787
  label_x_closed_issues_abbr:
788
    zero:  0 geschlossen
789
    one:   1 geschlossen
790
    other: "%{count} geschlossen"
791
  label_x_comments:
792
    zero: keine Kommentare
793
    one: 1 Kommentar
794
    other: "%{count} Kommentare"
795
  label_x_issues:
796
    zero:  0 Tickets
797
    one:   1 Ticket
798
    other: "%{count} Tickets"
799
  label_x_open_issues_abbr:
800
    zero:  0 offen
801
    one:   1 offen
802
    other: "%{count} offen"
803
  label_x_open_issues_abbr_on_total:
804
    zero:  0 offen / %{total}
805
    one:   1 offen / %{total}
806
    other: "%{count} offen / %{total}"
807
  label_x_projects:
808
    zero:  keine Projekte
809
    one:   1 Projekt
810
    other: "%{count} Projekte"
811
  label_year: Jahr
812
  label_yesterday: gestern
813

  
814
  mail_body_account_activation_request: "Ein neuer Benutzer (%{value}) hat sich registriert. Sein Konto wartet auf Ihre Genehmigung:"
815
  mail_body_account_information: Ihre Konto-Informationen
816
  mail_body_account_information_external: "Sie können sich mit Ihrem Konto %{value} anmelden."
817
  mail_body_lost_password: 'Benutzen Sie den folgenden Link, um Ihr Kennwort zu ändern:'
818
  mail_body_register: 'Um Ihr Konto zu aktivieren, benutzen Sie folgenden Link:'
819
  mail_body_reminder: "%{count} Tickets, die Ihnen zugewiesen sind, müssen in den nächsten %{days} Tagen abgegeben werden:"
820
  mail_body_wiki_content_added: "Die Wiki-Seite '%{id}' wurde von %{author} hinzugefügt."
821
  mail_body_wiki_content_updated: "Die Wiki-Seite '%{id}' wurde von %{author} aktualisiert."
822
  mail_subject_account_activation_request: "Antrag auf %{value} Kontoaktivierung"
823
  mail_subject_lost_password: "Ihr %{value} Kennwort"
824
  mail_subject_register: "%{value} Kontoaktivierung"
825
  mail_subject_reminder: "%{count} Tickets müssen in den nächsten %{days} Tagen abgegeben werden"
826
  mail_subject_wiki_content_added: "Wiki-Seite '%{id}' hinzugefügt"
827
  mail_subject_wiki_content_updated: "Wiki-Seite '%{id}' erfolgreich aktualisiert"
828

  
829
  notice_account_activated: Ihr Konto ist aktiviert. Sie können sich jetzt anmelden.
830
  notice_account_deleted: Ihr Benutzerkonto wurde unwiderruflich gelöscht.
831
  notice_account_invalid_creditentials: Benutzer oder Kennwort ist ungültig.
832
  notice_account_lost_email_sent: Eine E-Mail mit Anweisungen, ein neues Kennwort zu wählen, wurde Ihnen geschickt.
833
  notice_account_password_updated: Kennwort wurde erfolgreich aktualisiert.
834
  notice_account_pending: "Ihr Konto wurde erstellt und wartet jetzt auf die Genehmigung des Administrators."
835
  notice_account_register_done: Konto wurde erfolgreich angelegt.
836
  notice_account_unknown_email: Unbekannter Benutzer.
837
  notice_account_updated: Konto wurde erfolgreich aktualisiert.
838
  notice_account_wrong_password: Falsches Kennwort.
839
  notice_api_access_key_reseted: Ihr API-Zugriffsschlüssel wurde zurückgesetzt.
840
  notice_can_t_change_password: Dieses Konto verwendet eine externe Authentifizierungs-Quelle. Unmöglich, das Kennwort zu ändern.
841
  notice_default_data_loaded: Die Standard-Konfiguration wurde erfolgreich geladen.
842
  notice_email_error: "Beim Senden einer E-Mail ist ein Fehler aufgetreten (%{value})."
843
  notice_email_sent: "Eine E-Mail wurde an %{value} gesendet."
844
  notice_failed_to_save_issues: "%{count} von %{total} ausgewählten Tickets konnte(n) nicht gespeichert werden: %{ids}."
845
  notice_failed_to_save_members: "Benutzer konnte nicht gespeichert werden: %{errors}."
846
  notice_failed_to_save_time_entries: "Gescheitert %{count} Zeiteinträge für %{total} von ausgewählten: %{ids} zu speichern." 
847
  notice_feeds_access_key_reseted: Ihr Atom-Zugriffsschlüssel wurde zurückgesetzt.
848
  notice_file_not_found: Anhang existiert nicht oder ist gelöscht worden.
849
  notice_gantt_chart_truncated: Die Grafik ist unvollständig, da das Maximum der anzeigbaren Aufgaben überschritten wurde (%{max})
850
  notice_issue_done_ratios_updated: Der Ticket-Fortschritt wurde aktualisiert.
851
  notice_issue_successful_create: Ticket %{id} erstellt.
852
  notice_issue_update_conflict: Das Ticket wurde von einem anderen Nutzer überarbeitet während Ihrer Bearbeitung.
853
  notice_locking_conflict: Datum wurde von einem anderen Benutzer geändert.
854
  notice_no_issue_selected: "Kein Ticket ausgewählt! Bitte wählen Sie die Tickets, die Sie bearbeiten möchten."
855
  notice_not_authorized: Sie sind nicht berechtigt, auf diese Seite zuzugreifen.
856
  notice_not_authorized_archived_project: Das Projekt wurde archiviert und ist daher nicht nicht verfügbar.
857
  notice_successful_connection: Verbindung erfolgreich.
858
  notice_successful_create: Erfolgreich angelegt
859
  notice_successful_delete: Erfolgreich gelöscht.
860
  notice_successful_update: Erfolgreich aktualisiert.
861
  notice_unable_delete_time_entry: Der Zeiterfassungseintrag konnte nicht gelöscht werden.
862
  notice_unable_delete_version: Die Version konnte nicht gelöscht werden.
863
  notice_user_successful_create: Benutzer %{id} angelegt.
864

  
865
  permission_add_issue_notes: Kommentare hinzufügen
866
  permission_add_issue_watchers: Beobachter hinzufügen
867
  permission_add_issues: Tickets hinzufügen
868
  permission_add_messages: Forenbeiträge hinzufügen
869
  permission_add_project: Projekt erstellen
870
  permission_add_subprojects: Unterprojekte erstellen
871
  permission_add_documents: Dokumente hinzufügen
872
  permission_browse_repository: Projektarchiv ansehen
873
  permission_close_project: Schließen / erneutes Öffnen eines Projekts
874
  permission_comment_news: News kommentieren
875
  permission_commit_access: Commit-Zugriff
876
  permission_delete_issue_watchers: Beobachter löschen
877
  permission_delete_issues: Tickets löschen
878
  permission_delete_messages: Forenbeiträge löschen
879
  permission_delete_own_messages: Eigene Forenbeiträge löschen
880
  permission_delete_wiki_pages: Wiki-Seiten löschen
881
  permission_delete_wiki_pages_attachments: Anhänge löschen
882
  permission_delete_documents: Dokumente löschen
883
  permission_edit_issue_notes: Kommentare bearbeiten
884
  permission_edit_issues: Tickets bearbeiten
885
  permission_edit_messages: Forenbeiträge bearbeiten
886
  permission_edit_own_issue_notes: Eigene Kommentare bearbeiten
887
  permission_edit_own_messages: Eigene Forenbeiträge bearbeiten
888
  permission_edit_own_time_entries: Selbst gebuchte Aufwände bearbeiten
889
  permission_edit_project: Projekt bearbeiten
890
  permission_edit_time_entries: Gebuchte Aufwände bearbeiten
891
  permission_edit_wiki_pages: Wiki-Seiten bearbeiten
892
  permission_edit_documents: Dokumente bearbeiten
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff