grit 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grit might be problematic. Click here for more details.
- data/History.txt +5 -0
- data/Manifest.txt +36 -0
- data/README.txt +201 -0
- data/Rakefile +24 -0
- data/lib/grit.rb +31 -0
- data/lib/grit/actor.rb +36 -0
- data/lib/grit/blob.rb +117 -0
- data/lib/grit/commit.rb +169 -0
- data/lib/grit/diff.rb +57 -0
- data/lib/grit/errors.rb +7 -0
- data/lib/grit/git.rb +64 -0
- data/lib/grit/head.rb +79 -0
- data/lib/grit/lazy.rb +53 -0
- data/lib/grit/repo.rb +185 -0
- data/lib/grit/tree.rb +109 -0
- data/test/fixtures/blame +131 -0
- data/test/fixtures/cat_file_blob +1 -0
- data/test/fixtures/cat_file_blob_size +1 -0
- data/test/fixtures/diff_p +610 -0
- data/test/fixtures/for_each_ref +0 -0
- data/test/fixtures/ls_tree_a +7 -0
- data/test/fixtures/ls_tree_b +2 -0
- data/test/fixtures/rev_list +24 -0
- data/test/fixtures/rev_list_single +7 -0
- data/test/fixtures/rev_parse +1 -0
- data/test/helper.rb +13 -0
- data/test/profile.rb +21 -0
- data/test/suite.rb +6 -0
- data/test/test_actor.rb +35 -0
- data/test/test_blob.rb +74 -0
- data/test/test_commit.rb +64 -0
- data/test/test_git.rb +21 -0
- data/test/test_head.rb +17 -0
- data/test/test_reality.rb +17 -0
- data/test/test_repo.rb +167 -0
- data/test/test_tree.rb +61 -0
- metadata +99 -0
data/lib/grit/tree.rb
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class Tree
|
4
|
+
include Lazy
|
5
|
+
|
6
|
+
lazy_reader :contents
|
7
|
+
attr_reader :id
|
8
|
+
attr_reader :mode
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@contents = nil
|
13
|
+
@__baked__ = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# Construct the contents of the tree
|
17
|
+
# +repo+ is the Repo
|
18
|
+
# +treeish+ is the reference
|
19
|
+
# +paths+ is an optional Array of directory paths to restrict the tree
|
20
|
+
#
|
21
|
+
# Returns Grit::Tree (baked)
|
22
|
+
def self.construct(repo, treeish, paths = [])
|
23
|
+
output = repo.git.ls_tree({}, treeish, paths.join(" "))
|
24
|
+
|
25
|
+
self.allocate.construct_initialize(repo, treeish, output)
|
26
|
+
end
|
27
|
+
|
28
|
+
def construct_initialize(repo, id, text)
|
29
|
+
@repo = repo
|
30
|
+
@id = id
|
31
|
+
@contents = []
|
32
|
+
@__baked__ = nil
|
33
|
+
|
34
|
+
text.split("\n").each do |line|
|
35
|
+
@contents << content_from_string(repo, line)
|
36
|
+
end
|
37
|
+
__baked__
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def __bake__
|
42
|
+
temp = Tree.construct(@repo, @id, [])
|
43
|
+
@contents = temp.contents
|
44
|
+
end
|
45
|
+
|
46
|
+
# Create an unbaked Tree containing just the specified attributes
|
47
|
+
# +repo+ is the Repo
|
48
|
+
# +atts+ is a Hash of instance variable data
|
49
|
+
#
|
50
|
+
# Returns Grit::Tree (unbaked)
|
51
|
+
def self.create(repo, atts)
|
52
|
+
self.allocate.create_initialize(repo, atts)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Initializer for Tree.create
|
56
|
+
# +repo+ is the Repo
|
57
|
+
# +atts+ is a Hash of instance variable data
|
58
|
+
#
|
59
|
+
# Returns Grit::Tree (unbaked)
|
60
|
+
def create_initialize(repo, atts)
|
61
|
+
@repo = repo
|
62
|
+
@contents = nil
|
63
|
+
@__baked__ = nil
|
64
|
+
|
65
|
+
atts.each do |k, v|
|
66
|
+
instance_variable_set("@#{k}".to_sym, v)
|
67
|
+
end
|
68
|
+
self
|
69
|
+
end
|
70
|
+
|
71
|
+
# Parse a content item and create the appropriate object
|
72
|
+
# +repo+ is the Repo
|
73
|
+
# +text+ is the single line containing the items data in `git ls-tree` format
|
74
|
+
#
|
75
|
+
# Returns Grit::Blob or Grit::Tree
|
76
|
+
def content_from_string(repo, text)
|
77
|
+
mode, type, id, name = text.split(" ", 4)
|
78
|
+
case type
|
79
|
+
when "tree"
|
80
|
+
Tree.create(repo, :id => id, :mode => mode, :name => name)
|
81
|
+
when "blob"
|
82
|
+
Blob.create(repo, :id => id, :mode => mode, :name => name)
|
83
|
+
when "commit"
|
84
|
+
nil
|
85
|
+
else
|
86
|
+
raise "Invalid type: #{type}"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Find the named object in this tree's contents
|
91
|
+
#
|
92
|
+
# Examples
|
93
|
+
# Repo.new('/path/to/grit').tree/'lib'
|
94
|
+
# # => #<Grit::Tree "6cc23ee138be09ff8c28b07162720018b244e95e">
|
95
|
+
# Repo.new('/path/to/grit').tree/'README.txt'
|
96
|
+
# # => #<Grit::Blob "8b1e02c0fb554eed2ce2ef737a68bb369d7527df">
|
97
|
+
#
|
98
|
+
# Returns Grit::Blob or Grit::Tree or nil if not found
|
99
|
+
def /(file)
|
100
|
+
self.contents.select { |c| c.name == file }.first
|
101
|
+
end
|
102
|
+
|
103
|
+
# Pretty object inspection
|
104
|
+
def inspect
|
105
|
+
%Q{#<Grit::Tree "#{@id}">}
|
106
|
+
end
|
107
|
+
end # Tree
|
108
|
+
|
109
|
+
end # Grit
|
data/test/fixtures/blame
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 1 1 7
|
2
|
+
author Tom Preston-Werner
|
3
|
+
author-mail <tom@mojombo.com>
|
4
|
+
author-time 1191997100
|
5
|
+
author-tz -0700
|
6
|
+
committer Tom Preston-Werner
|
7
|
+
committer-mail <tom@mojombo.com>
|
8
|
+
committer-time 1191997100
|
9
|
+
committer-tz -0700
|
10
|
+
filename lib/grit.rb
|
11
|
+
summary initial grit setup
|
12
|
+
boundary
|
13
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
14
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 2 2
|
15
|
+
|
16
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 3 3
|
17
|
+
# core
|
18
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 4 4
|
19
|
+
|
20
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 5 5
|
21
|
+
# stdlib
|
22
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 6 6
|
23
|
+
|
24
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 7 7
|
25
|
+
# internal requires
|
26
|
+
3b1930208a82457747d76729ae088e90edca4673 8 8 1
|
27
|
+
author Tom Preston-Werner
|
28
|
+
author-mail <tom@mojombo.com>
|
29
|
+
author-time 1192267241
|
30
|
+
author-tz -0700
|
31
|
+
committer Tom Preston-Werner
|
32
|
+
committer-mail <tom@mojombo.com>
|
33
|
+
committer-time 1192267241
|
34
|
+
committer-tz -0700
|
35
|
+
filename lib/grit.rb
|
36
|
+
summary big refactor to do lazy loading
|
37
|
+
require 'grit/lazy'
|
38
|
+
4c8124ffcf4039d292442eeccabdeca5af5c5017 8 9 1
|
39
|
+
author Tom Preston-Werner
|
40
|
+
author-mail <tom@mojombo.com>
|
41
|
+
author-time 1191999972
|
42
|
+
author-tz -0700
|
43
|
+
committer Tom Preston-Werner
|
44
|
+
committer-mail <tom@mojombo.com>
|
45
|
+
committer-time 1191999972
|
46
|
+
committer-tz -0700
|
47
|
+
filename lib/grit.rb
|
48
|
+
summary implement Grit#heads
|
49
|
+
require 'grit/errors'
|
50
|
+
d01a4cfad6ea50285c4710243e3cbe019d381eba 9 10 1
|
51
|
+
author Tom Preston-Werner
|
52
|
+
author-mail <tom@mojombo.com>
|
53
|
+
author-time 1192032303
|
54
|
+
author-tz -0700
|
55
|
+
committer Tom Preston-Werner
|
56
|
+
committer-mail <tom@mojombo.com>
|
57
|
+
committer-time 1192032303
|
58
|
+
committer-tz -0700
|
59
|
+
filename lib/grit.rb
|
60
|
+
summary convert to Grit module, refactor to be more OO
|
61
|
+
require 'grit/git'
|
62
|
+
4c8124ffcf4039d292442eeccabdeca5af5c5017 9 11 1
|
63
|
+
require 'grit/head'
|
64
|
+
a47fd41f3aa4610ea527dcc1669dfdb9c15c5425 10 12 1
|
65
|
+
author Tom Preston-Werner
|
66
|
+
author-mail <tom@mojombo.com>
|
67
|
+
author-time 1192002639
|
68
|
+
author-tz -0700
|
69
|
+
committer Tom Preston-Werner
|
70
|
+
committer-mail <tom@mojombo.com>
|
71
|
+
committer-time 1192002639
|
72
|
+
committer-tz -0700
|
73
|
+
filename lib/grit.rb
|
74
|
+
summary add more comments throughout
|
75
|
+
require 'grit/commit'
|
76
|
+
b17b974691f0a26f26908495d24d9c4c718920f8 13 13 1
|
77
|
+
author Tom Preston-Werner
|
78
|
+
author-mail <tom@mojombo.com>
|
79
|
+
author-time 1192271832
|
80
|
+
author-tz -0700
|
81
|
+
committer Tom Preston-Werner
|
82
|
+
committer-mail <tom@mojombo.com>
|
83
|
+
committer-time 1192271832
|
84
|
+
committer-tz -0700
|
85
|
+
filename lib/grit.rb
|
86
|
+
summary started implementing Tree
|
87
|
+
require 'grit/tree'
|
88
|
+
74fd66519e983a0f29e16a342a6059dbffe36020 14 14 1
|
89
|
+
author Tom Preston-Werner
|
90
|
+
author-mail <tom@mojombo.com>
|
91
|
+
author-time 1192317005
|
92
|
+
author-tz -0700
|
93
|
+
committer Tom Preston-Werner
|
94
|
+
committer-mail <tom@mojombo.com>
|
95
|
+
committer-time 1192317005
|
96
|
+
committer-tz -0700
|
97
|
+
filename lib/grit.rb
|
98
|
+
summary add Blob
|
99
|
+
require 'grit/blob'
|
100
|
+
d01a4cfad6ea50285c4710243e3cbe019d381eba 12 15 1
|
101
|
+
require 'grit/repo'
|
102
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 9 16 1
|
103
|
+
|
104
|
+
d01a4cfad6ea50285c4710243e3cbe019d381eba 14 17 1
|
105
|
+
module Grit
|
106
|
+
b6e1b765e0c15586a2c5b9832854f95defd71e1f 18 18 6
|
107
|
+
author Tom Preston-Werner
|
108
|
+
author-mail <tom@mojombo.com>
|
109
|
+
author-time 1192860483
|
110
|
+
author-tz -0700
|
111
|
+
committer Tom Preston-Werner
|
112
|
+
committer-mail <tom@mojombo.com>
|
113
|
+
committer-time 1192860483
|
114
|
+
committer-tz -0700
|
115
|
+
filename lib/grit.rb
|
116
|
+
summary implement Repo.init_bare
|
117
|
+
class << self
|
118
|
+
b6e1b765e0c15586a2c5b9832854f95defd71e1f 19 19
|
119
|
+
attr_accessor :debug
|
120
|
+
b6e1b765e0c15586a2c5b9832854f95defd71e1f 20 20
|
121
|
+
end
|
122
|
+
b6e1b765e0c15586a2c5b9832854f95defd71e1f 21 21
|
123
|
+
|
124
|
+
b6e1b765e0c15586a2c5b9832854f95defd71e1f 22 22
|
125
|
+
self.debug = false
|
126
|
+
b6e1b765e0c15586a2c5b9832854f95defd71e1f 23 23
|
127
|
+
|
128
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 11 24 2
|
129
|
+
VERSION = '1.0.0'
|
130
|
+
634396b2f541a9f2d58b00be1a07f0c358b999b3 12 25
|
131
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello world
|
@@ -0,0 +1 @@
|
|
1
|
+
11
|
@@ -0,0 +1,610 @@
|
|
1
|
+
diff --git a/.gitignore b/.gitignore
|
2
|
+
index 4ebc8aea50e0a67e000ba29a30809d0a7b9b2666..2dd02534615434d88c51307beb0f0092f21fd103 100644
|
3
|
+
--- a/.gitignore
|
4
|
+
+++ b/.gitignore
|
5
|
+
@@ -1 +1,2 @@
|
6
|
+
coverage
|
7
|
+
+pkg
|
8
|
+
diff --git a/Manifest.txt b/Manifest.txt
|
9
|
+
index 641972d82c6d1b51122274ae8f6a0ecdfb56ee22..38bf80c54a526e76d74820a0f48606fe1ca7b1be 100644
|
10
|
+
--- a/Manifest.txt
|
11
|
+
+++ b/Manifest.txt
|
12
|
+
@@ -4,4 +4,31 @@ README.txt
|
13
|
+
Rakefile
|
14
|
+
bin/grit
|
15
|
+
lib/grit.rb
|
16
|
+
-test/test_grit.rb
|
17
|
+
|
18
|
+
+lib/grit/actor.rb
|
19
|
+
+lib/grit/blob.rb
|
20
|
+
+lib/grit/commit.rb
|
21
|
+
+lib/grit/errors.rb
|
22
|
+
+lib/grit/git.rb
|
23
|
+
+lib/grit/head.rb
|
24
|
+
+lib/grit/lazy.rb
|
25
|
+
+lib/grit/repo.rb
|
26
|
+
+lib/grit/tree.rb
|
27
|
+
+test/fixtures/blame
|
28
|
+
+test/fixtures/cat_file_blob
|
29
|
+
+test/fixtures/cat_file_blob_size
|
30
|
+
+test/fixtures/for_each_ref
|
31
|
+
+test/fixtures/ls_tree_a
|
32
|
+
+test/fixtures/ls_tree_b
|
33
|
+
+test/fixtures/rev_list
|
34
|
+
+test/fixtures/rev_list_single
|
35
|
+
+test/helper.rb
|
36
|
+
+test/profile.rb
|
37
|
+
+test/suite.rb
|
38
|
+
+test/test_actor.rb
|
39
|
+
+test/test_blob.rb
|
40
|
+
+test/test_commit.rb
|
41
|
+
+test/test_git.rb
|
42
|
+
+test/test_head.rb
|
43
|
+
+test/test_reality.rb
|
44
|
+
+test/test_repo.rb
|
45
|
+
+test/test_tree.rb
|
46
|
+
diff --git a/README.txt b/README.txt
|
47
|
+
index 8b1e02c0fb554eed2ce2ef737a68bb369d7527df..fca94f84afd7d749c62626011f972a509f6a5ac6 100644
|
48
|
+
--- a/README.txt
|
49
|
+
+++ b/README.txt
|
50
|
+
@@ -1,32 +1,185 @@
|
51
|
+
grit
|
52
|
+
- by FIX (your name)
|
53
|
+
- FIX (url)
|
54
|
+
+ by Tom Preston-Werner
|
55
|
+
+ grit.rubyforge.org
|
56
|
+
|
57
|
+
== DESCRIPTION:
|
58
|
+
+
|
59
|
+
+Grit is a Ruby library for extracting information from a git repository in and
|
60
|
+
+object oriented manner.
|
61
|
+
+
|
62
|
+
+== REQUIREMENTS:
|
63
|
+
+
|
64
|
+
+* git (http://git.or.cz) tested with 1.5.3.4
|
65
|
+
+
|
66
|
+
+== INSTALL:
|
67
|
+
+
|
68
|
+
+sudo gem install grit
|
69
|
+
+
|
70
|
+
+== USAGE:
|
71
|
+
+
|
72
|
+
+Grit gives you object model access to your git repository. Once you have
|
73
|
+
+created a repository object, you can traverse it to find parent commit(s),
|
74
|
+
+trees, blobs, etc.
|
75
|
+
+
|
76
|
+
+= Initialize a Repo object
|
77
|
+
+
|
78
|
+
+The first step is to create a Grit::Repo object to represent your repo. I
|
79
|
+
+include the Grit module so reduce typing.
|
80
|
+
+
|
81
|
+
+ include Grit
|
82
|
+
+ repo = Repo.new("/Users/tom/dev/grit")
|
83
|
+
|
84
|
+
-FIX (describe your package)
|
85
|
+
+In the above example, the directory /Users/tom/dev/grit is my working
|
86
|
+
+repo and contains the .git directory. You can also initialize Grit with a
|
87
|
+
+bare repo.
|
88
|
+
|
89
|
+
-== FEATURES/PROBLEMS:
|
90
|
+
+ repo = Repo.new("/var/git/grit.git")
|
91
|
+
|
92
|
+
-* FIX (list of features or problems)
|
93
|
+
+= Getting a list of commits
|
94
|
+
|
95
|
+
-== SYNOPSIS:
|
96
|
+
+From the Repo object, you can get a list of commits as an array of Commit
|
97
|
+
+objects.
|
98
|
+
|
99
|
+
- FIX (code sample of usage)
|
100
|
+
+ repo.commits
|
101
|
+
+ # => [#<Grit::Commit "e80bbd2ce67651aa18e57fb0b43618ad4baf7750">,
|
102
|
+
+ #<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">,
|
103
|
+
+ #<Grit::Commit "038af8c329ef7c1bae4568b98bd5c58510465493">,
|
104
|
+
+ #<Grit::Commit "40d3057d09a7a4d61059bca9dca5ae698de58cbe">,
|
105
|
+
+ #<Grit::Commit "4ea50f4754937bf19461af58ce3b3d24c77311d9">]
|
106
|
+
+
|
107
|
+
+Called without arguments, Repo#commits returns a list of up to ten commits
|
108
|
+
+reachable by the master branch (starting at the latest commit). You can ask
|
109
|
+
+for commits beginning at a different branch, commit, tag, etc.
|
110
|
+
|
111
|
+
-== REQUIREMENTS:
|
112
|
+
+ repo.commits('mybranch')
|
113
|
+
+ repo.commits('40d3057d09a7a4d61059bca9dca5ae698de58cbe')
|
114
|
+
+ repo.commits('v0.1')
|
115
|
+
+
|
116
|
+
+You can specify the maximum number of commits to return.
|
117
|
+
|
118
|
+
-* FIX (list of requirements)
|
119
|
+
+ repo.commits('master', 100)
|
120
|
+
+
|
121
|
+
+If you need paging, you can specify a number of commits to skip.
|
122
|
+
|
123
|
+
-== INSTALL:
|
124
|
+
+ repo.commits('master', 10, 20)
|
125
|
+
+
|
126
|
+
+The above will return commits 21-30 from the commit list.
|
127
|
+
+
|
128
|
+
+= The Commit object
|
129
|
+
+
|
130
|
+
+Commit objects contain information about that commit.
|
131
|
+
+
|
132
|
+
+ head = repo.commits.first
|
133
|
+
+
|
134
|
+
+ head.id
|
135
|
+
+ # => "e80bbd2ce67651aa18e57fb0b43618ad4baf7750"
|
136
|
+
+
|
137
|
+
+ head.parents
|
138
|
+
+ # => [#<Grit::Commit "91169e1f5fa4de2eaea3f176461f5dc784796769">]
|
139
|
+
+
|
140
|
+
+ head.tree
|
141
|
+
+ # => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
|
142
|
+
+
|
143
|
+
+ head.author
|
144
|
+
+ # => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
|
145
|
+
+
|
146
|
+
+ head.authored_date
|
147
|
+
+ # => Wed Oct 24 22:02:31 -0700 2007
|
148
|
+
+
|
149
|
+
+ head.committer
|
150
|
+
+ # => #<Grit::Actor "Tom Preston-Werner <tom@mojombo.com>">
|
151
|
+
+
|
152
|
+
+ head.committed_date
|
153
|
+
+ # => Wed Oct 24 22:02:31 -0700 2007
|
154
|
+
+
|
155
|
+
+ head.message
|
156
|
+
+ # => "add Actor inspect"
|
157
|
+
+
|
158
|
+
+You can traverse a commit's ancestry by chaining calls to #parents.
|
159
|
+
+
|
160
|
+
+ repo.commits.first.parents[0].parents[0].parents[0]
|
161
|
+
+
|
162
|
+
+The above corresponds to master^^^ or master~3 in git parlance.
|
163
|
+
+
|
164
|
+
+= The Tree object
|
165
|
+
+
|
166
|
+
+A tree records pointers to the contents of a directory. Let's say you want
|
167
|
+
+the root tree of the latest commit on the master branch.
|
168
|
+
+
|
169
|
+
+ tree = repo.commits.first.tree
|
170
|
+
+ # => #<Grit::Tree "3536eb9abac69c3e4db583ad38f3d30f8db4771f">
|
171
|
+
+
|
172
|
+
+ tree.id
|
173
|
+
+ # => "3536eb9abac69c3e4db583ad38f3d30f8db4771f"
|
174
|
+
+
|
175
|
+
+Once you have a tree, you can get the contents.
|
176
|
+
+
|
177
|
+
+ contents = tree.contents
|
178
|
+
+ # => [#<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">,
|
179
|
+
+ #<Grit::Blob "81d2c27608b352814cbe979a6acd678d30219678">,
|
180
|
+
+ #<Grit::Tree "c3d07b0083f01a6e1ac969a0f32b8d06f20c62e5">,
|
181
|
+
+ #<Grit::Tree "4d00fe177a8407dbbc64a24dbfc564762c0922d8">]
|
182
|
+
+
|
183
|
+
+This tree contains two Blob objects and two Tree objects. The trees are
|
184
|
+
+subdirectories and the blobs are files. Trees below the root have additional
|
185
|
+
+attributes.
|
186
|
+
+
|
187
|
+
+ contents.last.name
|
188
|
+
+ # => "lib"
|
189
|
+
+
|
190
|
+
+ contents.last.mode
|
191
|
+
+ # => "040000"
|
192
|
+
+
|
193
|
+
+There is a convenience method that allows you to get a named sub-object
|
194
|
+
+from a tree.
|
195
|
+
+
|
196
|
+
+ tree/"lib"
|
197
|
+
+ # => #<Grit::Tree "e74893a3d8a25cbb1367cf241cc741bfd503c4b2">
|
198
|
+
+
|
199
|
+
+You can also get a tree directly from the repo if you know its name.
|
200
|
+
+
|
201
|
+
+ repo.tree
|
202
|
+
+ # => #<Grit::Tree "master">
|
203
|
+
+
|
204
|
+
+ repo.tree("91169e1f5fa4de2eaea3f176461f5dc784796769")
|
205
|
+
+ # => #<Grit::Tree "91169e1f5fa4de2eaea3f176461f5dc784796769">
|
206
|
+
+
|
207
|
+
+= The Blob object
|
208
|
+
+
|
209
|
+
+A blob represents a file. Trees often contain blobs.
|
210
|
+
+
|
211
|
+
+ blob = tree.contents.first
|
212
|
+
+ # => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
|
213
|
+
+
|
214
|
+
+A blob has certain attributes.
|
215
|
+
+
|
216
|
+
+ blob.id
|
217
|
+
+ # => "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666"
|
218
|
+
+
|
219
|
+
+ blob.name
|
220
|
+
+ # => "README.txt"
|
221
|
+
+
|
222
|
+
+ blob.mode
|
223
|
+
+ # => "100644"
|
224
|
+
+
|
225
|
+
+ blob.size
|
226
|
+
+ # => 7726
|
227
|
+
+
|
228
|
+
+You can get the data of a blob as a string.
|
229
|
+
+
|
230
|
+
+ blob.data
|
231
|
+
+ # => "Grit is a library to ..."
|
232
|
+
+
|
233
|
+
+You can also get a blob directly from the repo if you know its name.
|
234
|
+
|
235
|
+
-* FIX (sudo gem install, anything else)
|
236
|
+
+ repo.blob("4ebc8aea50e0a67e000ba29a30809d0a7b9b2666")
|
237
|
+
+ # => #<Grit::Blob "4ebc8aea50e0a67e000ba29a30809d0a7b9b2666">
|
238
|
+
|
239
|
+
== LICENSE:
|
240
|
+
|
241
|
+
(The MIT License)
|
242
|
+
|
243
|
+
-Copyright (c) 2007 FIX
|
244
|
+
+Copyright (c) 2007 Tom Preston-Werner
|
245
|
+
|
246
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
247
|
+
a copy of this software and associated documentation files (the
|
248
|
+
diff --git a/Rakefile b/Rakefile
|
249
|
+
index 5bfb62163af455ca54422fd0b2e723ba1021ad12..72fde8c9ca87a1c992ce992bab13c3c4f13cddb9 100644
|
250
|
+
--- a/Rakefile
|
251
|
+
+++ b/Rakefile
|
252
|
+
@@ -4,11 +4,11 @@ require './lib/grit.rb'
|
253
|
+
|
254
|
+
Hoe.new('grit', Grit::VERSION) do |p|
|
255
|
+
p.rubyforge_name = 'grit'
|
256
|
+
- # p.author = 'FIX'
|
257
|
+
- # p.email = 'FIX'
|
258
|
+
- # p.summary = 'FIX'
|
259
|
+
- # p.description = p.paragraphs_of('README.txt', 2..5).join("\n\n")
|
260
|
+
- # p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[1..-1]
|
261
|
+
+ p.author = 'Tom Preston-Werner'
|
262
|
+
+ p.email = 'tom@rubyisawesome.com'
|
263
|
+
+ p.summary = 'Object model interface to a git repo'
|
264
|
+
+ p.description = p.paragraphs_of('README.txt', 2..2).join("\n\n")
|
265
|
+
+ p.url = p.paragraphs_of('README.txt', 0).first.split(/\n/)[2..-1].map { |u| u.strip }
|
266
|
+
p.changes = p.paragraphs_of('History.txt', 0..1).join("\n\n")
|
267
|
+
end
|
268
|
+
|
269
|
+
diff --git a/lib/grit.rb b/lib/grit.rb
|
270
|
+
index ae0792ae39d4891ebc1af996102a4f9df703394d..ae55fd7961ac49233f6ca515622a61e90d516044 100644
|
271
|
+
--- a/lib/grit.rb
|
272
|
+
+++ b/lib/grit.rb
|
273
|
+
@@ -1,4 +1,4 @@
|
274
|
+
-$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
275
|
+
+$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
276
|
+
|
277
|
+
# core
|
278
|
+
|
279
|
+
@@ -12,6 +12,8 @@ require 'grit/head'
|
280
|
+
require 'grit/commit'
|
281
|
+
require 'grit/tree'
|
282
|
+
require 'grit/blob'
|
283
|
+
+require 'grit/actor'
|
284
|
+
+require 'grit/diff'
|
285
|
+
require 'grit/repo'
|
286
|
+
|
287
|
+
module Grit
|
288
|
+
@@ -21,5 +23,5 @@ module Grit
|
289
|
+
|
290
|
+
self.debug = false
|
291
|
+
|
292
|
+
- VERSION = '1.0.0'
|
293
|
+
+ VERSION = '0.1.0'
|
294
|
+
end
|
295
|
+
|
296
|
+
diff --git a/lib/grit/actor.rb b/lib/grit/actor.rb
|
297
|
+
new file mode 100644
|
298
|
+
index 0000000000000000000000000000000000000000..f733bce6b57c0e5e353206e692b0e3105c2527f4
|
299
|
+
--- /dev/null
|
300
|
+
+++ b/lib/grit/actor.rb
|
301
|
+
@@ -0,0 +1,35 @@
|
302
|
+
+module Grit
|
303
|
+
+
|
304
|
+
+ class Actor
|
305
|
+
+ attr_reader :name
|
306
|
+
+ attr_reader :email
|
307
|
+
+
|
308
|
+
+ def initialize(name, email)
|
309
|
+
+ @name = name
|
310
|
+
+ @email = email
|
311
|
+
+ end
|
312
|
+
+
|
313
|
+
+ # Create an Actor from a string.
|
314
|
+
+ # +str+ is the string, which is expected to be in regular git format
|
315
|
+
+ #
|
316
|
+
+ # Format
|
317
|
+
+ # John Doe <jdoe@example.com>
|
318
|
+
+ #
|
319
|
+
+ # Returns Actor
|
320
|
+
+ def self.from_string(str)
|
321
|
+
+ case str
|
322
|
+
+ when /<.+>/
|
323
|
+
+ m, name, email = *str.match(/(.*) <(.+?)>/)
|
324
|
+
+ return self.new(name, email)
|
325
|
+
+ else
|
326
|
+
+ return self.new(str, nil)
|
327
|
+
+ end
|
328
|
+
+ end
|
329
|
+
+
|
330
|
+
+ # Pretty object inspection
|
331
|
+
+ def inspect
|
332
|
+
+ %Q{#<Grit::Actor "#{@name} <#{@email}>">}
|
333
|
+
+ end
|
334
|
+
+ end # Actor
|
335
|
+
+
|
336
|
+
+end # Grit
|
337
|
+
|
338
|
+
diff --git a/lib/grit/blob.rb b/lib/grit/blob.rb
|
339
|
+
index c863646d4278bfee2a7bcb64caace6b31f89ef03..87d43fab37844afdc2f8814dba3abdaa791f1370 100644
|
340
|
+
--- a/lib/grit/blob.rb
|
341
|
+
+++ b/lib/grit/blob.rb
|
342
|
+
@@ -81,9 +81,9 @@ module Grit
|
343
|
+
c = commits[info[:id]]
|
344
|
+
unless c
|
345
|
+
c = Commit.create(repo, :id => info[:id],
|
346
|
+
- :author => info[:author],
|
347
|
+
+ :author => Actor.from_string(info[:author] + ' ' + info[:author_email]),
|
348
|
+
:authored_date => info[:author_date],
|
349
|
+
- :committer => info[:committer],
|
350
|
+
+ :committer => Actor.from_string(info[:committer] + ' ' + info[:committer_email]),
|
351
|
+
:committed_date => info[:committer_date],
|
352
|
+
:message => info[:summary])
|
353
|
+
commits[info[:id]] = c
|
354
|
+
@@ -102,11 +102,6 @@ module Grit
|
355
|
+
def inspect
|
356
|
+
%Q{#<Grit::Blob "#{@id}">}
|
357
|
+
end
|
358
|
+
-
|
359
|
+
- # private
|
360
|
+
-
|
361
|
+
- def self.read_
|
362
|
+
- end
|
363
|
+
end # Blob
|
364
|
+
|
365
|
+
end # Grit
|
366
|
+
|
367
|
+
diff --git a/lib/grit/commit.rb b/lib/grit/commit.rb
|
368
|
+
index c2a9e2f81657b19925fe9bab4bc5d7ac130e5880..cd9c3e3184c97e83a8982fab9499cad3aec339f6 100644
|
369
|
+
--- a/lib/grit/commit.rb
|
370
|
+
+++ b/lib/grit/commit.rb
|
371
|
+
@@ -136,6 +136,11 @@ module Grit
|
372
|
+
commits
|
373
|
+
end
|
374
|
+
|
375
|
+
+ def self.diff(repo, id)
|
376
|
+
+ text = repo.git.diff({:full_index => true}, id)
|
377
|
+
+ Diff.list_from_string(repo, text)
|
378
|
+
+ end
|
379
|
+
+
|
380
|
+
# Convert this Commit to a String which is just the SHA1 id
|
381
|
+
def to_s
|
382
|
+
@id
|
383
|
+
@@ -153,7 +158,7 @@ module Grit
|
384
|
+
# Returns [String (actor name and email), Time (acted at time)]
|
385
|
+
def self.actor(line)
|
386
|
+
m, actor, epoch = *line.match(/^.+? (.*) (\d+) .*$/)
|
387
|
+
- [actor, Time.at(epoch.to_i)]
|
388
|
+
+ [Actor.from_string(actor), Time.at(epoch.to_i)]
|
389
|
+
end
|
390
|
+
end # Commit
|
391
|
+
|
392
|
+
diff --git a/lib/grit/git.rb b/lib/grit/git.rb
|
393
|
+
index 1d5251d40fb65ac89184ec662a3e1b04d0c24861..98eeddda5ed2b0e215e21128112393bdc9bc9039 100644
|
394
|
+
--- a/lib/grit/git.rb
|
395
|
+
+++ b/lib/grit/git.rb
|
396
|
+
@@ -13,17 +13,6 @@ module Grit
|
397
|
+
self.git_dir = git_dir
|
398
|
+
end
|
399
|
+
|
400
|
+
- # Converstion hash from Ruby style options to git command line
|
401
|
+
- # style options
|
402
|
+
- TRANSFORM = {:max_count => "--max-count=",
|
403
|
+
- :skip => "--skip=",
|
404
|
+
- :pretty => "--pretty=",
|
405
|
+
- :sort => "--sort=",
|
406
|
+
- :format => "--format=",
|
407
|
+
- :since => "--since=",
|
408
|
+
- :p => "-p",
|
409
|
+
- :s => "-s"}
|
410
|
+
-
|
411
|
+
# Run the given git command with the specified arguments and return
|
412
|
+
# the result as a String
|
413
|
+
# +cmd+ is the command
|
414
|
+
@@ -52,12 +41,19 @@ module Grit
|
415
|
+
def transform_options(options)
|
416
|
+
args = []
|
417
|
+
options.keys.each do |opt|
|
418
|
+
- if TRANSFORM[opt]
|
419
|
+
+ if opt.to_s.size == 1
|
420
|
+
+ if options[opt] == true
|
421
|
+
+ args << "-#{opt}"
|
422
|
+
+ else
|
423
|
+
+ val = options.delete(opt)
|
424
|
+
+ args << "-#{opt.to_s} #{val}"
|
425
|
+
+ end
|
426
|
+
+ else
|
427
|
+
if options[opt] == true
|
428
|
+
- args << TRANSFORM[opt]
|
429
|
+
+ args << "--#{opt.to_s.gsub(/_/, '-')}"
|
430
|
+
else
|
431
|
+
val = options.delete(opt)
|
432
|
+
- args << TRANSFORM[opt] + val.to_s
|
433
|
+
+ args << "--#{opt.to_s.gsub(/_/, '-')}=#{val}"
|
434
|
+
end
|
435
|
+
end
|
436
|
+
end
|
437
|
+
diff --git a/lib/grit/repo.rb b/lib/grit/repo.rb
|
438
|
+
index 624991d07e240ae66ff2a0dc55e2f2b5e262c75b..63bf03b839374c96a3d42a07d56681a797f52a71 100644
|
439
|
+
--- a/lib/grit/repo.rb
|
440
|
+
+++ b/lib/grit/repo.rb
|
441
|
+
@@ -93,6 +93,17 @@ module Grit
|
442
|
+
def blob(id)
|
443
|
+
Blob.create(self, :id => id)
|
444
|
+
end
|
445
|
+
+
|
446
|
+
+ # The commit log for a treeish
|
447
|
+
+ #
|
448
|
+
+ # Returns Grit::Commit[]
|
449
|
+
+ def log(commit = 'master', path = nil, options = {})
|
450
|
+
+ default_options = {:pretty => "raw"}
|
451
|
+
+ actual_options = default_options.merge(options)
|
452
|
+
+ arg = path ? "#{commit} -- #{path}" : commit
|
453
|
+
+ commits = self.git.log(actual_options, arg)
|
454
|
+
+ Commit.list_from_string(self, commits)
|
455
|
+
+ end
|
456
|
+
|
457
|
+
# The diff from commit +a+ to commit +b+, optionally restricted to the given file(s)
|
458
|
+
# +a+ is the base commit
|
459
|
+
@@ -121,4 +132,4 @@ module Grit
|
460
|
+
end
|
461
|
+
end # Repo
|
462
|
+
|
463
|
+
-end # Grit
|
464
|
+
|
465
|
+
+end # Grit
|
466
|
+
diff --git a/test/test_actor.rb b/test/test_actor.rb
|
467
|
+
new file mode 100644
|
468
|
+
index 0000000000000000000000000000000000000000..08391f12336831d048122c8d13bc8404f27e6b91
|
469
|
+
--- /dev/null
|
470
|
+
+++ b/test/test_actor.rb
|
471
|
+
@@ -0,0 +1,28 @@
|
472
|
+
+require File.dirname(__FILE__) + '/helper'
|
473
|
+
+
|
474
|
+
+class TestActor < Test::Unit::TestCase
|
475
|
+
+ def setup
|
476
|
+
+
|
477
|
+
+ end
|
478
|
+
+
|
479
|
+
+ # from_string
|
480
|
+
+
|
481
|
+
+ def test_from_string_should_separate_name_and_email
|
482
|
+
+ a = Actor.from_string("Tom Werner <tom@example.com>")
|
483
|
+
+ assert_equal "Tom Werner", a.name
|
484
|
+
+ assert_equal "tom@example.com", a.email
|
485
|
+
+ end
|
486
|
+
+
|
487
|
+
+ def test_from_string_should_handle_just_name
|
488
|
+
+ a = Actor.from_string("Tom Werner")
|
489
|
+
+ assert_equal "Tom Werner", a.name
|
490
|
+
+ assert_equal nil, a.email
|
491
|
+
+ end
|
492
|
+
+
|
493
|
+
+ # inspect
|
494
|
+
+
|
495
|
+
+ def test_inspect
|
496
|
+
+ a = Actor.from_string("Tom Werner <tom@example.com>")
|
497
|
+
+ assert_equal %Q{#<Grit::Actor "Tom Werner <tom@example.com>">}, a.inspect
|
498
|
+
+ end
|
499
|
+
+end
|
500
|
+
|
501
|
+
diff --git a/test/test_blob.rb b/test/test_blob.rb
|
502
|
+
index 6fa087d785661843034d03c7e0b917a8a80d5d8c..9ef84cc14266141b070771706b8aeebc3dfbef82 100644
|
503
|
+
--- a/test/test_blob.rb
|
504
|
+
+++ b/test/test_blob.rb
|
505
|
+
@@ -40,9 +40,11 @@ class TestBlob < Test::Unit::TestCase
|
506
|
+
c = b.first.first
|
507
|
+
c.expects(:__bake__).times(0)
|
508
|
+
assert_equal '634396b2f541a9f2d58b00be1a07f0c358b999b3', c.id
|
509
|
+
- assert_equal 'Tom Preston-Werner', c.author
|
510
|
+
+ assert_equal 'Tom Preston-Werner', c.author.name
|
511
|
+
+ assert_equal 'tom@mojombo.com', c.author.email
|
512
|
+
assert_equal Time.at(1191997100), c.authored_date
|
513
|
+
- assert_equal 'Tom Preston-Werner', c.committer
|
514
|
+
+ assert_equal 'Tom Preston-Werner', c.committer.name
|
515
|
+
+ assert_equal 'tom@mojombo.com', c.committer.email
|
516
|
+
assert_equal Time.at(1191997100), c.committed_date
|
517
|
+
assert_equal 'initial grit setup', c.message
|
518
|
+
# c.expects(:__bake__).times(1)
|
519
|
+
diff --git a/test/test_commit.rb b/test/test_commit.rb
|
520
|
+
index 3bd6af75deda05725900eb7fd06e8107df14c655..0936c90e5b29ede2b5214d6dc26d256a8c6646f4 100644
|
521
|
+
--- a/test/test_commit.rb
|
522
|
+
+++ b/test/test_commit.rb
|
523
|
+
@@ -10,9 +10,28 @@ class TestCommit < Test::Unit::TestCase
|
524
|
+
def test_bake
|
525
|
+
Git.any_instance.expects(:rev_list).returns(fixture('rev_list_single'))
|
526
|
+
@c = Commit.create(@r, :id => '4c8124ffcf4039d292442eeccabdeca5af5c5017')
|
527
|
+
- @c.author # cause bake-age
|
528
|
+
+ @c.author # bake
|
529
|
+
|
530
|
+
- assert_equal "Tom Preston-Werner <tom@mojombo.com>", @c.author
|
531
|
+
+ assert_equal "Tom Preston-Werner", @c.author.name
|
532
|
+
+ assert_equal "tom@mojombo.com", @c.author.email
|
533
|
+
+ end
|
534
|
+
+
|
535
|
+
+ # diff
|
536
|
+
+
|
537
|
+
+ def test_diff
|
538
|
+
+ Git.any_instance.expects(:diff).returns(fixture('diff_p'))
|
539
|
+
+ diffs = Commit.diff(@r, 'master')
|
540
|
+
+
|
541
|
+
+ assert_equal 15, diffs.size
|
542
|
+
+
|
543
|
+
+ assert_equal '.gitignore', diffs.first.a_path
|
544
|
+
+ assert_equal '.gitignore', diffs.first.b_path
|
545
|
+
+ assert_equal '4ebc8ae', diffs.first.a_commit
|
546
|
+
+ assert_equal '2dd0253', diffs.first.b_commit
|
547
|
+
+ assert_equal '100644', diffs.first.mode
|
548
|
+
+ assert_equal false, diffs.first.new_file
|
549
|
+
+ assert_equal false, diffs.first.deleted_file
|
550
|
+
+ assert_equal "--- a/.gitignore\n+++ b/.gitignore\n@@ -1 +1,2 @@\n coverage\n+pkg", diffs.first.diff
|
551
|
+
end
|
552
|
+
|
553
|
+
# to_s
|
554
|
+
diff --git a/test/test_git.rb b/test/test_git.rb
|
555
|
+
index e615a035d096b6cbc984e2f4213c06d0ac785321..72a18ec424f078f6daee75dbc62265c02ba7a892 100644
|
556
|
+
--- a/test/test_git.rb
|
557
|
+
+++ b/test/test_git.rb
|
558
|
+
@@ -10,6 +10,12 @@ class TestGit < Test::Unit::TestCase
|
559
|
+
end
|
560
|
+
|
561
|
+
def test_transform_options
|
562
|
+
+ assert_equal ["-s"], @git.transform_options({:s => true})
|
563
|
+
+ assert_equal ["-s 5"], @git.transform_options({:s => 5})
|
564
|
+
+
|
565
|
+
+ assert_equal ["--max-count"], @git.transform_options({:max_count => true})
|
566
|
+
assert_equal ["--max-count=5"], @git.transform_options({:max_count => 5})
|
567
|
+
+
|
568
|
+
+ assert_equal ["-t", "-s"], @git.transform_options({:s => true, :t => true})
|
569
|
+
end
|
570
|
+
end
|
571
|
+
|
572
|
+
diff --git a/test/test_repo.rb b/test/test_repo.rb
|
573
|
+
index d53476a51e3286be270c7b515ec1d65e5c1716e0..114a4464fa248550be10cc4abe0735d6025b5fca 100644
|
574
|
+
--- a/test/test_repo.rb
|
575
|
+
+++ b/test/test_repo.rb
|
576
|
+
@@ -59,9 +59,11 @@ class TestRepo < Test::Unit::TestCase
|
577
|
+
assert_equal '4c8124ffcf4039d292442eeccabdeca5af5c5017', c.id
|
578
|
+
assert_equal ["634396b2f541a9f2d58b00be1a07f0c358b999b3"], c.parents.map { |p| p.id }
|
579
|
+
assert_equal "672eca9b7f9e09c22dcb128c283e8c3c8d7697a4", c.tree.id
|
580
|
+
- assert_equal "Tom Preston-Werner <tom@mojombo.com>", c.author
|
581
|
+
+ assert_equal "Tom Preston-Werner", c.author.name
|
582
|
+
+ assert_equal "tom@mojombo.com", c.author.email
|
583
|
+
assert_equal Time.at(1191999972), c.authored_date
|
584
|
+
- assert_equal "Tom Preston-Werner <tom@mojombo.com>", c.committer
|
585
|
+
+ assert_equal "Tom Preston-Werner", c.committer.name
|
586
|
+
+ assert_equal "tom@mojombo.com", c.committer.email
|
587
|
+
assert_equal Time.at(1191999972), c.committed_date
|
588
|
+
assert_equal "implement Grit#heads", c.message
|
589
|
+
|
590
|
+
@@ -125,4 +127,18 @@ class TestRepo < Test::Unit::TestCase
|
591
|
+
def test_inspect
|
592
|
+
assert_equal %Q{#<Grit::Repo "#{File.expand_path(GRIT_REPO)}/.git">}, @r.inspect
|
593
|
+
end
|
594
|
+
-end
|
595
|
+
|
596
|
+
+
|
597
|
+
+ # log
|
598
|
+
+
|
599
|
+
+ def test_log
|
600
|
+
+ Git.any_instance.expects(:log).times(2).with({:pretty => 'raw'}, 'master').returns(fixture('rev_list'))
|
601
|
+
+
|
602
|
+
+ assert_equal '4c8124ffcf4039d292442eeccabdeca5af5c5017', @r.log.first.id
|
603
|
+
+ assert_equal 'ab25fd8483882c3bda8a458ad2965d2248654335', @r.log.last.id
|
604
|
+
+ end
|
605
|
+
+
|
606
|
+
+ def test_log_with_path_and_options
|
607
|
+
+ Git.any_instance.expects(:log).with({:pretty => 'raw', :max_count => 1}, 'master -- file.rb').returns(fixture('rev_list'))
|
608
|
+
+ @r.log('master', 'file.rb', :max_count => 1)
|
609
|
+
+ end
|
610
|
+
+end
|