From 852a0e63d294de874c3311f5e7edf40e2f2ecd60 Mon Sep 17 00:00:00 2001 From: scott Chacon Date: Mon, 12 Nov 2007 17:29:39 -0800 Subject: added a bunch of good stuff to the commit object --- README | 13 +++++++++ Rakefile | 2 +- TODO | 22 +-------------- lib/git.rb | 8 +----- lib/git/author.rb | 14 ++++++++++ lib/git/lib.rb | 26 ++++++++++++++++++ lib/git/object.rb | 67 +++++++++++++++++++++++++++++++++++++++++++++- tests/units/test_lib.rb | 8 ++++++ tests/units/test_object.rb | 12 +++++++++ 9 files changed, 142 insertions(+), 30 deletions(-) create mode 100644 lib/git/author.rb diff --git a/README b/README index 624707f..36fcba9 100644 --- a/README +++ b/README @@ -55,6 +55,19 @@ Here are the operations that need read permission only. g.gblob(treeish) g.gcommit(treeish) + + commit = g.gcommit('1cc8667014381') + commit.gtree + commit.parent.sha + commit.parents.size + commit.author.name + commit.author.email + commit.author.date.strftime("%m-%d-%y") + commit.committer.name + commit.date.strftime("%m-%d-%y") + commit.message + + g.revparse('v2.5:Makefile') g.branches # returns Git::Branch objects diff --git a/Rakefile b/Rakefile index 323fac1..0d5574a 100644 --- a/Rakefile +++ b/Rakefile @@ -5,7 +5,7 @@ require 'rake/gempackagetask' spec = Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = "git" - s.version = "1.0.1" + s.version = "1.0.2" s.author = "Scott Chacon" s.email = "schacon@gmail.com" s.summary = "A package for using Git in Ruby code." diff --git a/TODO b/TODO index 883ec7e..839b29a 100644 --- a/TODO +++ b/TODO @@ -2,33 +2,13 @@ * Git::Object methods - tree recursion - commit information - - Git::Object - - sha - - type - - cat_file - - raw - - Git::Commit - - tree - - parent - - author # git author - - author_date - - committer # git author - - committer_date / date - - message Git::Tree - children - blobs/files - subtrees/subdirs - - Git::Blob << File - - size - - permissions - -* pushing + * More Error Examples * More Git::Status methods diff --git a/lib/git.rb b/lib/git.rb index 1452427..7dfbd40 100644 --- a/lib/git.rb +++ b/lib/git.rb @@ -21,17 +21,11 @@ require 'git/remote' require 'git/diff' require 'git/status' -=begin require 'git/author' -require 'git/file' - -require 'git/sha' -require 'git/ref' -=end module Git - VERSION = '1.0.1' + VERSION = '1.0.2' def self.bare(git_dir) Base.bare(git_dir) diff --git a/lib/git/author.rb b/lib/git/author.rb new file mode 100644 index 0000000..545abb9 --- /dev/null +++ b/lib/git/author.rb @@ -0,0 +1,14 @@ +module Git + class Author + attr_accessor :name, :email, :date + + def initialize(author_string) + if m = /(.*?) <(.*?)> (\d+) (.*)/.match(author_string) + @name = m[1] + @email = m[2] + @date = Time.at(m[3].to_i) + end + end + + end +end \ No newline at end of file diff --git a/lib/git/lib.rb b/lib/git/lib.rb index 575f0d7..13a3b4c 100644 --- a/lib/git/lib.rb +++ b/lib/git/lib.rb @@ -79,6 +79,32 @@ module Git command('cat-file', ['-s', sha]).to_i end + # returns useful array of raw commit object data + def commit_data(sha) + in_message = false + + hsh = {'message' => '', 'parent' => []} + command_lines('cat-file', ['commit', sha.to_s]).each do |line| + if in_message + hsh['message'] += line + "\n" + end + + if (line != '') && !in_message + data = line.split + key = data.shift + value = data.join(' ') + if key == 'parent' + hsh[key] << value + else + hsh[key] = value + end + else + in_message = true + end + end + hsh + end + def object_contents(sha) command('cat-file', ['-p', sha]) end diff --git a/lib/git/object.rb b/lib/git/object.rb index a7d7c17..58ea7ab 100644 --- a/lib/git/object.rb +++ b/lib/git/object.rb @@ -12,7 +12,7 @@ module Git def initialize(base, sha) @base = base - @sha = sha + @sha = sha.to_s @size = @base.lib.object_size(@sha) setup end @@ -63,9 +63,74 @@ module Git end class Commit < AbstractObject + + @tree = nil + @parents = nil + @author = nil + @committer = nil + @message = nil + def setup @type = 'commit' end + + def message + check_commit + @message + end + + def gtree + check_commit + Tree.new(@base, @tree) + end + + def parent + parents.first + end + + # array of all parent commits + def parents + check_commit + @parents + end + + # git author + def author + check_commit + @author + end + + def author_date + author.date + end + + # git author + def committer + check_commit + @committer + end + + def committer_date + committer.date + end + alias_method :date, :committer_date + + def diff_parent + diff(parent) + end + + private + + # see if this object has been initialized and do so if not + def check_commit + data = @base.lib.commit_data(@sha) + @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 + end class Tag < AbstractObject diff --git a/tests/units/test_lib.rb b/tests/units/test_lib.rb index 5fbd896..5afb4ec 100644 --- a/tests/units/test_lib.rb +++ b/tests/units/test_lib.rb @@ -13,6 +13,14 @@ class TestLib < Test::Unit::TestCase set_file_paths @lib = Git.open(@wdir).lib end + + def test_commit_data + data = @lib.commit_data('1cc8667014381') + assert_equal('scott Chacon 1194561188 -0800', data['author']) + assert_equal('94c827875e2cadb8bc8d4cdd900f19aa9e8634c7', data['tree']) + assert_equal("test\n", data['message']) + assert_equal(["546bec6f8872efa41d5d97a369f669165ecda0de"], data['parent']) + end # takes parameters, returns array of appropriate commit objects # :count diff --git a/tests/units/test_object.rb b/tests/units/test_object.rb index a8c6bce..c4a2de7 100644 --- a/tests/units/test_object.rb +++ b/tests/units/test_object.rb @@ -16,6 +16,18 @@ class TestObject < Test::Unit::TestCase o = @git.object('1cc8667014381') assert(o.is_a?(Git::Object::Commit)) + assert_equal('94c827875e2cadb8bc8d4cdd900f19aa9e8634c7', o.gtree.to_s) + assert_equal('546bec6f8872efa41d5d97a369f669165ecda0de', o.parent.sha) + assert_equal(1, o.parents.size) + assert_equal('scott Chacon', o.author.name) + assert_equal('schacon@agadorsparticus.corp.reactrix.com', o.author.email) + assert_equal('11-08-07', o.author.date.strftime("%m-%d-%y")) + assert_equal('11-08-07', o.author_date.strftime("%m-%d-%y")) + assert_equal('scott Chacon', o.committer.name) + assert_equal('11-08-07', o.committer_date.strftime("%m-%d-%y")) + assert_equal('11-08-07', o.date.strftime("%m-%d-%y")) + assert_equal('test', o.message) + o = @git.object('HEAD') assert(o.is_a?(Git::Object::Commit)) assert_equal('commit', o.type) -- cgit