pjhyett-grit 0.9.11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/History.txt +13 -0
  2. data/Manifest.txt +71 -0
  3. data/README.txt +213 -0
  4. data/Rakefile +29 -0
  5. data/grit.gemspec +62 -0
  6. data/lib/grit.rb +54 -0
  7. data/lib/grit/actor.rb +36 -0
  8. data/lib/grit/blob.rb +117 -0
  9. data/lib/grit/commit.rb +229 -0
  10. data/lib/grit/commit_stats.rb +104 -0
  11. data/lib/grit/config.rb +44 -0
  12. data/lib/grit/diff.rb +70 -0
  13. data/lib/grit/errors.rb +7 -0
  14. data/lib/grit/git-ruby.rb +184 -0
  15. data/lib/grit/git-ruby/commit_db.rb +52 -0
  16. data/lib/grit/git-ruby/file_index.rb +186 -0
  17. data/lib/grit/git-ruby/git_object.rb +344 -0
  18. data/lib/grit/git-ruby/internal/loose.rb +137 -0
  19. data/lib/grit/git-ruby/internal/mmap.rb +58 -0
  20. data/lib/grit/git-ruby/internal/pack.rb +382 -0
  21. data/lib/grit/git-ruby/internal/raw_object.rb +37 -0
  22. data/lib/grit/git-ruby/object.rb +319 -0
  23. data/lib/grit/git-ruby/repository.rb +731 -0
  24. data/lib/grit/git.rb +122 -0
  25. data/lib/grit/head.rb +83 -0
  26. data/lib/grit/index.rb +121 -0
  27. data/lib/grit/lazy.rb +33 -0
  28. data/lib/grit/ref.rb +95 -0
  29. data/lib/grit/repo.rb +387 -0
  30. data/lib/grit/status.rb +151 -0
  31. data/lib/grit/tag.rb +71 -0
  32. data/lib/grit/tree.rb +104 -0
  33. data/test/test_actor.rb +35 -0
  34. data/test/test_blob.rb +79 -0
  35. data/test/test_commit.rb +184 -0
  36. data/test/test_config.rb +58 -0
  37. data/test/test_diff.rb +18 -0
  38. data/test/test_git.rb +70 -0
  39. data/test/test_grit.rb +32 -0
  40. data/test/test_head.rb +47 -0
  41. data/test/test_real.rb +19 -0
  42. data/test/test_reality.rb +17 -0
  43. data/test/test_remote.rb +14 -0
  44. data/test/test_repo.rb +277 -0
  45. data/test/test_tag.rb +25 -0
  46. data/test/test_tree.rb +96 -0
  47. metadata +128 -0
