3 class GitExecuteError < StandardError
13 if base.is_a?(Git::Base)
14 @git_dir = base.repo.path
15 @git_index_file = base.index.path
16 @git_work_dir = base.dir.path
17 elsif base.is_a?(Hash)
18 @git_dir = base[:repository]
19 @git_index_file = base[:index]
20 @git_work_dir = base[:working_directory]
28 def log_commits(opts = {})
29 arr_opts = ['--pretty=oneline']
30 arr_opts << "-#{opts[:count]}" if opts[:count]
31 arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String
32 arr_opts << "#{opts[:between][0]}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2)
33 arr_opts << opts[:object] if opts[:object].is_a? String
34 arr_opts << '-- ' + opts[:path_limiter] if opts[:path_limiter].is_a? String
36 command_lines('log', arr_opts).map { |l| l.split.first }
40 command('rev-parse', string)
44 command('cat-file', ['-t', sha])
48 command('cat-file', ['-s', sha]).to_i
51 def object_contents(sha)
52 command('cat-file', ['-p', sha])
57 command_lines('branch', '-a').each do |b|
59 current = true if b[0, 2] == '* '
60 arr << [b.gsub('* ', '').strip, current]
66 command('config', ['--get', name])
71 command_lines('config', ['--list']).each do |line|
72 (key, value) = line.split('=')
78 def config_remote(name)
80 command_lines('config', ['--get-regexp', "remote.#{name}"]).each do |line|
81 (key, value) = line.split
82 hsh[key.gsub("remote.#{name}.", '')] = value
88 # [tree-ish] = [[line_no, match], [line_no, match2]]
89 # [tree-ish] = [[line_no, match], [line_no, match2]]
90 def grep(string, opts = {})
91 opts[:object] = 'HEAD' if !opts[:object]
94 grep_opts << '-i' if opts[:ignore_case]
95 grep_opts << '-v' if opts[:invert_match]
96 grep_opts << "-e '#{string}'"
97 grep_opts << opts[:object] if opts[:object].is_a?(String)
98 grep_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
100 command_lines('grep', grep_opts).each do |line|
101 if m = /(.*)\:(\d+)\:(.*)/.match(line)
103 hsh[m[1]] << [m[2].to_i, m[3]]
109 def diff_full(obj1 = 'HEAD', obj2 = nil, opts = {})
112 diff_opts << obj2 if obj2.is_a?(String)
113 diff_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
115 command('diff', diff_opts)
118 def diff_stats(obj1 = 'HEAD', obj2 = nil, opts = {})
119 diff_opts = ['--numstat']
121 diff_opts << obj2 if obj2.is_a?(String)
122 diff_opts << ('-- ' + opts[:path_limiter]) if opts[:path_limiter].is_a? String
124 hsh = {:total => {:insertions => 0, :deletions => 0, :lines => 0, :files => 0}, :files => {}}
126 command_lines('diff', diff_opts).each do |file|
127 (insertions, deletions, filename) = file.split("\t")
128 hsh[:total][:insertions] += insertions.to_i
129 hsh[:total][:deletions] += deletions.to_i
130 hsh[:total][:lines] = (hsh[:total][:deletions] + hsh[:total][:insertions])
131 hsh[:total][:files] += 1
132 hsh[:files][filename] = {:insertions => insertions.to_i, :deletions => deletions.to_i}
140 def command_lines(cmd, opts)
141 command(cmd, opts).split("\n")
144 def command(cmd, opts = {})
145 ENV['GIT_DIR'] = @git_dir
146 ENV['GIT_INDEX_FILE'] = @git_index_file if @git_index_file
147 ENV['GIT_WORK_DIR'] = @git_work_dir if @git_work_dir
148 Dir.chdir(@git_work_dir || @git_dir) do
149 opts = opts.to_a.join(' ')
150 #puts "git #{cmd} #{opts}"
151 out = `git #{cmd} #{opts} 2>&1`.chomp
154 raise Git::GitExecuteError.new(out)