From 303ffc868266400a518602d2e9e9285361029cb2 Mon Sep 17 00:00:00 2001 From: scott Chacon Date: Mon, 19 Nov 2007 07:14:20 -0800 Subject: changed logging to be far more efficient if you're accessing all the commit objects --- lib/git/lib.rb | 46 +++++++++++++++++++++++++++++++++++++++++----- lib/git/log.rb | 4 ++-- lib/git/object.rb | 21 ++++++++++++++++----- 3 files changed, 59 insertions(+), 12 deletions(-) (limited to 'lib/git') diff --git a/lib/git/lib.rb b/lib/git/lib.rb index 31cf164..0d44183 100644 --- a/lib/git/lib.rb +++ b/lib/git/lib.rb @@ -69,6 +69,18 @@ module Git command_lines('log', arr_opts, true).map { |l| l.split.first } end + def full_log_commits(opts = {}) + arr_opts = ['--pretty=raw'] + arr_opts << "-#{opts[:count]}" if opts[:count] + arr_opts << "--since=\"#{opts[:since]}\"" if opts[:since].is_a? String + arr_opts << "#{opts[:between][0].to_s}..#{opts[:between][1].to_s}" if (opts[:between] && opts[:between].size == 2) + arr_opts << opts[:object] if opts[:object].is_a? String + arr_opts << '-- ' + opts[:path_limiter] if opts[:path_limiter].is_a? String + + full_log = command_lines('log', arr_opts, true) + process_commit_data(full_log) + end + def revparse(string) command('rev-parse', string) end @@ -87,28 +99,52 @@ module Git # returns useful array of raw commit object data def commit_data(sha) + sha = sha.to_s + cdata = command_lines('cat-file', ['commit', sha]) + process_commit_data(cdata, sha) + end + + def process_commit_data(data, sha = nil) in_message = false - hsh = {'message' => '', 'parent' => []} - command_lines('cat-file', ['commit', sha.to_s]).each do |line| - if in_message + if sha + hsh = {'sha' => sha, 'message' => '', 'parent' => []} + else + hsh_array = [] + end + + data.each do |line| + if in_message && line != '' hsh['message'] += line + "\n" end - + if (line != '') && !in_message data = line.split key = data.shift value = data.join(' ') + if key == 'commit' + sha = value + hsh_array << hsh if hsh + hsh = {'sha' => sha, 'message' => '', 'parent' => []} + end if key == 'parent' hsh[key] << value else hsh[key] = value end + elsif in_message && line == '' + in_message = false else in_message = true end end - hsh + + if hsh_array + hsh_array << hsh if hsh + hsh_array + else + hsh + end end def object_contents(sha) diff --git a/lib/git/log.rb b/lib/git/log.rb index c91538d..9437ea6 100644 --- a/lib/git/log.rb +++ b/lib/git/log.rb @@ -84,9 +84,9 @@ module Git # actually run the 'git log' command def run_log - log = @base.lib.log_commits(:count => @count, :object => @object, + log = @base.lib.full_log_commits(:count => @count, :object => @object, :path_limiter => @path, :since => @since, :between => @between) - @commits = log.map { |l| Git::Object::Commit.new(@base, l) } + @commits = log.map { |c| Git::Object::Commit.new(@base, c['sha'], c) } end end diff --git a/lib/git/object.rb b/lib/git/object.rb index aeeae89..058053c 100644 --- a/lib/git/object.rb +++ b/lib/git/object.rb @@ -151,6 +151,13 @@ module Git @committer = nil @message = nil + def initialize(base, sha, init = nil) + super(base, sha) + if init + set_commit(init) + end + end + def message check_commit @message @@ -199,6 +206,14 @@ module Git def diff_parent diff(parent) end + + def set_commit(data) + @committer = Git::Author.new(data['committer']) + @author = Git::Author.new(data['author']) + @tree = Tree.new(@base, data['tree']) + @parents = data['parent'].map{ |sha| Commit.new(@base, sha) } + @message = data['message'].chomp + end private @@ -210,11 +225,7 @@ module Git def check_commit if !@tree data = @base.lib.commit_data(@objectish) - @committer = Git::Author.new(data['committer']) - @author = Git::Author.new(data['author']) - @tree = Tree.new(@base, data['tree']) - @parents = data['parent'].map{ |sha| Commit.new(@base, sha) } - @message = data['message'].chomp + set_commit(data) end end -- cgit