mojombo-grit 0.9.4 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|