##// END OF EJS Templates
scm: git: remove unused "--all" option of "git log" in lib revisions method...
Toshi MARUYAMA -
r8693:f319409abc95
parent child
Show More
@@ -1,387 +1,386
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2011 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/abstract_adapter'
19 19
20 20 module Redmine
21 21 module Scm
22 22 module Adapters
23 23 class GitAdapter < AbstractAdapter
24 24
25 25 # Git executable name
26 26 GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
27 27
28 28 class << self
29 29 def client_command
30 30 @@bin ||= GIT_BIN
31 31 end
32 32
33 33 def sq_bin
34 34 @@sq_bin ||= shell_quote_command
35 35 end
36 36
37 37 def client_version
38 38 @@client_version ||= (scm_command_version || [])
39 39 end
40 40
41 41 def client_available
42 42 !client_version.empty?
43 43 end
44 44
45 45 def scm_command_version
46 46 scm_version = scm_version_from_command_line.dup
47 47 if scm_version.respond_to?(:force_encoding)
48 48 scm_version.force_encoding('ASCII-8BIT')
49 49 end
50 50 if m = scm_version.match(%r{\A(.*?)((\d+\.)+\d+)})
51 51 m[2].scan(%r{\d+}).collect(&:to_i)
52 52 end
53 53 end
54 54
55 55 def scm_version_from_command_line
56 56 shellout("#{sq_bin} --version --no-color") { |io| io.read }.to_s
57 57 end
58 58 end
59 59
60 60 def initialize(url, root_url=nil, login=nil, password=nil, path_encoding=nil)
61 61 super
62 62 @path_encoding = path_encoding.blank? ? 'UTF-8' : path_encoding
63 63 end
64 64
65 65 def path_encoding
66 66 @path_encoding
67 67 end
68 68
69 69 def info
70 70 begin
71 71 Info.new(:root_url => url, :lastrev => lastrev('',nil))
72 72 rescue
73 73 nil
74 74 end
75 75 end
76 76
77 77 def branches
78 78 return @branches if @branches
79 79 @branches = []
80 80 cmd_args = %w|branch --no-color --verbose --no-abbrev|
81 81 scm_cmd(*cmd_args) do |io|
82 82 io.each_line do |line|
83 83 branch_rev = line.match('\s*\*?\s*(.*?)\s*([0-9a-f]{40}).*$')
84 84 bran = Branch.new(branch_rev[1])
85 85 bran.revision = branch_rev[2]
86 86 bran.scmid = branch_rev[2]
87 87 @branches << bran
88 88 end
89 89 end
90 90 @branches.sort!
91 91 rescue ScmCommandAborted
92 92 nil
93 93 end
94 94
95 95 def tags
96 96 return @tags if @tags
97 97 cmd_args = %w|tag|
98 98 scm_cmd(*cmd_args) do |io|
99 99 @tags = io.readlines.sort!.map{|t| t.strip}
100 100 end
101 101 rescue ScmCommandAborted
102 102 nil
103 103 end
104 104
105 105 def default_branch
106 106 bras = self.branches
107 107 return nil if bras.nil?
108 108 bras.include?('master') ? 'master' : bras.first
109 109 end
110 110
111 111 def entry(path=nil, identifier=nil)
112 112 parts = path.to_s.split(%r{[\/\\]}).select {|n| !n.blank?}
113 113 search_path = parts[0..-2].join('/')
114 114 search_name = parts[-1]
115 115 if search_path.blank? && search_name.blank?
116 116 # Root entry
117 117 Entry.new(:path => '', :kind => 'dir')
118 118 else
119 119 # Search for the entry in the parent directory
120 120 es = entries(search_path, identifier,
121 121 options = {:report_last_commit => false})
122 122 es ? es.detect {|e| e.name == search_name} : nil
123 123 end
124 124 end
125 125
126 126 def entries(path=nil, identifier=nil, options={})
127 127 path ||= ''
128 128 p = scm_iconv(@path_encoding, 'UTF-8', path)
129 129 entries = Entries.new
130 130 cmd_args = %w|ls-tree -l|
131 131 cmd_args << "HEAD:#{p}" if identifier.nil?
132 132 cmd_args << "#{identifier}:#{p}" if identifier
133 133 scm_cmd(*cmd_args) do |io|
134 134 io.each_line do |line|
135 135 e = line.chomp.to_s
136 136 if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\t(.+)$/
137 137 type = $1
138 138 sha = $2
139 139 size = $3
140 140 name = $4
141 141 if name.respond_to?(:force_encoding)
142 142 name.force_encoding(@path_encoding)
143 143 end
144 144 full_path = p.empty? ? name : "#{p}/#{name}"
145 145 n = scm_iconv('UTF-8', @path_encoding, name)
146 146 full_p = scm_iconv('UTF-8', @path_encoding, full_path)
147 147 entries << Entry.new({:name => n,
148 148 :path => full_p,
149 149 :kind => (type == "tree") ? 'dir' : 'file',
150 150 :size => (type == "tree") ? nil : size,
151 151 :lastrev => options[:report_last_commit] ?
152 152 lastrev(full_path, identifier) : Revision.new
153 153 }) unless entries.detect{|entry| entry.name == name}
154 154 end
155 155 end
156 156 end
157 157 entries.sort_by_name
158 158 rescue ScmCommandAborted
159 159 nil
160 160 end
161 161
162 162 def lastrev(path, rev)
163 163 return nil if path.nil?
164 164 cmd_args = %w|log --no-color --encoding=UTF-8 --date=iso --pretty=fuller --no-merges -n 1|
165 165 cmd_args << rev if rev
166 166 cmd_args << "--" << path unless path.empty?
167 167 lines = []
168 168 scm_cmd(*cmd_args) { |io| lines = io.readlines }
169 169 begin
170 170 id = lines[0].split[1]
171 171 author = lines[1].match('Author:\s+(.*)$')[1]
172 172 time = Time.parse(lines[4].match('CommitDate:\s+(.*)$')[1])
173 173
174 174 Revision.new({
175 175 :identifier => id,
176 176 :scmid => id,
177 177 :author => author,
178 178 :time => time,
179 179 :message => nil,
180 180 :paths => nil
181 181 })
182 182 rescue NoMethodError => e
183 183 logger.error("The revision '#{path}' has a wrong format")
184 184 return nil
185 185 end
186 186 rescue ScmCommandAborted
187 187 nil
188 188 end
189 189
190 190 def revisions(path, identifier_from, identifier_to, options={})
191 191 revs = Revisions.new
192 192 cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents|
193 193 cmd_args << "--reverse" if options[:reverse]
194 cmd_args << "--all" if options[:all]
195 194 cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit]
196 195 from_to = ""
197 196 from_to << "#{identifier_from}.." if identifier_from
198 197 from_to << "#{identifier_to}" if identifier_to
199 198 cmd_args << from_to if !from_to.empty?
200 199 cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty?
201 200
202 201 scm_cmd *cmd_args do |io|
203 202 files=[]
204 203 changeset = {}
205 204 parsing_descr = 0 #0: not parsing desc or files, 1: parsing desc, 2: parsing files
206 205
207 206 io.each_line do |line|
208 207 if line =~ /^commit ([0-9a-f]{40})(( [0-9a-f]{40})*)$/
209 208 key = "commit"
210 209 value = $1
211 210 parents_str = $2
212 211 if (parsing_descr == 1 || parsing_descr == 2)
213 212 parsing_descr = 0
214 213 revision = Revision.new({
215 214 :identifier => changeset[:commit],
216 215 :scmid => changeset[:commit],
217 216 :author => changeset[:author],
218 217 :time => Time.parse(changeset[:date]),
219 218 :message => changeset[:description],
220 219 :paths => files,
221 220 :parents => changeset[:parents]
222 221 })
223 222 if block_given?
224 223 yield revision
225 224 else
226 225 revs << revision
227 226 end
228 227 changeset = {}
229 228 files = []
230 229 end
231 230 changeset[:commit] = $1
232 231 unless parents_str.nil? or parents_str == ""
233 232 changeset[:parents] = parents_str.strip.split(' ')
234 233 end
235 234 elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
236 235 key = $1
237 236 value = $2
238 237 if key == "Author"
239 238 changeset[:author] = value
240 239 elsif key == "CommitDate"
241 240 changeset[:date] = value
242 241 end
243 242 elsif (parsing_descr == 0) && line.chomp.to_s == ""
244 243 parsing_descr = 1
245 244 changeset[:description] = ""
246 245 elsif (parsing_descr == 1 || parsing_descr == 2) \
247 246 && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\t(.+)$/
248 247 parsing_descr = 2
249 248 fileaction = $1
250 249 filepath = $2
251 250 p = scm_iconv('UTF-8', @path_encoding, filepath)
252 251 files << {:action => fileaction, :path => p}
253 252 elsif (parsing_descr == 1 || parsing_descr == 2) \
254 253 && line =~ /^:\d+\s+\d+\s+[0-9a-f.]+\s+[0-9a-f.]+\s+(\w)\d+\s+(\S+)\t(.+)$/
255 254 parsing_descr = 2
256 255 fileaction = $1
257 256 filepath = $3
258 257 p = scm_iconv('UTF-8', @path_encoding, filepath)
259 258 files << {:action => fileaction, :path => p}
260 259 elsif (parsing_descr == 1) && line.chomp.to_s == ""
261 260 parsing_descr = 2
262 261 elsif (parsing_descr == 1)
263 262 changeset[:description] << line[4..-1]
264 263 end
265 264 end
266 265
267 266 if changeset[:commit]
268 267 revision = Revision.new({
269 268 :identifier => changeset[:commit],
270 269 :scmid => changeset[:commit],
271 270 :author => changeset[:author],
272 271 :time => Time.parse(changeset[:date]),
273 272 :message => changeset[:description],
274 273 :paths => files,
275 274 :parents => changeset[:parents]
276 275 })
277 276 if block_given?
278 277 yield revision
279 278 else
280 279 revs << revision
281 280 end
282 281 end
283 282 end
284 283 revs
285 284 rescue ScmCommandAborted => e
286 285 logger.error("git log #{from_to.to_s} error: #{e.message}")
287 286 revs
288 287 end
289 288
290 289 def diff(path, identifier_from, identifier_to=nil)
291 290 path ||= ''
292 291 cmd_args = []
293 292 if identifier_to
294 293 cmd_args << "diff" << "--no-color" << identifier_to << identifier_from
295 294 else
296 295 cmd_args << "show" << "--no-color" << identifier_from
297 296 end
298 297 cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) unless path.empty?
299 298 diff = []
300 299 scm_cmd *cmd_args do |io|
301 300 io.each_line do |line|
302 301 diff << line
303 302 end
304 303 end
305 304 diff
306 305 rescue ScmCommandAborted
307 306 nil
308 307 end
309 308
310 309 def annotate(path, identifier=nil)
311 310 identifier = 'HEAD' if identifier.blank?
312 311 cmd_args = %w|blame|
313 312 cmd_args << "-p" << identifier << "--" << scm_iconv(@path_encoding, 'UTF-8', path)
314 313 blame = Annotate.new
315 314 content = nil
316 315 scm_cmd(*cmd_args) { |io| io.binmode; content = io.read }
317 316 # git annotates binary files
318 317 return nil if content.is_binary_data?
319 318 identifier = ''
320 319 # git shows commit author on the first occurrence only
321 320 authors_by_commit = {}
322 321 content.split("\n").each do |line|
323 322 if line =~ /^([0-9a-f]{39,40})\s.*/
324 323 identifier = $1
325 324 elsif line =~ /^author (.+)/
326 325 authors_by_commit[identifier] = $1.strip
327 326 elsif line =~ /^\t(.*)/
328 327 blame.add_line($1, Revision.new(
329 328 :identifier => identifier,
330 329 :revision => identifier,
331 330 :scmid => identifier,
332 331 :author => authors_by_commit[identifier]
333 332 ))
334 333 identifier = ''
335 334 author = ''
336 335 end
337 336 end
338 337 blame
339 338 rescue ScmCommandAborted
340 339 nil
341 340 end
342 341
343 342 def cat(path, identifier=nil)
344 343 if identifier.nil?
345 344 identifier = 'HEAD'
346 345 end
347 346 cmd_args = %w|show --no-color|
348 347 cmd_args << "#{identifier}:#{scm_iconv(@path_encoding, 'UTF-8', path)}"
349 348 cat = nil
350 349 scm_cmd(*cmd_args) do |io|
351 350 io.binmode
352 351 cat = io.read
353 352 end
354 353 cat
355 354 rescue ScmCommandAborted
356 355 nil
357 356 end
358 357
359 358 class Revision < Redmine::Scm::Adapters::Revision
360 359 # Returns the readable identifier
361 360 def format_identifier
362 361 identifier[0,8]
363 362 end
364 363 end
365 364
366 365 def scm_cmd(*args, &block)
367 366 repo_path = root_url || url
368 367 full_args = ['--git-dir', repo_path]
369 368 if self.class.client_version_above?([1, 7, 2])
370 369 full_args << '-c' << 'core.quotepath=false'
371 370 full_args << '-c' << 'log.decorate=no'
372 371 end
373 372 full_args += args
374 373 ret = shellout(
375 374 self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
376 375 &block
377 376 )
378 377 if $? && $?.exitstatus != 0
379 378 raise ScmCommandAborted, "git exited with non-zero status: #{$?.exitstatus}"
380 379 end
381 380 ret
382 381 end
383 382 private :scm_cmd
384 383 end
385 384 end
386 385 end
387 386 end
@@ -1,433 +1,422
1 1 # encoding: utf-8
2 2
3 3 # This file includes UTF-8 "Felix SchΓ€fer".
4 4 # We need to consider Ruby 1.9 compatibility.
5 5
6 6 require File.expand_path('../../../../../../test_helper', __FILE__)
7 7 begin
8 8 require 'mocha'
9 9
10 10 class GitAdapterTest < ActiveSupport::TestCase
11 11 REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
12 12
13 13 FELIX_UTF8 = "Felix SchΓ€fer"
14 14 FELIX_HEX = "Felix Sch\xC3\xA4fer"
15 15 CHAR_1_HEX = "\xc3\x9c"
16 16
17 17 ## Ruby uses ANSI api to fork a process on Windows.
18 18 ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem
19 19 ## and these are incompatible with ASCII.
20 20 # WINDOWS_PASS = Redmine::Platform.mswin?
21 21 WINDOWS_PASS = false
22 22
23 23 ## Git, Mercurial and CVS path encodings are binary.
24 24 ## Subversion supports URL encoding for path.
25 25 ## Redmine Mercurial adapter and extension use URL encoding.
26 26 ## Git accepts only binary path in command line parameter.
27 27 ## So, there is no way to use binary command line parameter in JRuby.
28 28 JRUBY_SKIP = (RUBY_PLATFORM == 'java')
29 29 JRUBY_SKIP_STR = "TODO: This test fails in JRuby"
30 30
31 31 if File.directory?(REPOSITORY_PATH)
32 32 def setup
33 33 adapter_class = Redmine::Scm::Adapters::GitAdapter
34 34 assert adapter_class
35 35 assert adapter_class.client_command
36 36 assert_equal true, adapter_class.client_available
37 37 assert_equal true, adapter_class.client_version_above?([1])
38 38 assert_equal true, adapter_class.client_version_above?([1, 0])
39 39
40 40 @adapter = Redmine::Scm::Adapters::GitAdapter.new(
41 41 REPOSITORY_PATH,
42 42 nil,
43 43 nil,
44 44 nil,
45 45 'ISO-8859-1'
46 46 )
47 47 assert @adapter
48 48 @char_1 = CHAR_1_HEX.dup
49 49 if @char_1.respond_to?(:force_encoding)
50 50 @char_1.force_encoding('UTF-8')
51 51 end
52 52 end
53 53
54 54 def test_scm_version
55 55 to_test = { "git version 1.7.3.4\n" => [1,7,3,4],
56 56 "1.6.1\n1.7\n1.8" => [1,6,1],
57 57 "1.6.2\r\n1.8.1\r\n1.9.1" => [1,6,2]}
58 58 to_test.each do |s, v|
59 59 test_scm_version_for(s, v)
60 60 end
61 61 end
62 62
63 63 def test_branches
64 64 brs = []
65 65 @adapter.branches.each do |b|
66 66 brs << b
67 67 end
68 68 assert_equal 4, brs.length
69 69 assert_equal 'latin-1-path-encoding', brs[0].to_s
70 70 assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', brs[0].revision
71 71 assert_equal brs[0].scmid, brs[0].revision
72 72 assert_equal 'master', brs[1].to_s
73 73 assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', brs[1].revision
74 74 assert_equal brs[1].scmid, brs[1].revision
75 75 assert_equal 'test-latin-1', brs[2].to_s
76 76 assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', brs[2].revision
77 77 assert_equal brs[2].scmid, brs[2].revision
78 78 assert_equal 'test_branch', brs[3].to_s
79 79 assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', brs[3].revision
80 80 assert_equal brs[3].scmid, brs[3].revision
81 81 end
82 82
83 83 def test_tags
84 84 assert_equal [
85 85 "tag00.lightweight",
86 86 "tag01.annotated",
87 87 ], @adapter.tags
88 88 end
89 89
90 def test_getting_all_revisions
91 assert_equal 21, @adapter.revisions('',nil,nil,:all => true).length
92 end
93
94 def test_revisions_reverse
95 revs1 = @adapter.revisions('',nil,nil,{:all => true, :reverse => true })
96 assert_equal 21, revs1.length
97 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[0].identifier
98 assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[20].identifier
99 end
100
101 90 def test_revisions_master_all
102 91 revs1 = []
103 92 @adapter.revisions('', nil, "master",{}) do |rev|
104 93 revs1 << rev
105 94 end
106 95 assert_equal 15, revs1.length
107 96 assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[ 0].identifier
108 97 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
109 98
110 99 revs2 = []
111 100 @adapter.revisions('', nil, "master",
112 101 {:reverse => true}) do |rev|
113 102 revs2 << rev
114 103 end
115 104 assert_equal 15, revs2.length
116 105 assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
117 106 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
118 107 end
119 108
120 109 def test_revisions_master_merged_rev
121 110 revs1 = []
122 111 @adapter.revisions('',
123 112 "713f4944648826f558cf548222f813dabe7cbb04",
124 113 "master",
125 114 {:reverse => true}) do |rev|
126 115 revs1 << rev
127 116 end
128 117 assert_equal 8, revs1.length
129 118 assert_equal 'fba357b886984ee71185ad2065e65fc0417d9b92', revs1[ 0].identifier
130 119 assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs1[ 1].identifier
131 120 # 4a07fe31b is not a child of 713f49446
132 121 assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs1[ 2].identifier
133 122 # Merged revision
134 123 assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs1[ 3].identifier
135 124 assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs1[-1].identifier
136 125
137 126 revs2 = []
138 127 @adapter.revisions('',
139 128 "fba357b886984ee71185ad2065e65fc0417d9b92",
140 129 "master",
141 130 {:reverse => true}) do |rev|
142 131 revs2 << rev
143 132 end
144 133 assert_equal 7, revs2.length
145 134 assert_equal '7e61ac704deecde634b51e59daa8110435dcb3da', revs2[ 0].identifier
146 135 # 4a07fe31b is not a child of fba357b8869
147 136 assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', revs2[ 1].identifier
148 137 # Merged revision
149 138 assert_equal '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', revs2[ 2].identifier
150 139 assert_equal '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c', revs2[-1].identifier
151 140 end
152 141
153 142 def test_revisions_branch_latin_1_path_encoding_all
154 143 revs1 = []
155 144 @adapter.revisions('', nil, "latin-1-path-encoding",{}) do |rev|
156 145 revs1 << rev
157 146 end
158 147 assert_equal 8, revs1.length
159 148 assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[ 0].identifier
160 149 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[-1].identifier
161 150
162 151 revs2 = []
163 152 @adapter.revisions('', nil, "latin-1-path-encoding",
164 153 {:reverse => true}) do |rev|
165 154 revs2 << rev
166 155 end
167 156 assert_equal 8, revs2.length
168 157 assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
169 158 assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs2[ 0].identifier
170 159 end
171 160
172 161 def test_revisions_branch_latin_1_path_encoding_with_rev
173 162 revs1 = []
174 163 @adapter.revisions('',
175 164 '7234cb2750b63f47bff735edc50a1c0a433c2518',
176 165 "latin-1-path-encoding",
177 166 {:reverse => true}) do |rev|
178 167 revs1 << rev
179 168 end
180 169 assert_equal 7, revs1.length
181 170 assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', revs1[ 0].identifier
182 171 assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[-1].identifier
183 172
184 173 revs2 = []
185 174 @adapter.revisions('',
186 175 '57ca437c0acbbcb749821fdf3726a1367056d364',
187 176 "latin-1-path-encoding",
188 177 {:reverse => true}) do |rev|
189 178 revs2 << rev
190 179 end
191 180 assert_equal 3, revs2.length
192 181 assert_equal '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', revs2[ 0].identifier
193 182 assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[-1].identifier
194 183 end
195 184
196 185 def test_revisions_invalid_rev
197 186 revs1 = []
198 187 @adapter.revisions('',
199 188 '1234abcd',
200 189 "master",
201 190 {:reverse => true}) do |rev|
202 191 revs1 << rev
203 192 end
204 193 assert_equal [], revs1
205 194 end
206 195
207 196 def test_getting_revisions_with_spaces_in_filename
208 197 assert_equal 1, @adapter.revisions("filemane with spaces.txt",
209 198 nil, "master").length
210 199 end
211 200
212 201 def test_parents
213 202 revs1 = []
214 203 @adapter.revisions('',
215 204 nil,
216 205 "master",
217 206 {:reverse => true}) do |rev|
218 207 revs1 << rev
219 208 end
220 209 assert_equal 15, revs1.length
221 210 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
222 211 revs1[0].identifier
223 212 assert_equal nil, revs1[0].parents
224 213 assert_equal "899a15dba03a3b350b89c3f537e4bbe02a03cdc9",
225 214 revs1[1].identifier
226 215 assert_equal 1, revs1[1].parents.length
227 216 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
228 217 revs1[1].parents[0]
229 218 assert_equal "32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf",
230 219 revs1[10].identifier
231 220 assert_equal 2, revs1[10].parents.length
232 221 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8",
233 222 revs1[10].parents[0]
234 223 assert_equal "7e61ac704deecde634b51e59daa8110435dcb3da",
235 224 revs1[10].parents[1]
236 225 end
237 226
238 227 def test_getting_revisions_with_leading_and_trailing_spaces_in_filename
239 228 assert_equal " filename with a leading space.txt ",
240 229 @adapter.revisions(" filename with a leading space.txt ",
241 230 nil, "master")[0].paths[0][:path]
242 231 end
243 232
244 233 def test_getting_entries_with_leading_and_trailing_spaces_in_filename
245 234 assert_equal " filename with a leading space.txt ",
246 235 @adapter.entries('',
247 236 '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name
248 237 end
249 238
250 239 def test_annotate
251 240 annotate = @adapter.annotate('sources/watchers_controller.rb')
252 241 assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
253 242 assert_equal 41, annotate.lines.size
254 243 assert_equal "# This program is free software; you can redistribute it and/or",
255 244 annotate.lines[4].strip
256 245 assert_equal "7234cb2750b63f47bff735edc50a1c0a433c2518",
257 246 annotate.revisions[4].identifier
258 247 assert_equal "jsmith", annotate.revisions[4].author
259 248 end
260 249
261 250 def test_annotate_moved_file
262 251 annotate = @adapter.annotate('renamed_test.txt')
263 252 assert_kind_of Redmine::Scm::Adapters::Annotate, annotate
264 253 assert_equal 2, annotate.lines.size
265 254 end
266 255
267 256 def test_last_rev
268 257 last_rev = @adapter.lastrev("README",
269 258 "4f26664364207fa8b1af9f8722647ab2d4ac5d43")
270 259 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.scmid
271 260 assert_equal "4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8", last_rev.identifier
272 261 assert_equal "Adam Soltys <asoltys@gmail.com>", last_rev.author
273 262 assert_equal "2009-06-24 05:27:38".to_time, last_rev.time
274 263 end
275 264
276 265 def test_last_rev_with_spaces_in_filename
277 266 last_rev = @adapter.lastrev("filemane with spaces.txt",
278 267 "ed5bb786bbda2dee66a2d50faf51429dbc043a7b")
279 268 str_felix_utf8 = FELIX_UTF8.dup
280 269 str_felix_hex = FELIX_HEX.dup
281 270 last_rev_author = last_rev.author
282 271 if last_rev_author.respond_to?(:force_encoding)
283 272 last_rev_author.force_encoding('UTF-8')
284 273 end
285 274 assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.scmid
286 275 assert_equal "ed5bb786bbda2dee66a2d50faf51429dbc043a7b", last_rev.identifier
287 276 assert_equal "#{str_felix_utf8} <felix@fachschaften.org>",
288 277 last_rev.author
289 278 assert_equal "#{str_felix_hex} <felix@fachschaften.org>",
290 279 last_rev.author
291 280 assert_equal "2010-09-18 19:59:46".to_time, last_rev.time
292 281 end
293 282
294 283 def test_latin_1_path
295 284 if WINDOWS_PASS
296 285 #
297 286 elsif JRUBY_SKIP
298 287 puts JRUBY_SKIP_STR
299 288 else
300 289 p2 = "latin-1-dir/test-#{@char_1}-2.txt"
301 290 ['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1|
302 291 assert @adapter.diff(p2, r1)
303 292 assert @adapter.cat(p2, r1)
304 293 assert_equal 1, @adapter.annotate(p2, r1).lines.length
305 294 ['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2|
306 295 assert @adapter.diff(p2, r1, r2)
307 296 end
308 297 end
309 298 end
310 299 end
311 300
312 301 def test_entries_tag
313 302 entries1 = @adapter.entries(nil, 'tag01.annotated',
314 303 options = {:report_last_commit => true})
315 304 assert entries1
316 305 assert_equal 3, entries1.size
317 306 assert_equal 'sources', entries1[1].name
318 307 assert_equal 'sources', entries1[1].path
319 308 assert_equal 'dir', entries1[1].kind
320 309 readme = entries1[2]
321 310 assert_equal 'README', readme.name
322 311 assert_equal 'README', readme.path
323 312 assert_equal 'file', readme.kind
324 313 assert_equal 27, readme.size
325 314 assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier
326 315 assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time
327 316 end
328 317
329 318 def test_entries_branch
330 319 entries1 = @adapter.entries(nil, 'test_branch',
331 320 options = {:report_last_commit => true})
332 321 assert entries1
333 322 assert_equal 4, entries1.size
334 323 assert_equal 'sources', entries1[1].name
335 324 assert_equal 'sources', entries1[1].path
336 325 assert_equal 'dir', entries1[1].kind
337 326 readme = entries1[2]
338 327 assert_equal 'README', readme.name
339 328 assert_equal 'README', readme.path
340 329 assert_equal 'file', readme.kind
341 330 assert_equal 159, readme.size
342 331 assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier
343 332 assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time
344 333 end
345 334
346 335 def test_entries_latin_1_files
347 336 entries1 = @adapter.entries('latin-1-dir', '64f1f3e8')
348 337 assert entries1
349 338 assert_equal 3, entries1.size
350 339 f1 = entries1[1]
351 340 assert_equal "test-#{@char_1}-2.txt", f1.name
352 341 assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path
353 342 assert_equal 'file', f1.kind
354 343 end
355 344
356 345 def test_entries_latin_1_dir
357 346 if WINDOWS_PASS
358 347 #
359 348 elsif JRUBY_SKIP
360 349 puts JRUBY_SKIP_STR
361 350 else
362 351 entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir",
363 352 '1ca7f5ed')
364 353 assert entries1
365 354 assert_equal 3, entries1.size
366 355 f1 = entries1[1]
367 356 assert_equal "test-#{@char_1}-2.txt", f1.name
368 357 assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path
369 358 assert_equal 'file', f1.kind
370 359 end
371 360 end
372 361
373 362 def test_path_encoding_default_utf8
374 363 adpt1 = Redmine::Scm::Adapters::GitAdapter.new(
375 364 REPOSITORY_PATH
376 365 )
377 366 assert_equal "UTF-8", adpt1.path_encoding
378 367 adpt2 = Redmine::Scm::Adapters::GitAdapter.new(
379 368 REPOSITORY_PATH,
380 369 nil,
381 370 nil,
382 371 nil,
383 372 ""
384 373 )
385 374 assert_equal "UTF-8", adpt2.path_encoding
386 375 end
387 376
388 377 def test_cat_path_invalid
389 378 assert_nil @adapter.cat('invalid')
390 379 end
391 380
392 381 def test_cat_revision_invalid
393 382 assert @adapter.cat('README')
394 383 assert_nil @adapter.cat('README', 'abcd1234efgh')
395 384 end
396 385
397 386 def test_diff_path_invalid
398 387 assert_equal [], @adapter.diff('invalid', '713f4944648826f5')
399 388 end
400 389
401 390 def test_diff_revision_invalid
402 391 assert_nil @adapter.diff(nil, 'abcd1234efgh')
403 392 assert_nil @adapter.diff(nil, '713f4944648826f5', 'abcd1234efgh')
404 393 assert_nil @adapter.diff(nil, 'abcd1234efgh', '713f4944648826f5')
405 394 end
406 395
407 396 def test_annotate_path_invalid
408 397 assert_nil @adapter.annotate('invalid')
409 398 end
410 399
411 400 def test_annotate_revision_invalid
412 401 assert @adapter.annotate('README')
413 402 assert_nil @adapter.annotate('README', 'abcd1234efgh')
414 403 end
415 404
416 405 private
417 406
418 407 def test_scm_version_for(scm_command_version, version)
419 408 @adapter.class.expects(:scm_version_from_command_line).returns(scm_command_version)
420 409 assert_equal version, @adapter.class.scm_command_version
421 410 end
422 411
423 412 else
424 413 puts "Git test repository NOT FOUND. Skipping unit tests !!!"
425 414 def test_fake; assert true end
426 415 end
427 416 end
428 417
429 418 rescue LoadError
430 419 class GitMochaFake < ActiveSupport::TestCase
431 420 def test_fake; assert(false, "Requires mocha to run those tests") end
432 421 end
433 422 end
General Comments 0
You need to be logged in to leave comments. Login now