diff lib/redmine/scm/adapters/git_adapter.rb @ 1115:433d4f72a19b redmine-2.2

Update to Redmine SVN revision 11137 on 2.2-stable branch
author Chris Cannam
date Mon, 07 Jan 2013 12:01:42 +0000
parents cbb26bc654de
children 51d7f3e06556 622f24f53b42 261b3d9a4903
line wrap: on
line diff
--- a/lib/redmine/scm/adapters/git_adapter.rb	Wed Jun 27 14:54:18 2012 +0100
+++ b/lib/redmine/scm/adapters/git_adapter.rb	Mon Jan 07 12:01:42 2013 +0000
@@ -1,5 +1,5 @@
 # Redmine - project management software
-# Copyright (C) 2006-2011  Jean-Philippe Lang
+# Copyright (C) 2006-2012  Jean-Philippe Lang
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License
@@ -25,6 +25,10 @@
         # Git executable name
         GIT_BIN = Redmine::Configuration['scm_git_command'] || "git"
 
+        class GitBranch < Branch 
+          attr_accessor :is_default
+        end
+
         class << self
           def client_command
             @@bin    ||= GIT_BIN
@@ -78,12 +82,13 @@
           return @branches if @branches
           @branches = []
           cmd_args = %w|branch --no-color --verbose --no-abbrev|
-          scm_cmd(*cmd_args) do |io|
+          git_cmd(cmd_args) do |io|
             io.each_line do |line|
-              branch_rev = line.match('\s*\*?\s*(.*?)\s*([0-9a-f]{40}).*$')
-              bran = Branch.new(branch_rev[1])
-              bran.revision =  branch_rev[2]
-              bran.scmid    =  branch_rev[2]
+              branch_rev = line.match('\s*(\*?)\s*(.*?)\s*([0-9a-f]{40}).*$')
+              bran = GitBranch.new(branch_rev[2])
+              bran.revision =  branch_rev[3]
+              bran.scmid    =  branch_rev[3]
+              bran.is_default = ( branch_rev[1] == '*' )
               @branches << bran
             end
           end
@@ -95,7 +100,7 @@
         def tags
           return @tags if @tags
           cmd_args = %w|tag|
-          scm_cmd(*cmd_args) do |io|
+          git_cmd(cmd_args) do |io|
             @tags = io.readlines.sort!.map{|t| t.strip}
           end
         rescue ScmCommandAborted
@@ -105,7 +110,10 @@
         def default_branch
           bras = self.branches
           return nil if bras.nil?
-          bras.include?('master') ? 'master' : bras.first
+          default_bras = bras.select{|x| x.is_default == true}
+          return default_bras.first.to_s if ! default_bras.empty?
+          master_bras = bras.select{|x| x.to_s == 'master'}
+          master_bras.empty? ? bras.first.to_s : 'master' 
         end
 
         def entry(path=nil, identifier=nil)
@@ -130,7 +138,7 @@
           cmd_args = %w|ls-tree -l|
           cmd_args << "HEAD:#{p}"          if identifier.nil?
           cmd_args << "#{identifier}:#{p}" if identifier
-          scm_cmd(*cmd_args) do |io|
+          git_cmd(cmd_args) do |io|
             io.each_line do |line|
               e = line.chomp.to_s
               if e =~ /^\d+\s+(\w+)\s+([0-9a-f]{40})\s+([0-9-]+)\t(.+)$/
@@ -165,7 +173,7 @@
           cmd_args << rev if rev
           cmd_args << "--" << path unless path.empty?
           lines = []
-          scm_cmd(*cmd_args) { |io| lines = io.readlines }
+          git_cmd(cmd_args) { |io| lines = io.readlines }
           begin
               id = lines[0].split[1]
               author = lines[1].match('Author:\s+(.*)$')[1]
@@ -189,18 +197,28 @@
 
         def revisions(path, identifier_from, identifier_to, options={})
           revs = Revisions.new
-          cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents|
+          cmd_args = %w|log --no-color --encoding=UTF-8 --raw --date=iso --pretty=fuller --parents --stdin|
           cmd_args << "--reverse" if options[:reverse]
-          cmd_args << "--all" if options[:all]
           cmd_args << "-n" << "#{options[:limit].to_i}" if options[:limit]
-          from_to = ""
-          from_to << "#{identifier_from}.." if identifier_from
-          from_to << "#{identifier_to}" if identifier_to
-          cmd_args << from_to if !from_to.empty?
-          cmd_args << "--since=#{options[:since].strftime("%Y-%m-%d %H:%M:%S")}" if options[:since]
           cmd_args << "--" << scm_iconv(@path_encoding, 'UTF-8', path) if path && !path.empty?
+          revisions = []
+          if identifier_from || identifier_to
+            revisions << ""
+            revisions[0] << "#{identifier_from}.." if identifier_from
+            revisions[0] << "#{identifier_to}" if identifier_to
+          else
+            unless options[:includes].blank?
+              revisions += options[:includes]
+            end
+            unless options[:excludes].blank?
+              revisions += options[:excludes].map{|r| "^#{r}"}
+            end
+          end
 
-          scm_cmd *cmd_args do |io|
+          git_cmd(cmd_args, {:write_stdin => true}) do |io|
+            io.binmode
+            io.puts(revisions.join("\n"))
+            io.close_write
             files=[]
             changeset = {}
             parsing_descr = 0  #0: not parsing desc or files, 1: parsing desc, 2: parsing files
@@ -284,8 +302,13 @@
           end
           revs
         rescue ScmCommandAborted => e
-          logger.error("git log #{from_to.to_s} error: #{e.message}")
-          revs
+          err_msg = "git log error: #{e.message}"
+          logger.error(err_msg)
+          if block_given?
+            raise CommandFailed, err_msg
+          else
+            revs
+          end
         end
 
         def diff(path, identifier_from, identifier_to=nil)
@@ -298,7 +321,7 @@
           end
           cmd_args << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path) unless path.empty?
           diff = []
-          scm_cmd *cmd_args do |io|
+          git_cmd(cmd_args) do |io|
             io.each_line do |line|
               diff << line
             end
@@ -314,7 +337,7 @@
           cmd_args << "-p" << identifier << "--" <<  scm_iconv(@path_encoding, 'UTF-8', path)
           blame = Annotate.new
           content = nil
-          scm_cmd(*cmd_args) { |io| io.binmode; content = io.read }
+          git_cmd(cmd_args) { |io| io.binmode; content = io.read }
           # git annotates binary files
           return nil if content.is_binary_data?
           identifier = ''
@@ -348,7 +371,7 @@
           cmd_args = %w|show --no-color|
           cmd_args << "#{identifier}:#{scm_iconv(@path_encoding, 'UTF-8', path)}"
           cat = nil
-          scm_cmd(*cmd_args) do |io|
+          git_cmd(cmd_args) do |io|
             io.binmode
             cat = io.read
           end
@@ -364,7 +387,7 @@
           end
         end
 
-        def scm_cmd(*args, &block)
+        def git_cmd(args, options = {}, &block)
           repo_path = root_url || url
           full_args = ['--git-dir', repo_path]
           if self.class.client_version_above?([1, 7, 2])
@@ -374,6 +397,7 @@
           full_args += args
           ret = shellout(
                    self.class.sq_bin + ' ' + full_args.map { |e| shell_quote e.to_s }.join(' '),
+                   options,
                    &block
                    )
           if $? && $?.exitstatus != 0
@@ -381,7 +405,7 @@
           end
           ret
         end
-        private :scm_cmd
+        private :git_cmd
       end
     end
   end