comparison lib/redmine/scm/adapters/git_adapter.rb @ 909:cbb26bc654de redmine-1.3

Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author Chris Cannam
date Fri, 24 Feb 2012 19:09:32 +0000
parents cbce1fd3b1b7
children 433d4f72a19b
comparison
equal deleted inserted replaced
908:c6c2cbd0afee 909:cbb26bc654de
23 class GitAdapter < AbstractAdapter 23 class GitAdapter < AbstractAdapter
24 24
25 # Git executable name 25 # Git executable name
26 GIT_BIN = Redmine::Configuration['scm_git_command'] || "git" 26 GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
27 27
28 # raised if scm command exited with error, e.g. unknown revision.
29 class ScmCommandAborted < CommandFailed; end
30
31 class << self 28 class << self
32 def client_command 29 def client_command
33 @@bin ||= GIT_BIN 30 @@bin ||= GIT_BIN
34 end 31 end
35 32
36 def sq_bin 33 def sq_bin
37 @@sq_bin ||= shell_quote(GIT_BIN) 34 @@sq_bin ||= shell_quote_command
38 end 35 end
39 36
40 def client_version 37 def client_version
41 @@client_version ||= (scm_command_version || []) 38 @@client_version ||= (scm_command_version || [])
42 end 39 end
78 end 75 end
79 76
80 def branches 77 def branches
81 return @branches if @branches 78 return @branches if @branches
82 @branches = [] 79 @branches = []
83 cmd_args = %w|branch --no-color| 80 cmd_args = %w|branch --no-color --verbose --no-abbrev|
84 scm_cmd(*cmd_args) do |io| 81 scm_cmd(*cmd_args) do |io|
85 io.each_line do |line| 82 io.each_line do |line|
86 @branches << line.match('\s*\*?\s*(.*)$')[1] 83 branch_rev = line.match('\s*\*?\s*(.*?)\s*([0-9a-f]{40}).*$')
84 bran = Branch.new(branch_rev[1])
85 bran.revision = branch_rev[2]
86 bran.scmid = branch_rev[2]
87 @branches << bran
87 end 88 end
88 end 89 end
89 @branches.sort! 90 @branches.sort!
90 rescue ScmCommandAborted 91 rescue ScmCommandAborted
91 nil 92 nil
186 nil 187 nil
187 end 188 end
188 189
189 def revisions(path, identifier_from, identifier_to, options={}) 190 def revisions(path, identifier_from, identifier_to, options={})
190 revs = Revisions.new 191 revs = Revisions.new
191 cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller| 192 cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents|
192 cmd_args << "--reverse" if options[:reverse] 193 cmd_args << "--reverse" if options[:reverse]
193 cmd_args << "--all" if options[:all] 194 cmd_args << "--all" if options[:all]
194 cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit] 195 cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit]
195 from_to = "" 196 from_to = ""
196 from_to << "#{identifier_from}.." if identifier_from 197 from_to << "#{identifier_from}.." if identifier_from
203 files=[] 204 files=[]
204 changeset = {} 205 changeset = {}
205 parsing_descr = 0 #0: not parsing desc or files, 1: parsing desc, 2: parsing files 206 parsing_descr = 0 #0: not parsing desc or files, 1: parsing desc, 2: parsing files
206 207
207 io.each_line do |line| 208 io.each_line do |line|
208 if line =~ /^commit ([0-9a-f]{40})$/ 209 if line =~ /^commit ([0-9a-f]{40})(( [0-9a-f]{40})*)$/
209 key = "commit" 210 key = "commit"
210 value = $1 211 value = $1
212 parents_str = $2
211 if (parsing_descr == 1 || parsing_descr == 2) 213 if (parsing_descr == 1 || parsing_descr == 2)
212 parsing_descr = 0 214 parsing_descr = 0
213 revision = Revision.new({ 215 revision = Revision.new({
214 :identifier => changeset[:commit], 216 :identifier => changeset[:commit],
215 :scmid => changeset[:commit], 217 :scmid => changeset[:commit],
216 :author => changeset[:author], 218 :author => changeset[:author],
217 :time => Time.parse(changeset[:date]), 219 :time => Time.parse(changeset[:date]),
218 :message => changeset[:description], 220 :message => changeset[:description],
219 :paths => files 221 :paths => files,
222 :parents => changeset[:parents]
220 }) 223 })
221 if block_given? 224 if block_given?
222 yield revision 225 yield revision
223 else 226 else
224 revs << revision 227 revs << revision
225 end 228 end
226 changeset = {} 229 changeset = {}
227 files = [] 230 files = []
228 end 231 end
229 changeset[:commit] = $1 232 changeset[:commit] = $1
233 unless parents_str.nil? or parents_str == ""
234 changeset[:parents] = parents_str.strip.split(' ')
235 end
230 elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/ 236 elsif (parsing_descr == 0) && line =~ /^(\w+):\s*(.*)$/
231 key = $1 237 key = $1
232 value = $2 238 value = $2
233 if key == "Author" 239 if key == "Author"
234 changeset[:author] = value 240 changeset[:author] = value
264 :identifier => changeset[:commit], 270 :identifier => changeset[:commit],
265 :scmid => changeset[:commit], 271 :scmid => changeset[:commit],
266 :author => changeset[:author], 272 :author => changeset[:author],
267 :time => Time.parse(changeset[:date]), 273 :time => Time.parse(changeset[:date]),
268 :message => changeset[:description], 274 :message => changeset[:description],
269 :paths => files 275 :paths => files,
276 :parents => changeset[:parents]
270 }) 277 })
271 if block_given? 278 if block_given?
272 yield revision 279 yield revision
273 else 280 else
274 revs << revision 281 revs << revision
357 end 364 end
358 end 365 end
359 366
360 def scm_cmd(*args, &block) 367 def scm_cmd(*args, &block)
361 repo_path = root_url || url 368 repo_path = root_url || url
362 full_args = [GIT_BIN, '--git-dir', repo_path] 369 full_args = ['--git-dir', repo_path]
363 if self.class.client_version_above?([1, 7, 2]) 370 if self.class.client_version_above?([1, 7, 2])
364 full_args << '-c' << 'core.quotepath=false' 371 full_args << '-c' << 'core.quotepath=false'
365 full_args << '-c' << 'log.decorate=no' 372 full_args << '-c' << 'log.decorate=no'
366 end 373 end
367 full_args += args 374 full_args += args
368 ret = shellout(full_args.map { |e| shell_quote e.to_s }.join(' '), &block) 375 ret = shellout(
376 self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
377 &block
378 )
369 if $? && $?.exitstatus != 0 379 if $? && $?.exitstatus != 0
370 raise ScmCommandAborted, "git exited with non-zero status: #{$?.exitstatus}" 380 raise ScmCommandAborted, "git exited with non-zero status: #{$?.exitstatus}"
371 end 381 end
372 ret 382 ret
373 end 383 end