This commit is contained in:
Chris Wanstrath 2009-02-13 15:58:50 -08:00
Родитель ef447cf909
Коммит d76b71c087
2 изменённых файлов: 91 добавлений и 70 удалений

Просмотреть файл

@ -1,5 +1,5 @@
module Grit
class Commit
attr_reader :id
lazy_reader :parents
@ -11,7 +11,7 @@ module Grit
lazy_reader :message
lazy_reader :short_message
lazy_reader :author_string
# Instantiate a new Commit
# +id+ is the id of the commit
# +parents+ is an array of commit ids (will be converted into Commit instances)
@ -35,11 +35,11 @@ module Grit
@message = message.join("\n")
@short_message = message[0] || ''
end
def id_abbrev
@id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
end
# Create an unbaked Commit containing just the specified attributes
# +repo+ is the Repo
# +atts+ is a Hash of instance variable data
@ -48,7 +48,7 @@ module Grit
def self.create(repo, atts)
self.allocate.create_initialize(repo, atts)
end
# Initializer for Commit.create
# +repo+ is the Repo
# +atts+ is a Hash of instance variable data
@ -61,11 +61,11 @@ module Grit
end
self
end
def lazy_source
self.class.find_all(@repo, @id, {:max_count => 1}).first
end
# Count the number of commits reachable from this ref
# +repo+ is the Repo
# +ref+ is the ref from which to begin (SHA1 or name)
@ -74,7 +74,7 @@ module Grit
def self.count(repo, ref)
repo.git.rev_list({}, ref).size / 41
end
# Find all commits matching the given criteria.
# +repo+ is the Repo
# +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
@ -85,21 +85,21 @@ module Grit
# Returns Grit::Commit[] (baked)
def self.find_all(repo, ref, options = {})
allowed_options = [:max_count, :skip, :since]
default_options = {:pretty => "raw"}
actual_options = default_options.merge(options)
if ref
output = repo.git.rev_list(actual_options, ref)
else
output = repo.git.rev_list(actual_options.merge(:all => true))
end
self.list_from_string(repo, output)
rescue Grit::GitRuby::Repository::NoSuchShaFound
[]
end
# Parse out commit information into an array of baked Commit objects
# +repo+ is the Repo
# +text+ is the text output from the git command (raw format)
@ -111,40 +111,40 @@ module Grit
#
def self.list_from_string(repo, text)
lines = text.split("\n")
commits = []
while !lines.empty?
id = lines.shift.split.last
tree = lines.shift.split.last
parents = []
parents << lines.shift.split.last while lines.first =~ /^parent/
author, authored_date = self.actor(lines.shift)
committer, committed_date = self.actor(lines.shift)
# not doing anything with this yet, but it's sometimes there
encoding = lines.shift.split.last if lines.first =~ /^encoding/
lines.shift
message_lines = []
message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
lines.shift while lines.first && lines.first.empty?
commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
end
commits
end
# Show diffs between two trees:
# +repo+ is the Repo
# +a+ is a named commit
# +b+ is an optional named commit. Passing an array assumes you
# wish to omit the second named commit and limit the diff to the
# +b+ is an optional named commit. Passing an array assumes you
# wish to omit the second named commit and limit the diff to the
# given paths.
# +paths* is an array of paths to limit the diff.
#
@ -175,10 +175,10 @@ module Grit
if parents.empty?
show
else
self.class.diff(@repo, parents.first.id, @id)
self.class.diff(@repo, parents.first.id, @id)
end
end
# Convert this Commit to a String which is just the SHA1 id
def to_s
@id
@ -187,18 +187,22 @@ module Grit
def sha
@id
end
def date
@committed_date
end
def to_patch
@repo.git.format_patch({'1' => true, :stdout => true}, to_s)
end
# Pretty object inspection
def inspect
%Q{#<Grit::Commit "#{@id}">}
end
# private
# Parse out the actor (author or committer) info
#
# Returns [String (actor name and email), Time (acted at time)]
@ -206,11 +210,11 @@ module Grit
m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
[Actor.from_string(actor), Time.at(epoch.to_i)]
end
def author_string
"%s <%s> %s %+05d" % [author.name, author.email, authored_date.to_i, 800]
end
def to_hash
{
'id' => id,
@ -230,5 +234,5 @@ module Grit
}
end
end # Commit
end # Grit

Просмотреть файл

@ -4,40 +4,40 @@ class TestCommit < Test::Unit::TestCase
def setup
@r = Repo.new(File.join(File.dirname(__FILE__), *%w[dot_git]), :is_bare => true)
end
# __bake__
def test_bake
Git.any_instance.expects(:rev_list).returns(fixture('rev_list_single'))
@c = Commit.create(@r, :id => '4c8124ffcf4039d292442eeccabdeca5af5c5017')
@c.author # bake
assert_equal "Tom Preston-Werner", @c.author.name
assert_equal "tom@mojombo.com", @c.author.email
end
# short_name
def test_id_abbrev
assert_equal '80f136f', @r.commit('80f136f500dfdb8c3e8abf4ae716f875f0a1b57f').id_abbrev
end
# count
def test_count
assert_equal 107, Commit.count(@r, 'master')
end
# diff
def test_diff
# git diff --full-index 91169e1f5fa4de2eaea3f176461f5dc784796769 > test/fixtures/diff_p
Git.any_instance.expects(:diff).with({:full_index => true}, 'master').returns(fixture('diff_p'))
diffs = Commit.diff(@r, 'master')
assert_equal 15, diffs.size
assert_equal '.gitignore', diffs.first.a_path
assert_equal '.gitignore', diffs.first.b_path
assert_equal '4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs.first.a_commit.id
@ -46,36 +46,36 @@ class TestCommit < Test::Unit::TestCase
assert_equal false, diffs.first.new_file
assert_equal false, diffs.first.deleted_file
assert_equal "--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs.first.diff
assert_equal 'lib/grit/actor.rb', diffs[5].a_path
assert_equal nil, diffs[5].a_commit
assert_equal 'f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_commit.id
assert_equal true, diffs[5].new_file
end
def test_diff_with_two_commits
# git diff --full-index 59ddc32 13d27d5 > test/fixtures/diff_2
Git.any_instance.expects(:diff).with({:full_index => true}, '59ddc32', '13d27d5').returns(fixture('diff_2'))
diffs = Commit.diff(@r, '59ddc32', '13d27d5')
assert_equal 3, diffs.size
assert_equal %w(lib/grit/commit.rb test/fixtures/show_empty_commit test/test_commit.rb), diffs.collect { |d| d.a_path }
end
def test_diff_with_files
# git diff --full-index 59ddc32 -- lib > test/fixtures/diff_f
Git.any_instance.expects(:diff).with({:full_index => true}, '59ddc32', '--', 'lib').returns(fixture('diff_f'))
diffs = Commit.diff(@r, '59ddc32', %w(lib))
assert_equal 1, diffs.size
assert_equal 'lib/grit/diff.rb', diffs.first.a_path
end
def test_diff_with_two_commits_and_files
# git diff --full-index 59ddc32 13d27d5 -- lib > test/fixtures/diff_2f
Git.any_instance.expects(:diff).with({:full_index => true}, '59ddc32', '13d27d5', '--', 'lib').returns(fixture('diff_2f'))
diffs = Commit.diff(@r, '59ddc32', '13d27d5', %w(lib))
assert_equal 1, diffs.size
assert_equal 'lib/grit/commit.rb', diffs.first.a_path
end
@ -83,13 +83,13 @@ class TestCommit < Test::Unit::TestCase
# diffs
def test_diffs
# git diff --full-index 91169e1f5fa4de2eaea3f176461f5dc784796769 > test/fixtures/diff_p
Git.any_instance.expects(:diff).returns(fixture('diff_p'))
@c = Commit.create(@r, :id => '91169e1f5fa4de2eaea3f176461f5dc784796769')
diffs = @c.diffs
assert_equal 15, diffs.size
assert_equal '.gitignore', diffs.first.a_path
assert_equal '.gitignore', diffs.first.b_path
assert_equal '4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs.first.a_commit.id
@ -98,7 +98,7 @@ class TestCommit < Test::Unit::TestCase
assert_equal false, diffs.first.new_file
assert_equal false, diffs.first.deleted_file
assert_equal "--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs.first.diff
assert_equal 'lib/grit/actor.rb', diffs[5].a_path
assert_equal nil, diffs[5].a_commit
assert_equal 'f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_commit.id
@ -111,9 +111,9 @@ class TestCommit < Test::Unit::TestCase
Git.any_instance.expects(:show).with({:full_index => true, :pretty => 'raw'}, '634396b2f541a9f2d58b00be1a07f0c358b999b3').returns(fixture('diff_i'))
@c = Commit.create(@r, :id => '634396b2f541a9f2d58b00be1a07f0c358b999b3')
diffs = @c.diffs
assert_equal 10, diffs.size
assert_equal 'History.txt', diffs.first.a_path
assert_equal 'History.txt', diffs.first.b_path
assert_equal nil, diffs.first.a_commit
@ -123,44 +123,61 @@ class TestCommit < Test::Unit::TestCase
assert_equal false, diffs.first.deleted_file
assert_equal "--- /dev/null\n+++ b/History.txt\n@@ -0,0 +1,5 @@\n+== 1.0.0 / 2007-10-09\n+\n+* 1 major enhancement\n+ * Birthday!\n+", diffs.first.diff
assert_equal 'lib/grit.rb', diffs[5].a_path
assert_equal nil, diffs[5].a_commit
assert_equal '32cec87d1e78946a827ddf6a8776be4d81dcf1d1', diffs[5].b_commit.id
assert_equal true, diffs[5].new_file
end
def test_diffs_on_initial_import_with_empty_commit
Git.any_instance.expects(:show).with(
{:full_index => true, :pretty => 'raw'},
{:full_index => true, :pretty => 'raw'},
'634396b2f541a9f2d58b00be1a07f0c358b999b3'
).returns(fixture('show_empty_commit'))
@c = Commit.create(@r, :id => '634396b2f541a9f2d58b00be1a07f0c358b999b3')
diffs = @c.diffs
assert_equal [], diffs
end
def test_diffs_with_mode_only_change
Git.any_instance.expects(:diff).returns(fixture('diff_mode_only'))
@c = Commit.create(@r, :id => '91169e1f5fa4de2eaea3f176461f5dc784796769')
diffs = @c.diffs
assert_equal 23, diffs.size
assert_equal '100644', diffs[0].a_mode
assert_equal '100755', diffs[0].b_mode
end
# to_s
def test_to_s
@c = Commit.create(@r, :id => 'abc')
assert_equal "abc", @c.to_s
end
# to_patch
def test_to_patch
@c = Commit.create(@r, :id => '80f136f500dfdb8c3e8abf4ae716f875f0a1b57f')
patch = @c.to_patch
assert patch.include?('From 80f136f500dfdb8c3e8abf4ae716f875f0a1b57f Mon Sep 17 00:00:00 2001')
assert patch.include?('From: tom <tom@taco.(none)>')
assert patch.include?('Date: Tue, 20 Nov 2007 17:27:42 -0800')
assert patch.include?('Subject: [PATCH] fix tests on other machines')
assert patch.include?('test/test_reality.rb | 30 +++++++++++++++---------------')
assert patch.include?('@@ -1,17 +1,17 @@')
assert patch.include?('+# recurse(t)')
assert patch.include?('1.6.0')
end
# inspect
def test_inspect
@c = Commit.create(@r, :id => 'abc')
assert_equal %Q{#<Grit::Commit "abc">}, @c.inspect