mojombo-grit 0.9.4 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/API.txt +101 -0
- data/History.txt +38 -2
- data/README.md +210 -0
- data/VERSION.yml +4 -0
- data/lib/grit.rb +13 -4
- data/lib/grit/blame.rb +61 -0
- data/lib/grit/blob.rb +11 -2
- data/lib/grit/commit.rb +44 -31
- data/lib/grit/commit_stats.rb +26 -2
- data/lib/grit/diff.rb +6 -6
- data/lib/grit/git-ruby.rb +4 -2
- data/lib/grit/git-ruby/file_index.rb +10 -3
- data/lib/grit/git-ruby/git_object.rb +9 -3
- data/lib/grit/git-ruby/internal/{mmap.rb → file_window.rb} +2 -2
- data/lib/grit/git-ruby/internal/loose.rb +6 -6
- data/lib/grit/git-ruby/internal/pack.rb +19 -19
- data/lib/grit/git-ruby/object.rb +8 -2
- data/lib/grit/git-ruby/repository.rb +11 -6
- data/lib/grit/git.rb +23 -10
- data/lib/grit/index.rb +12 -11
- data/lib/grit/merge.rb +45 -0
- data/lib/grit/ref.rb +20 -16
- data/lib/grit/repo.rb +59 -9
- data/lib/grit/ruby1.9.rb +7 -0
- data/lib/grit/submodule.rb +5 -1
- data/lib/grit/tag.rb +61 -66
- data/lib/grit/tree.rb +20 -1
- metadata +29 -47
- data/Manifest.txt +0 -71
- data/README.txt +0 -213
- data/Rakefile +0 -29
- data/grit.gemspec +0 -62
- data/lib/grit/head.rb +0 -83
- data/test/test_actor.rb +0 -35
- data/test/test_blob.rb +0 -79
- data/test/test_commit.rb +0 -190
- data/test/test_config.rb +0 -58
- data/test/test_diff.rb +0 -18
- data/test/test_git.rb +0 -64
- data/test/test_grit.rb +0 -32
- data/test/test_head.rb +0 -47
- data/test/test_real.rb +0 -19
- data/test/test_reality.rb +0 -17
- data/test/test_remote.rb +0 -14
- data/test/test_repo.rb +0 -277
- data/test/test_tag.rb +0 -25
- data/test/test_tree.rb +0 -96
data/lib/grit/blob.rb
CHANGED
@@ -104,14 +104,23 @@ module Grit
|
|
104
104
|
info = nil
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
107
|
+
|
108
108
|
blames
|
109
109
|
end
|
110
110
|
|
111
|
+
def basename
|
112
|
+
File.basename(name)
|
113
|
+
end
|
114
|
+
|
111
115
|
# Pretty object inspection
|
112
116
|
def inspect
|
113
117
|
%Q{#<Grit::Blob "#{@id}">}
|
114
118
|
end
|
119
|
+
|
120
|
+
# Compares blobs by name
|
121
|
+
def <=>(other)
|
122
|
+
name <=> other.name
|
123
|
+
end
|
115
124
|
end # Blob
|
116
|
-
|
125
|
+
|
117
126
|
end # Grit
|
data/lib/grit/commit.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Grit
|
2
|
-
|
2
|
+
|
3
3
|
class Commit
|
4
4
|
attr_reader :id
|
5
5
|
lazy_reader :parents
|
@@ -10,7 +10,8 @@ module Grit
|
|
10
10
|
lazy_reader :committed_date
|
11
11
|
lazy_reader :message
|
12
12
|
lazy_reader :short_message
|
13
|
-
|
13
|
+
lazy_reader :author_string
|
14
|
+
|
14
15
|
# Instantiate a new Commit
|
15
16
|
# +id+ is the id of the commit
|
16
17
|
# +parents+ is an array of commit ids (will be converted into Commit instances)
|
@@ -34,11 +35,11 @@ module Grit
|
|
34
35
|
@message = message.join("\n")
|
35
36
|
@short_message = message[0] || ''
|
36
37
|
end
|
37
|
-
|
38
|
+
|
38
39
|
def id_abbrev
|
39
40
|
@id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
|
40
41
|
end
|
41
|
-
|
42
|
+
|
42
43
|
# Create an unbaked Commit containing just the specified attributes
|
43
44
|
# +repo+ is the Repo
|
44
45
|
# +atts+ is a Hash of instance variable data
|
@@ -47,7 +48,7 @@ module Grit
|
|
47
48
|
def self.create(repo, atts)
|
48
49
|
self.allocate.create_initialize(repo, atts)
|
49
50
|
end
|
50
|
-
|
51
|
+
|
51
52
|
# Initializer for Commit.create
|
52
53
|
# +repo+ is the Repo
|
53
54
|
# +atts+ is a Hash of instance variable data
|
@@ -60,11 +61,11 @@ module Grit
|
|
60
61
|
end
|
61
62
|
self
|
62
63
|
end
|
63
|
-
|
64
|
+
|
64
65
|
def lazy_source
|
65
66
|
self.class.find_all(@repo, @id, {:max_count => 1}).first
|
66
67
|
end
|
67
|
-
|
68
|
+
|
68
69
|
# Count the number of commits reachable from this ref
|
69
70
|
# +repo+ is the Repo
|
70
71
|
# +ref+ is the ref from which to begin (SHA1 or name)
|
@@ -73,7 +74,7 @@ module Grit
|
|
73
74
|
def self.count(repo, ref)
|
74
75
|
repo.git.rev_list({}, ref).size / 41
|
75
76
|
end
|
76
|
-
|
77
|
+
|
77
78
|
# Find all commits matching the given criteria.
|
78
79
|
# +repo+ is the Repo
|
79
80
|
# +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
|
@@ -84,21 +85,21 @@ module Grit
|
|
84
85
|
# Returns Grit::Commit[] (baked)
|
85
86
|
def self.find_all(repo, ref, options = {})
|
86
87
|
allowed_options = [:max_count, :skip, :since]
|
87
|
-
|
88
|
+
|
88
89
|
default_options = {:pretty => "raw"}
|
89
90
|
actual_options = default_options.merge(options)
|
90
|
-
|
91
|
+
|
91
92
|
if ref
|
92
93
|
output = repo.git.rev_list(actual_options, ref)
|
93
94
|
else
|
94
95
|
output = repo.git.rev_list(actual_options.merge(:all => true))
|
95
96
|
end
|
96
|
-
|
97
|
+
|
97
98
|
self.list_from_string(repo, output)
|
98
99
|
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
99
100
|
[]
|
100
101
|
end
|
101
|
-
|
102
|
+
|
102
103
|
# Parse out commit information into an array of baked Commit objects
|
103
104
|
# +repo+ is the Repo
|
104
105
|
# +text+ is the text output from the git command (raw format)
|
@@ -110,40 +111,40 @@ module Grit
|
|
110
111
|
#
|
111
112
|
def self.list_from_string(repo, text)
|
112
113
|
lines = text.split("\n")
|
113
|
-
|
114
|
+
|
114
115
|
commits = []
|
115
|
-
|
116
|
+
|
116
117
|
while !lines.empty?
|
117
118
|
id = lines.shift.split.last
|
118
119
|
tree = lines.shift.split.last
|
119
|
-
|
120
|
+
|
120
121
|
parents = []
|
121
122
|
parents << lines.shift.split.last while lines.first =~ /^parent/
|
122
|
-
|
123
|
+
|
123
124
|
author, authored_date = self.actor(lines.shift)
|
124
125
|
committer, committed_date = self.actor(lines.shift)
|
125
|
-
|
126
|
+
|
126
127
|
# not doing anything with this yet, but it's sometimes there
|
127
128
|
encoding = lines.shift.split.last if lines.first =~ /^encoding/
|
128
|
-
|
129
|
+
|
129
130
|
lines.shift
|
130
|
-
|
131
|
+
|
131
132
|
message_lines = []
|
132
133
|
message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
|
133
|
-
|
134
|
+
|
134
135
|
lines.shift while lines.first && lines.first.empty?
|
135
|
-
|
136
|
+
|
136
137
|
commits << Commit.new(repo, id, parents, tree, author, authored_date, committer, committed_date, message_lines)
|
137
138
|
end
|
138
|
-
|
139
|
+
|
139
140
|
commits
|
140
141
|
end
|
141
|
-
|
142
|
+
|
142
143
|
# Show diffs between two trees:
|
143
144
|
# +repo+ is the Repo
|
144
145
|
# +a+ is a named commit
|
145
|
-
# +b+ is an optional named commit. Passing an array assumes you
|
146
|
-
# wish to omit the second named commit and limit the diff to the
|
146
|
+
# +b+ is an optional named commit. Passing an array assumes you
|
147
|
+
# wish to omit the second named commit and limit the diff to the
|
147
148
|
# given paths.
|
148
149
|
# +paths* is an array of paths to limit the diff.
|
149
150
|
#
|
@@ -174,10 +175,14 @@ module Grit
|
|
174
175
|
if parents.empty?
|
175
176
|
show
|
176
177
|
else
|
177
|
-
self.class.diff(@repo, parents.first.id, @id)
|
178
|
+
self.class.diff(@repo, parents.first.id, @id)
|
178
179
|
end
|
179
180
|
end
|
180
181
|
|
182
|
+
def stats
|
183
|
+
stats = @repo.commit_stats(self.sha, 1)[0][-1]
|
184
|
+
end
|
185
|
+
|
181
186
|
# Convert this Commit to a String which is just the SHA1 id
|
182
187
|
def to_s
|
183
188
|
@id
|
@@ -186,18 +191,22 @@ module Grit
|
|
186
191
|
def sha
|
187
192
|
@id
|
188
193
|
end
|
189
|
-
|
194
|
+
|
190
195
|
def date
|
191
196
|
@committed_date
|
192
197
|
end
|
193
|
-
|
198
|
+
|
199
|
+
def to_patch
|
200
|
+
@repo.git.format_patch({'1' => true, :stdout => true}, to_s)
|
201
|
+
end
|
202
|
+
|
194
203
|
# Pretty object inspection
|
195
204
|
def inspect
|
196
205
|
%Q{#<Grit::Commit "#{@id}">}
|
197
206
|
end
|
198
|
-
|
207
|
+
|
199
208
|
# private
|
200
|
-
|
209
|
+
|
201
210
|
# Parse out the actor (author or committer) info
|
202
211
|
#
|
203
212
|
# Returns [String (actor name and email), Time (acted at time)]
|
@@ -206,6 +215,10 @@ module Grit
|
|
206
215
|
[Actor.from_string(actor), Time.at(epoch.to_i)]
|
207
216
|
end
|
208
217
|
|
218
|
+
def author_string
|
219
|
+
"%s <%s> %s %+05d" % [author.name, author.email, authored_date.to_i, 800]
|
220
|
+
end
|
221
|
+
|
209
222
|
def to_hash
|
210
223
|
{
|
211
224
|
'id' => id,
|
@@ -225,5 +238,5 @@ module Grit
|
|
225
238
|
}
|
226
239
|
end
|
227
240
|
end # Commit
|
228
|
-
|
241
|
+
|
229
242
|
end # Grit
|
data/lib/grit/commit_stats.rb
CHANGED
@@ -62,12 +62,12 @@ module Grit
|
|
62
62
|
lines.shift
|
63
63
|
|
64
64
|
message_lines = []
|
65
|
-
message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
|
65
|
+
message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/ || lines.first == ''
|
66
66
|
|
67
67
|
lines.shift while lines.first && lines.first.empty?
|
68
68
|
|
69
69
|
files = []
|
70
|
-
while lines.first =~ /^(
|
70
|
+
while lines.first =~ /^([-\d]+)\s+([-\d]+)\s+(.+)/
|
71
71
|
(additions, deletions, filename) = lines.shift.split
|
72
72
|
additions = additions.to_i
|
73
73
|
deletions = deletions.to_i
|
@@ -88,6 +88,13 @@ module Grit
|
|
88
88
|
%Q{#<Grit::CommitStats "#{@id}">}
|
89
89
|
end
|
90
90
|
|
91
|
+
# Convert to an easy-to-traverse structure
|
92
|
+
def to_diffstat
|
93
|
+
files.map do |metadata|
|
94
|
+
DiffStat.new(*metadata)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
91
98
|
# private
|
92
99
|
|
93
100
|
def to_hash
|
@@ -99,6 +106,23 @@ module Grit
|
|
99
106
|
'total' => total
|
100
107
|
}
|
101
108
|
end
|
109
|
+
|
102
110
|
end # CommitStats
|
103
111
|
|
112
|
+
class DiffStat
|
113
|
+
attr_reader :filename, :additions, :deletions
|
114
|
+
|
115
|
+
def initialize(filename, additions, deletions, total=nil)
|
116
|
+
@filename, @additions, @deletions = filename, additions, deletions
|
117
|
+
end
|
118
|
+
|
119
|
+
def net
|
120
|
+
additions - deletions
|
121
|
+
end
|
122
|
+
|
123
|
+
def inspect
|
124
|
+
"#{filename}: +#{additions} -#{deletions}"
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
104
128
|
end # Grit
|
data/lib/grit/diff.rb
CHANGED
@@ -2,17 +2,17 @@ module Grit
|
|
2
2
|
|
3
3
|
class Diff
|
4
4
|
attr_reader :a_path, :b_path
|
5
|
-
attr_reader :
|
5
|
+
attr_reader :a_blob, :b_blob
|
6
6
|
attr_reader :a_mode, :b_mode
|
7
7
|
attr_reader :new_file, :deleted_file
|
8
8
|
attr_reader :diff
|
9
9
|
|
10
|
-
def initialize(repo, a_path, b_path,
|
10
|
+
def initialize(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff)
|
11
11
|
@repo = repo
|
12
12
|
@a_path = a_path
|
13
13
|
@b_path = b_path
|
14
|
-
@
|
15
|
-
@
|
14
|
+
@a_blob = a_blob =~ /^0{40}$/ ? nil : Blob.create(repo, :id => a_blob)
|
15
|
+
@b_blob = b_blob =~ /^0{40}$/ ? nil : Blob.create(repo, :id => b_blob)
|
16
16
|
@a_mode = a_mode
|
17
17
|
@b_mode = b_mode
|
18
18
|
@new_file = new_file
|
@@ -51,7 +51,7 @@ module Grit
|
|
51
51
|
deleted_file = true
|
52
52
|
end
|
53
53
|
|
54
|
-
m,
|
54
|
+
m, a_blob, b_blob, b_mode = *lines.shift.match(%r{^index ([0-9A-Fa-f]+)\.\.([0-9A-Fa-f]+) ?(.+)?$})
|
55
55
|
b_mode.strip! if b_mode
|
56
56
|
|
57
57
|
diff_lines = []
|
@@ -60,7 +60,7 @@ module Grit
|
|
60
60
|
end
|
61
61
|
diff = diff_lines.join("\n")
|
62
62
|
|
63
|
-
diffs << Diff.new(repo, a_path, b_path,
|
63
|
+
diffs << Diff.new(repo, a_path, b_path, a_blob, b_blob, a_mode, b_mode, new_file, deleted_file, diff)
|
64
64
|
end
|
65
65
|
|
66
66
|
diffs
|
data/lib/grit/git-ruby.rb
CHANGED
@@ -72,8 +72,8 @@ module Grit
|
|
72
72
|
(sha1, sha2) = string.split('..')
|
73
73
|
return [rev_parse({}, sha1), rev_parse({}, sha2)]
|
74
74
|
end
|
75
|
-
|
76
|
-
if
|
75
|
+
|
76
|
+
if /^[0-9a-f]{40}$/.match(string) # passing in a sha - just no-op it
|
77
77
|
return string.chomp
|
78
78
|
end
|
79
79
|
|
@@ -113,6 +113,8 @@ module Grit
|
|
113
113
|
|
114
114
|
def blame_tree(commit, path = nil)
|
115
115
|
begin
|
116
|
+
path = [path].join('/').to_s + '/' if (path && path != '')
|
117
|
+
path = '' if !path.is_a? String
|
116
118
|
commits = file_index.last_commits(rev_parse({}, commit), looking_for(commit, path))
|
117
119
|
clean_paths(commits)
|
118
120
|
rescue FileIndex::IndexFileNotFound
|
@@ -22,12 +22,18 @@ module Grit
|
|
22
22
|
class UnsupportedRef < StandardError
|
23
23
|
end
|
24
24
|
|
25
|
+
class << self
|
26
|
+
attr_accessor :max_file_size
|
27
|
+
end
|
28
|
+
|
29
|
+
self.max_file_size = 10_000_000 # ~10M
|
30
|
+
|
25
31
|
attr_reader :files
|
26
32
|
|
27
33
|
# initializes index given repo_path
|
28
34
|
def initialize(repo_path)
|
29
35
|
@index_file = File.join(repo_path, 'file-index')
|
30
|
-
if File.file?(@index_file)
|
36
|
+
if File.file?(@index_file) && (File.size(@index_file) < Grit::GitRuby::FileIndex.max_file_size)
|
31
37
|
read_index
|
32
38
|
else
|
33
39
|
raise IndexFileNotFound
|
@@ -46,6 +52,7 @@ module Grit
|
|
46
52
|
commits_from(commit_sha).size
|
47
53
|
end
|
48
54
|
|
55
|
+
# builds a list of all commits reachable from a single commit
|
49
56
|
def commits_from(commit_sha)
|
50
57
|
raise UnsupportedRef if commit_sha.is_a? Array
|
51
58
|
|
@@ -69,7 +76,7 @@ module Grit
|
|
69
76
|
end
|
70
77
|
|
71
78
|
def sort_commits(sha_array)
|
72
|
-
sha_array.sort { |a, b| @commit_order[b] <=> @commit_order[a] }
|
79
|
+
sha_array.sort { |a, b| @commit_order[b].to_i <=> @commit_order[a].to_i }
|
73
80
|
end
|
74
81
|
|
75
82
|
# returns files changed at commit sha
|
@@ -183,4 +190,4 @@ if __FILE__ == $0
|
|
183
190
|
end
|
184
191
|
|
185
192
|
|
186
|
-
|
193
|
+
|
@@ -115,7 +115,7 @@ module Grit
|
|
115
115
|
def initialize(mode, filename, sha1o)
|
116
116
|
@mode = 0
|
117
117
|
mode.each_byte do |i|
|
118
|
-
@mode = (@mode << 3) | (i-'0'
|
118
|
+
@mode = (@mode << 3) | (i-'0'.getord(0))
|
119
119
|
end
|
120
120
|
@name = filename
|
121
121
|
@sha1 = sha1o
|
@@ -179,8 +179,14 @@ module Grit
|
|
179
179
|
|
180
180
|
def self.read_bytes_until(io, char)
|
181
181
|
string = ''
|
182
|
-
|
183
|
-
|
182
|
+
if RUBY_VERSION > '1.9'
|
183
|
+
while ((next_char = io.getc) != char) && !io.eof
|
184
|
+
string += next_char
|
185
|
+
end
|
186
|
+
else
|
187
|
+
while ((next_char = io.getc.chr) != char) && !io.eof
|
188
|
+
string += next_char
|
189
|
+
end
|
184
190
|
end
|
185
191
|
string
|
186
192
|
end
|
@@ -12,7 +12,7 @@
|
|
12
12
|
module Grit
|
13
13
|
module GitRuby
|
14
14
|
module Internal
|
15
|
-
class
|
15
|
+
class FileWindow
|
16
16
|
def initialize(file, version = 1)
|
17
17
|
@file = file
|
18
18
|
@offset = nil
|
@@ -46,7 +46,7 @@ module Grit
|
|
46
46
|
end
|
47
47
|
@offset = offset + len ? len : 1
|
48
48
|
if not len
|
49
|
-
@file.read(1)
|
49
|
+
@file.read(1).getord(0)
|
50
50
|
else
|
51
51
|
@file.read(len)
|
52
52
|
end
|
@@ -29,7 +29,7 @@ module Grit
|
|
29
29
|
begin
|
30
30
|
return nil unless sha1[0...2] && sha1[2..39]
|
31
31
|
path = @directory + '/' + sha1[0...2] + '/' + sha1[2..39]
|
32
|
-
get_raw_object(File.
|
32
|
+
get_raw_object(File.open(path, 'rb').read)
|
33
33
|
rescue Errno::ENOENT
|
34
34
|
nil
|
35
35
|
end
|
@@ -76,7 +76,7 @@ module Grit
|
|
76
76
|
content = Zlib::Deflate.deflate(store)
|
77
77
|
|
78
78
|
FileUtils.mkdir_p(@directory+'/'+sha1[0...2])
|
79
|
-
File.open(path, '
|
79
|
+
File.open(path, 'wb') do |f|
|
80
80
|
f.write content
|
81
81
|
end
|
82
82
|
end
|
@@ -102,7 +102,7 @@ module Grit
|
|
102
102
|
# private
|
103
103
|
def unpack_object_header_gently(buf)
|
104
104
|
used = 0
|
105
|
-
c = buf
|
105
|
+
c = buf.getord(used)
|
106
106
|
used += 1
|
107
107
|
|
108
108
|
type = (c >> 4) & 7;
|
@@ -112,7 +112,7 @@ module Grit
|
|
112
112
|
if buf.length <= used
|
113
113
|
raise LooseObjectError, "object file too short"
|
114
114
|
end
|
115
|
-
c = buf
|
115
|
+
c = buf.getord(used)
|
116
116
|
used += 1
|
117
117
|
|
118
118
|
size += (c & 0x7f) << shift
|
@@ -127,8 +127,8 @@ module Grit
|
|
127
127
|
private :unpack_object_header_gently
|
128
128
|
|
129
129
|
def legacy_loose_object?(buf)
|
130
|
-
word = (buf
|
131
|
-
buf
|
130
|
+
word = (buf.getord(0) << 8) + buf.getord(1)
|
131
|
+
buf.getord(0) == 0x78 && word % 31 == 0
|
132
132
|
end
|
133
133
|
private :legacy_loose_object?
|
134
134
|
end
|