data/lib/grit/tag.rb ADDED
@@ -0,0 +1,71 @@
1
+ module Grit
2
+
3
+ class Tag
4
+ attr_reader :name
5
+ attr_reader :commit
6
+
7
+ # Instantiate a new Tag
8
+ # +name+ is the name of the head
9
+ # +commit+ is the Commit that the head points to
10
+ #
11
+ # Returns Grit::Tag (baked)
12
+ def initialize(name, commit)
13
+ @name = name
14
+ @commit = commit
15
+ end
16
+
17
+ # Find all Tags
18
+ # +repo+ is the Repo
19
+ # +options+ is a Hash of options
20
+ #
21
+ # Returns Grit::Tag[] (baked)
22
+ def self.find_all(repo, options = {})
23
+ default_options = {:sort => "committerdate",
24
+ :format => "%(refname)%00%(objectname)"}
25
+
26
+ actual_options = default_options.merge(options)
27
+
28
+ output = repo.git.for_each_ref(actual_options, "refs/tags")
29
+
30
+ self.list_from_string(repo, output)
31
+ end
32
+
33
+ # Parse out tag information into an array of baked Tag objects
34
+ # +repo+ is the Repo
35
+ # +text+ is the text output from the git command
36
+ #
37
+ # Returns Grit::Tag[] (baked)
38
+ def self.list_from_string(repo, text)
39
+ tags = []
40
+
41
+ text.split("\n").each do |line|
42
+ tags << self.from_string(repo, line)
43
+ end
44
+
45
+ tags
46
+ end
47
+
48
+ # Create a new Tag instance from the given string.
49
+ # +repo+ is the Repo
50
+ # +line+ is the formatted tag information
51
+ #
52
+ # Format
53
+ # name: [a-zA-Z_/]+
54
+ # <null byte>
55
+ # id: [0-9A-Fa-f]{40}
56
+ #
57
+ # Returns Grit::Tag (baked)
58
+ def self.from_string(repo, line)
59
+ full_name, id = line.split("\0")
60
+ name = full_name.split("/").last
61
+ commit = Commit.create(repo, :id => id)
62
+ self.new(name, commit)
63
+ end
64
+
65
+ # Pretty object inspection
66
+ def inspect
67
+ %Q{#<Grit::Tag "#{@name}">}
68
+ end
69
+ end # Tag
70
+
71
+ end # Grit
data/lib/grit/tree.rb ADDED
@@ -0,0 +1,104 @@
1
+ module Grit
2
+
3
+ class Tree
4
+ lazy_reader :contents
5
+ attr_reader :id
6
+ attr_reader :mode
7
+ attr_reader :name
8
+
9
+ # Construct the contents of the tree
10
+ # +repo+ is the Repo
11
+ # +treeish+ is the reference
12
+ # +paths+ is an optional Array of directory paths to restrict the tree
13
+ #
14
+ # Returns Grit::Tree (baked)
15
+ def self.construct(repo, treeish, paths = [])
16
+ output = repo.git.ls_tree({}, treeish, *paths)
17
+ self.allocate.construct_initialize(repo, treeish, output)
18
+ end
19
+
20
+ def construct_initialize(repo, id, text)
21
+ @repo = repo
22
+ @id = id
23
+ @contents = []
24
+
25
+ text.split("\n").each do |line|
26
+ @contents << content_from_string(repo, line)
27
+ end
28
+ @contents.compact!
29
+
30
+ self
31
+ end
32
+
33
+ def lazy_source
34
+ Tree.construct(@repo, @id, [])
35
+ end
36
+
37
+ # Create an unbaked Tree containing just the specified attributes
38
+ # +repo+ is the Repo
39
+ # +atts+ is a Hash of instance variable data
40
+ #
41
+ # Returns Grit::Tree (unbaked)
42
+ def self.create(repo, atts)
43
+ self.allocate.create_initialize(repo, atts)
44
+ end
45
+
46
+ # Initializer for Tree.create
47
+ # +repo+ is the Repo
48
+ # +atts+ is a Hash of instance variable data
49
+ #
50
+ # Returns Grit::Tree (unbaked)
51
+ def create_initialize(repo, atts)
52
+ @repo = repo
53
+
54
+ atts.each do |k, v|
55
+ instance_variable_set("@#{k}", v)
56
+ end
57
+ self
58
+ end
59
+
60
+ # Parse a content item and create the appropriate object
61
+ # +repo+ is the Repo
62
+ # +text+ is the single line containing the items data in `git ls-tree` format
63
+ #
64
+ # Returns Grit::Blob or Grit::Tree
65
+ def content_from_string(repo, text)
66
+ mode, type, id, name = text.split(" ", 4)
67
+ case type
68
+ when "tree"
69
+ Tree.create(repo, :id => id, :mode => mode, :name => name)
70
+ when "blob"
71
+ Blob.create(repo, :id => id, :mode => mode, :name => name)
72
+ when "link"
73
+ Blob.create(repo, :id => id, :mode => mode, :name => name)
74
+ when "commit"
75
+ Submodule.create(repo, :id => id, :mode => mode, :name => name)
76
+ else
77
+ raise "Invalid type: #{type}"
78
+ end
79
+ end
80
+
81
+ # Find the named object in this tree's contents
82
+ #
83
+ # Examples
84
+ # Repo.new('/path/to/grit').tree/'lib'
85
+ # # => #<Grit::Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
86
+ # Repo.new('/path/to/grit').tree/'README.txt'
87
+ # # => #<Grit::Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
88
+ #
89
+ # Returns Grit::Blob or Grit::Tree or nil if not found
90
+ def /(file)
91
+ if file =~ /\//
92
+ file.split("/").inject(self) { |acc, x| acc/x } rescue nil
93
+ else
94
+ self.contents.find { |c| c.name == file }
95
+ end
96
+ end
97
+
98
+ # Pretty object inspection
99
+ def inspect
100
+ %Q{#<Grit::Tree "#{@id}">}
101
+ end
102
+ end # Tree
103
+
104
+ end # Grit
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestActor < Test::Unit::TestCase
4
+ def setup
5
+
6
+ end
7
+
8
+ # from_string
9
+
10
+ def test_from_string_should_separate_name_and_email
11
+ a = Actor.from_string("Tom Werner <tom@example.com>")
12
+ assert_equal "Tom Werner", a.name
13
+ assert_equal "tom@example.com", a.email
14
+ end
15
+
16
+ def test_from_string_should_handle_just_name
17
+ a = Actor.from_string("Tom Werner")
18
+ assert_equal "Tom Werner", a.name
19
+ assert_equal nil, a.email
20
+ end
21
+
22
+ # inspect
23
+
24
+ def test_inspect
25
+ a = Actor.from_string("Tom Werner <tom@example.com>")
26
+ assert_equal %Q{#<Grit::Actor "Tom Werner <tom@example.com>">}, a.inspect
27
+ end
28
+
29
+ # to_s
30
+
31
+ def test_to_s_should_alias_name
32
+ a = Actor.from_string("Tom Werner <tom@example.com>")
33
+ assert_equal a.name, a.to_s
34
+ end
35
+ end
data/test/test_blob.rb ADDED
@@ -0,0 +1,79 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestBlob < Test::Unit::TestCase
4
+ def setup
5
+ @r = Repo.new(GRIT_REPO)
6
+ @b = Blob.allocate
7
+ end
8
+
9
+ # blob
10
+ def test_nosuch_blob
11
+ t = @r.blob('blahblah')
12
+ puts t.data
13
+ assert t.is_a?(Blob)
14
+ end
15
+
16
+ def test_data_should_return_blob_contents
17
+ Git.any_instance.expects(:cat_file).returns(fixture('cat_file_blob'))
18
+ blob = Blob.create(@r, :id => 'abc')
19
+ assert_equal "Hello world", blob.data
20
+ end
21
+
22
+ def test_data_should_cache
23
+ Git.any_instance.expects(:cat_file).returns(fixture('cat_file_blob')).times(1)
24
+ blob = Blob.create(@r, :id => 'abc')
25
+ blob.data
26
+ blob.data
27
+ end
28
+
29
+ # size
30
+
31
+ def test_size_should_return_file_size
32
+ Git.any_instance.expects(:cat_file).returns(fixture('cat_file_blob_size'))
33
+ blob = Blob.create(@r, :id => 'abc')
34
+ assert_equal 11, blob.size
35
+ end
36
+
37
+ # data
38
+
39
+ # mime_type
40
+
41
+ def test_mime_type_should_return_mime_type_for_known_types
42
+ blob = Blob.create(@r, :id => 'abc', :name => 'foo.png')
43
+ assert_equal "image/png", blob.mime_type
44
+ end
45
+
46
+ def test_mime_type_should_return_text_plain_for_unknown_types
47
+ blob = Blob.create(@r, :id => 'abc')
48
+ assert_equal "text/plain", blob.mime_type
49
+ end
50
+
51
+ # blame
52
+
53
+ def test_blame
54
+ Git.any_instance.expects(:blame).returns(fixture('blame'))
55
+ b = Blob.blame(@r, 'master', 'lib/grit.rb')
56
+ assert_equal 13, b.size
57
+ assert_equal 25, b.inject(0) { |acc, x| acc + x.last.size }
58
+ assert_equal b[0].first.object_id, b[9].first.object_id
59
+ c = b.first.first
60
+ c.expects(:__bake__).times(0)
61
+ assert_equal '634396b2f541a9f2d58b00be1a07f0c358b999b3', c.id
62
+ assert_equal 'Tom Preston-Werner', c.author.name
63
+ assert_equal 'tom@mojombo.com', c.author.email
64
+ assert_equal Time.at(1191997100), c.authored_date
65
+ assert_equal 'Tom Preston-Werner', c.committer.name
66
+ assert_equal 'tom@mojombo.com', c.committer.email
67
+ assert_equal Time.at(1191997100), c.committed_date
68
+ assert_equal 'initial grit setup', c.message
69
+ # c.expects(:__bake__).times(1)
70
+ # assert_equal Tree, c.tree.class
71
+ end
72
+
73
+ # inspect
74
+
75
+ def test_inspect
76
+ @b = Blob.create(@r, :id => 'abc')
77
+ assert_equal %Q{#<Grit::Blob "abc">}, @b.inspect
78
+ end
79
+ end
@@ -0,0 +1,184 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class TestCommit < Test::Unit::TestCase
4
+ def setup
5
+ @r = Repo.new(File.join(File.dirname(__FILE__), *%w[dot_git]), :is_bare => true)
6
+ end
7
+
8
+ # __bake__
9
+
10
+ def test_bake
11
+ Git.any_instance.expects(:rev_list).returns(fixture('rev_list_single'))
12
+ @c = Commit.create(@r, :id => '4c8124ffcf4039d292442eeccabdeca5af5c5017')
13
+ @c.author # bake
14
+
15
+ assert_equal "Tom Preston-Werner", @c.author.name
16
+ assert_equal "tom@mojombo.com", @c.author.email
17
+ end
18
+
19
+ # short_name
20
+
21
+ def test_id_abbrev
22
+ assert_equal '80f136f', @r.commit('80f136f500dfdb8c3e8abf4ae716f875f0a1b57f').id_abbrev
23
+ end
24
+
25
+ # diff
26
+
27
+ def test_diff
28
+ # git diff --full-index 91169e1f5fa4de2eaea3f176461f5dc784796769 > test/fixtures/diff_p
29
+
30
+ Git.any_instance.expects(:diff).with({:full_index => true}, 'master').returns(fixture('diff_p'))
31
+ diffs = Commit.diff(@r, 'master')
32
+
33
+ assert_equal 15, diffs.size
34
+
35
+ assert_equal '.gitignore', diffs.first.a_path
36
+ assert_equal '.gitignore', diffs.first.b_path
37
+ assert_equal '4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs.first.a_commit.id
38
+ assert_equal '2dd02534615434d88c51307beb0f0092f21fd103', diffs.first.b_commit.id
39
+ assert_equal '100644', diffs.first.b_mode
40
+ assert_equal false, diffs.first.new_file
41
+ assert_equal false, diffs.first.deleted_file
42
+ assert_equal "--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs.first.diff
43
+
44
+ assert_equal 'lib/grit/actor.rb', diffs[5].a_path
45
+ assert_equal nil, diffs[5].a_commit
46
+ assert_equal 'f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_commit.id
47
+ assert_equal true, diffs[5].new_file
48
+ end
49
+
50
+ def test_diff_with_two_commits
51
+ # git diff --full-index 59ddc32 13d27d5 > test/fixtures/diff_2
52
+ Git.any_instance.expects(:diff).with({:full_index => true}, '59ddc32', '13d27d5').returns(fixture('diff_2'))
53
+ diffs = Commit.diff(@r, '59ddc32', '13d27d5')
54
+
55
+ assert_equal 3, diffs.size
56
+ assert_equal %w(lib/grit/commit.rb test/fixtures/show_empty_commit test/test_commit.rb), diffs.collect { |d| d.a_path }
57
+ end
58
+
59
+ def test_diff_with_files
60
+ # git diff --full-index 59ddc32 -- lib > test/fixtures/diff_f
61
+ Git.any_instance.expects(:diff).with({:full_index => true}, '59ddc32', '--', 'lib').returns(fixture('diff_f'))
62
+ diffs = Commit.diff(@r, '59ddc32', %w(lib))
63
+
64
+ assert_equal 1, diffs.size
65
+ assert_equal 'lib/grit/diff.rb', diffs.first.a_path
66
+ end
67
+
68
+ def test_diff_with_two_commits_and_files
69
+ # git diff --full-index 59ddc32 13d27d5 -- lib > test/fixtures/diff_2f
70
+ Git.any_instance.expects(:diff).with({:full_index => true}, '59ddc32', '13d27d5', '--', 'lib').returns(fixture('diff_2f'))
71
+ diffs = Commit.diff(@r, '59ddc32', '13d27d5', %w(lib))
72
+
73
+ assert_equal 1, diffs.size
74
+ assert_equal 'lib/grit/commit.rb', diffs.first.a_path
75
+ end
76
+
77
+ # diffs
78
+ def test_diffs
79
+ # git diff --full-index 91169e1f5fa4de2eaea3f176461f5dc784796769 > test/fixtures/diff_p
80
+
81
+ Git.any_instance.expects(:diff).returns(fixture('diff_p'))
82
+ @c = Commit.create(@r, :id => '91169e1f5fa4de2eaea3f176461f5dc784796769')
83
+ diffs = @c.diffs
84
+
85
+ assert_equal 15, diffs.size
86
+
87
+ assert_equal '.gitignore', diffs.first.a_path
88
+ assert_equal '.gitignore', diffs.first.b_path
89
+ assert_equal '4ebc8aea50e0a67e000ba29a30809d0a7b9b2666', diffs.first.a_commit.id
90
+ assert_equal '2dd02534615434d88c51307beb0f0092f21fd103', diffs.first.b_commit.id
91
+ assert_equal '100644', diffs.first.b_mode
92
+ assert_equal false, diffs.first.new_file
93
+ assert_equal false, diffs.first.deleted_file
94
+ assert_equal "--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs.first.diff
95
+
96
+ assert_equal 'lib/grit/actor.rb', diffs[5].a_path
97
+ assert_equal nil, diffs[5].a_commit
98
+ assert_equal 'f733bce6b57c0e5e353206e692b0e3105c2527f4', diffs[5].b_commit.id
99
+ assert_equal true, diffs[5].new_file
100
+ end
101
+
102
+ def test_diffs_on_initial_import
103
+ # git show --full-index 634396b2f541a9f2d58b00be1a07f0c358b999b3 > test/fixtures/diff_i
104
+
105
+ Git.any_instance.expects(:show).with({:full_index => true, :pretty => 'raw'}, '634396b2f541a9f2d58b00be1a07f0c358b999b3').returns(fixture('diff_i'))
106
+ @c = Commit.create(@r, :id => '634396b2f541a9f2d58b00be1a07f0c358b999b3')
107
+ diffs = @c.diffs
108
+
109
+ assert_equal 10, diffs.size
110
+
111
+ assert_equal 'History.txt', diffs.first.a_path
112
+ assert_equal 'History.txt', diffs.first.b_path
113
+ assert_equal nil, diffs.first.a_commit
114
+ assert_equal nil, diffs.first.b_mode
115
+ assert_equal '81d2c27608b352814cbe979a6acd678d30219678', diffs.first.b_commit.id
116
+ assert_equal true, diffs.first.new_file
117
+ assert_equal false, diffs.first.deleted_file
118
+ 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
119
+
120
+
121
+ assert_equal 'lib/grit.rb', diffs[5].a_path
122
+ assert_equal nil, diffs[5].a_commit
123
+ assert_equal '32cec87d1e78946a827ddf6a8776be4d81dcf1d1', diffs[5].b_commit.id
124
+ assert_equal true, diffs[5].new_file
125
+ end
126
+
127
+ def test_diffs_on_initial_import_with_empty_commit
128
+ Git.any_instance.expects(:show).with(
129
+ {:full_index => true, :pretty => 'raw'},
130
+ '634396b2f541a9f2d58b00be1a07f0c358b999b3'
131
+ ).returns(fixture('show_empty_commit'))
132
+
133
+ @c = Commit.create(@r, :id => '634396b2f541a9f2d58b00be1a07f0c358b999b3')
134
+ diffs = @c.diffs
135
+
136
+ assert_equal [], diffs
137
+ end
138
+
139
+ def test_diffs_with_mode_only_change
140
+ Git.any_instance.expects(:diff).returns(fixture('diff_mode_only'))
141
+ @c = Commit.create(@r, :id => '91169e1f5fa4de2eaea3f176461f5dc784796769')
142
+ diffs = @c.diffs
143
+
144
+ assert_equal 23, diffs.size
145
+ assert_equal '100644', diffs[0].a_mode
146
+ assert_equal '100755', diffs[0].b_mode
147
+ end
148
+
149
+ # to_s
150
+
151
+ def test_to_s
152
+ @c = Commit.create(@r, :id => 'abc')
153
+ assert_equal "abc", @c.to_s
154
+ end
155
+
156
+ # inspect
157
+
158
+ def test_inspect
159
+ @c = Commit.create(@r, :id => 'abc')
160
+ assert_equal %Q{#<Grit::Commit "abc">}, @c.inspect
161
+ end
162
+
163
+ # to_hash
164
+
165
+ def test_to_hash
166
+ old_tz, ENV["TZ"] = ENV["TZ"], "US/Pacific"
167
+ @c = Commit.create(@r, :id => '4c8124ffcf4039d292442eeccabdeca5af5c5017')
168
+ date = Time.parse('Wed Oct 10 03:06:12 -0400 2007')
169
+ expected = {
170
+ 'parents' => ['id' => "634396b2f541a9f2d58b00be1a07f0c358b999b3"],
171
+ 'committed_date' => date.xmlschema,
172
+ 'tree' => "672eca9b7f9e09c22dcb128c283e8c3c8d7697a4",
173
+ 'authored_date' => date.xmlschema,
174
+ 'committer' => {'email' => "tom@mojombo.com", 'name' => "Tom Preston-Werner"},
175
+ 'message' => "implement Grit#heads",
176
+ 'author' => {'email' => "tom@mojombo.com", 'name' => "Tom Preston-Werner"},
177
+ 'id' => "4c8124ffcf4039d292442eeccabdeca5af5c5017"
178
+ }
179
+
180
+ assert_equal expected, @c.to_hash
181
+ ensure
182
+ ENV["TZ"] = old_tz
183
+ end
184
+ end