mojombo-grit 0.8.1 → 0.9.3
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/History.txt +7 -0
- data/Manifest.txt +18 -1
- data/grit.gemspec +56 -10
- data/lib/{mojombo-grit.rb → grit.rb} +20 -4
- data/lib/grit/commit.rb +32 -11
- data/lib/grit/commit_stats.rb +104 -0
- data/lib/grit/git-ruby.rb +182 -0
- data/lib/grit/git-ruby/commit_db.rb +52 -0
- data/lib/grit/git-ruby/file_index.rb +186 -0
- data/lib/grit/git-ruby/git_object.rb +344 -0
- data/lib/grit/git-ruby/internal/loose.rb +136 -0
- data/lib/grit/git-ruby/internal/mmap.rb +58 -0
- data/lib/grit/git-ruby/internal/pack.rb +382 -0
- data/lib/grit/git-ruby/internal/raw_object.rb +37 -0
- data/lib/grit/git-ruby/object.rb +319 -0
- data/lib/grit/git-ruby/repository.rb +729 -0
- data/lib/grit/git.rb +33 -15
- data/lib/grit/head.rb +6 -15
- data/lib/grit/index.rb +121 -0
- data/lib/grit/ref.rb +95 -0
- data/lib/grit/repo.rb +95 -6
- data/lib/grit/status.rb +151 -0
- data/lib/grit/tree.rb +3 -2
- data/test/test_blob.rb +5 -0
- data/test/test_commit.rb +7 -5
- data/test/test_diff.rb +1 -1
- data/test/test_git.rb +20 -2
- data/test/test_grit.rb +32 -0
- data/test/test_head.rb +30 -5
- data/test/test_real.rb +8 -6
- data/test/test_remote.rb +14 -0
- data/test/test_repo.rb +86 -79
- data/test/test_tag.rb +2 -6
- data/test/test_tree.rb +5 -0
- metadata +40 -40
- data/test/fixtures/blame +0 -131
- data/test/fixtures/cat_file_blob +0 -1
- data/test/fixtures/cat_file_blob_size +0 -1
- data/test/fixtures/diff_2 +0 -54
- data/test/fixtures/diff_2f +0 -19
- data/test/fixtures/diff_f +0 -15
- data/test/fixtures/diff_i +0 -201
- data/test/fixtures/diff_mode_only +0 -1152
- data/test/fixtures/diff_new_mode +0 -17
- data/test/fixtures/diff_p +0 -610
- data/test/fixtures/for_each_ref +0 -0
- data/test/fixtures/for_each_ref_tags +0 -0
- data/test/fixtures/ls_tree_a +0 -7
- data/test/fixtures/ls_tree_b +0 -2
- data/test/fixtures/ls_tree_commit +0 -3
- data/test/fixtures/rev_list +0 -26
- data/test/fixtures/rev_list_count +0 -655
- data/test/fixtures/rev_list_single +0 -7
- data/test/fixtures/rev_parse +0 -1
- data/test/fixtures/show_empty_commit +0 -6
- data/test/fixtures/simple_config +0 -2
- data/test/helper.rb +0 -17
- data/test/profile.rb +0 -21
- data/test/suite.rb +0 -6
data/History.txt
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
+
== 0.8.3 / 2008-07-07
|
2
|
+
* Capture stderr and log if debug is true (rsanheim)
|
3
|
+
|
4
|
+
== 0.8.2 / 2008-06-27
|
5
|
+
* Allow user provided logger (rsanheim)
|
6
|
+
|
1
7
|
== 0.8.0 / 2008-04-24
|
2
8
|
* Lots of fixes and additions
|
3
9
|
|
4
10
|
== 0.7.0 / 2008-01-07
|
5
11
|
* First public release!
|
6
12
|
|
13
|
+
|
data/Manifest.txt
CHANGED
@@ -3,19 +3,33 @@ Manifest.txt
|
|
3
3
|
README.txt
|
4
4
|
Rakefile
|
5
5
|
grit.gemspec
|
6
|
-
lib/grit.rb
|
7
6
|
lib/grit/actor.rb
|
8
7
|
lib/grit/blob.rb
|
9
8
|
lib/grit/commit.rb
|
9
|
+
lib/grit/commit_stats.rb
|
10
10
|
lib/grit/config.rb
|
11
11
|
lib/grit/diff.rb
|
12
12
|
lib/grit/errors.rb
|
13
|
+
lib/grit/git-ruby/commit_db.rb
|
14
|
+
lib/grit/git-ruby/file_index.rb
|
15
|
+
lib/grit/git-ruby/git_object.rb
|
16
|
+
lib/grit/git-ruby/internal/loose.rb
|
17
|
+
lib/grit/git-ruby/internal/mmap.rb
|
18
|
+
lib/grit/git-ruby/internal/pack.rb
|
19
|
+
lib/grit/git-ruby/internal/raw_object.rb
|
20
|
+
lib/grit/git-ruby/object.rb
|
21
|
+
lib/grit/git-ruby/repository.rb
|
22
|
+
lib/grit/git-ruby.rb
|
13
23
|
lib/grit/git.rb
|
14
24
|
lib/grit/head.rb
|
25
|
+
lib/grit/index.rb
|
15
26
|
lib/grit/lazy.rb
|
27
|
+
lib/grit/ref.rb
|
16
28
|
lib/grit/repo.rb
|
29
|
+
lib/grit/status.rb
|
17
30
|
lib/grit/tag.rb
|
18
31
|
lib/grit/tree.rb
|
32
|
+
lib/grit.rb
|
19
33
|
test/fixtures/blame
|
20
34
|
test/fixtures/cat_file_blob
|
21
35
|
test/fixtures/cat_file_blob_size
|
@@ -27,6 +41,7 @@ test/fixtures/diff_mode_only
|
|
27
41
|
test/fixtures/diff_new_mode
|
28
42
|
test/fixtures/diff_p
|
29
43
|
test/fixtures/for_each_ref
|
44
|
+
test/fixtures/for_each_ref_remotes
|
30
45
|
test/fixtures/for_each_ref_tags
|
31
46
|
test/fixtures/ls_tree_a
|
32
47
|
test/fixtures/ls_tree_b
|
@@ -46,8 +61,10 @@ test/test_commit.rb
|
|
46
61
|
test/test_config.rb
|
47
62
|
test/test_diff.rb
|
48
63
|
test/test_git.rb
|
64
|
+
test/test_grit.rb
|
49
65
|
test/test_head.rb
|
50
66
|
test/test_reality.rb
|
67
|
+
test/test_remote.rb
|
51
68
|
test/test_repo.rb
|
52
69
|
test/test_tag.rb
|
53
70
|
test/test_tree.rb
|
data/grit.gemspec
CHANGED
@@ -1,16 +1,62 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
s.name
|
3
|
-
s.version
|
4
|
-
s.date
|
5
|
-
s.summary
|
6
|
-
s.email
|
7
|
-
s.homepage = "http://github.com/
|
2
|
+
s.name = "grit"
|
3
|
+
s.version = "0.9.3"
|
4
|
+
s.date = "2008-04-24"
|
5
|
+
s.summary = "Object model interface to a git repo"
|
6
|
+
s.email = "tom@rubyisawesome.com"
|
7
|
+
s.homepage = "http://github.com/schacon/grit"
|
8
8
|
s.description = "Grit is a Ruby library for extracting information from a git repository in and object oriented manner."
|
9
9
|
s.has_rdoc = true
|
10
|
-
s.authors
|
11
|
-
s.files
|
12
|
-
|
10
|
+
s.authors = ["Tom Preston-Werner", "Scott Chacon"]
|
11
|
+
s.files = ["History.txt",
|
12
|
+
"Manifest.txt",
|
13
|
+
"README.txt",
|
14
|
+
"Rakefile",
|
15
|
+
"grit.gemspec",
|
16
|
+
"lib/grit/actor.rb",
|
17
|
+
"lib/grit/blob.rb",
|
18
|
+
"lib/grit/commit.rb",
|
19
|
+
"lib/grit/commit_stats.rb",
|
20
|
+
"lib/grit/config.rb",
|
21
|
+
"lib/grit/diff.rb",
|
22
|
+
"lib/grit/errors.rb",
|
23
|
+
"lib/grit/git-ruby/commit_db.rb",
|
24
|
+
"lib/grit/git-ruby/file_index.rb",
|
25
|
+
"lib/grit/git-ruby/git_object.rb",
|
26
|
+
"lib/grit/git-ruby/internal",
|
27
|
+
"lib/grit/git-ruby/internal/loose.rb",
|
28
|
+
"lib/grit/git-ruby/internal/mmap.rb",
|
29
|
+
"lib/grit/git-ruby/internal/pack.rb",
|
30
|
+
"lib/grit/git-ruby/internal/raw_object.rb",
|
31
|
+
"lib/grit/git-ruby/object.rb",
|
32
|
+
"lib/grit/git-ruby/repository.rb",
|
33
|
+
"lib/grit/git-ruby.rb",
|
34
|
+
"lib/grit/git.rb",
|
35
|
+
"lib/grit/head.rb",
|
36
|
+
"lib/grit/index.rb",
|
37
|
+
"lib/grit/lazy.rb",
|
38
|
+
"lib/grit/ref.rb",
|
39
|
+
"lib/grit/repo.rb",
|
40
|
+
"lib/grit/status.rb",
|
41
|
+
"lib/grit/tag.rb",
|
42
|
+
"lib/grit/tree.rb",
|
43
|
+
"lib/grit.rb"]
|
44
|
+
s.test_files = ["test/test_actor.rb",
|
45
|
+
"test/test_blob.rb", "test/test_commit.rb",
|
46
|
+
"test/test_config.rb",
|
47
|
+
"test/test_diff.rb",
|
48
|
+
"test/test_git.rb",
|
49
|
+
"test/test_grit.rb",
|
50
|
+
"test/test_head.rb",
|
51
|
+
"test/test_real.rb",
|
52
|
+
"test/test_reality.rb",
|
53
|
+
"test/test_remote.rb",
|
54
|
+
"test/test_repo.rb",
|
55
|
+
"test/test_tag.rb",
|
56
|
+
"test/test_tree.rb"]
|
13
57
|
s.rdoc_options = ["--main", "README.txt"]
|
14
58
|
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
|
59
|
+
s.add_dependency("diff-lcs", ["> 0.0.0"])
|
15
60
|
s.add_dependency("mime-types", ["> 0.0.0"])
|
16
|
-
|
61
|
+
s.add_dependency("open4", ["> 0.0.0"])
|
62
|
+
end
|
@@ -6,32 +6,48 @@ require 'time'
|
|
6
6
|
|
7
7
|
# stdlib
|
8
8
|
require 'timeout'
|
9
|
+
require 'logger'
|
9
10
|
|
10
11
|
# third party
|
11
12
|
require 'rubygems'
|
12
13
|
require 'mime/types'
|
13
14
|
require 'open4'
|
15
|
+
require 'digest/sha1'
|
14
16
|
|
15
17
|
# internal requires
|
16
18
|
require 'grit/lazy'
|
17
19
|
require 'grit/errors'
|
20
|
+
require 'grit/git-ruby'
|
18
21
|
require 'grit/git'
|
19
|
-
require 'grit/
|
20
|
-
require 'grit/tag'
|
22
|
+
require 'grit/ref'
|
21
23
|
require 'grit/commit'
|
24
|
+
require 'grit/commit_stats'
|
22
25
|
require 'grit/tree'
|
23
26
|
require 'grit/blob'
|
24
27
|
require 'grit/actor'
|
25
28
|
require 'grit/diff'
|
26
29
|
require 'grit/config'
|
27
30
|
require 'grit/repo'
|
31
|
+
require 'grit/index'
|
32
|
+
require 'grit/status'
|
33
|
+
|
28
34
|
|
29
35
|
module Grit
|
36
|
+
|
30
37
|
class << self
|
38
|
+
# Set +debug+ to true to log all git calls and responses
|
31
39
|
attr_accessor :debug
|
40
|
+
attr_accessor :use_git_ruby
|
41
|
+
# The standard +logger+ for debugging git calls - this defaults to a plain STDOUT logger
|
42
|
+
attr_accessor :logger
|
43
|
+
def log(str)
|
44
|
+
logger.debug { str }
|
45
|
+
end
|
32
46
|
end
|
33
|
-
|
34
47
|
self.debug = false
|
48
|
+
self.use_git_ruby = true
|
49
|
+
|
50
|
+
@logger ||= ::Logger.new(STDOUT)
|
35
51
|
|
36
|
-
VERSION = '0.
|
52
|
+
VERSION = '0.9.1'
|
37
53
|
end
|
data/lib/grit/commit.rb
CHANGED
@@ -36,7 +36,7 @@ module Grit
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def id_abbrev
|
39
|
-
@id_abbrev ||= @repo.git.rev_parse({
|
39
|
+
@id_abbrev ||= @repo.git.rev_parse({}, self.id).chomp[0, 7]
|
40
40
|
end
|
41
41
|
|
42
42
|
# Create an unbaked Commit containing just the specified attributes
|
@@ -84,7 +84,7 @@ module Grit
|
|
84
84
|
# Returns Grit::Commit[] (baked)
|
85
85
|
def self.find_all(repo, ref, options = {})
|
86
86
|
allowed_options = [:max_count, :skip, :since]
|
87
|
-
|
87
|
+
|
88
88
|
default_options = {:pretty => "raw"}
|
89
89
|
actual_options = default_options.merge(options)
|
90
90
|
|
@@ -93,8 +93,10 @@ module Grit
|
|
93
93
|
else
|
94
94
|
output = repo.git.rev_list(actual_options.merge(:all => true))
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
self.list_from_string(repo, output)
|
98
|
+
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
99
|
+
[]
|
98
100
|
end
|
99
101
|
|
100
102
|
# Parse out commit information into an array of baked Commit objects
|
@@ -102,11 +104,15 @@ module Grit
|
|
102
104
|
# +text+ is the text output from the git command (raw format)
|
103
105
|
#
|
104
106
|
# Returns Grit::Commit[] (baked)
|
107
|
+
#
|
108
|
+
# really should re-write this to be more accepting of non-standard commit messages
|
109
|
+
# - it broke when 'encoding' was introduced - not sure what else might show up
|
110
|
+
#
|
105
111
|
def self.list_from_string(repo, text)
|
106
112
|
lines = text.split("\n")
|
107
113
|
|
108
114
|
commits = []
|
109
|
-
|
115
|
+
|
110
116
|
while !lines.empty?
|
111
117
|
id = lines.shift.split.last
|
112
118
|
tree = lines.shift.split.last
|
@@ -117,6 +123,9 @@ module Grit
|
|
117
123
|
author, authored_date = self.actor(lines.shift)
|
118
124
|
committer, committed_date = self.actor(lines.shift)
|
119
125
|
|
126
|
+
# not doing anything with this yet, but it's sometimes there
|
127
|
+
encoding = lines.shift.split.last if lines.first =~ /^encoding/
|
128
|
+
|
120
129
|
lines.shift
|
121
130
|
|
122
131
|
message_lines = []
|
@@ -151,15 +160,19 @@ module Grit
|
|
151
160
|
Diff.list_from_string(repo, text)
|
152
161
|
end
|
153
162
|
|
163
|
+
def show
|
164
|
+
diff = @repo.git.show({:full_index => true, :pretty => 'raw'}, @id)
|
165
|
+
if diff =~ /diff --git a/
|
166
|
+
diff = diff.sub(/.+?(diff --git a)/m, '\1')
|
167
|
+
else
|
168
|
+
diff = ''
|
169
|
+
end
|
170
|
+
Diff.list_from_string(@repo, diff)
|
171
|
+
end
|
172
|
+
|
154
173
|
def diffs
|
155
174
|
if parents.empty?
|
156
|
-
|
157
|
-
if diff =~ /diff --git a/
|
158
|
-
diff = diff.sub(/.+?(diff --git a)/m, '\1')
|
159
|
-
else
|
160
|
-
diff = ''
|
161
|
-
end
|
162
|
-
Diff.list_from_string(@repo, diff)
|
175
|
+
show
|
163
176
|
else
|
164
177
|
self.class.diff(@repo, parents.first.id, @id)
|
165
178
|
end
|
@@ -169,6 +182,14 @@ module Grit
|
|
169
182
|
def to_s
|
170
183
|
@id
|
171
184
|
end
|
185
|
+
|
186
|
+
def sha
|
187
|
+
@id
|
188
|
+
end
|
189
|
+
|
190
|
+
def date
|
191
|
+
@committed_date
|
192
|
+
end
|
172
193
|
|
173
194
|
# Pretty object inspection
|
174
195
|
def inspect
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class CommitStats
|
4
|
+
|
5
|
+
attr_reader :id, :files, :additions, :deletions, :total
|
6
|
+
|
7
|
+
# Instantiate a new CommitStats
|
8
|
+
# +id+ is the id of the commit
|
9
|
+
# +files+ is an array of :
|
10
|
+
# [ [filename, adds, deletes, total],
|
11
|
+
# [filename, adds, deletes, total],
|
12
|
+
# [filename, adds, deletes, total] ]
|
13
|
+
#
|
14
|
+
# Returns Grit::CommitStats (baked)
|
15
|
+
def initialize(repo, id, files)
|
16
|
+
@repo = repo
|
17
|
+
@id = id
|
18
|
+
@files = files
|
19
|
+
@additions = files.inject(0) { |total, a| total += a[1] }
|
20
|
+
@deletions = files.inject(0) { |total, a| total += a[2] }
|
21
|
+
@total = files.inject(0) { |total, a| total += a[3] }
|
22
|
+
end
|
23
|
+
|
24
|
+
# Find all commit stats matching the given criteria.
|
25
|
+
# +repo+ is the Repo
|
26
|
+
# +ref+ is the ref from which to begin (SHA1 or name) or nil for --all
|
27
|
+
# +options+ is a Hash of optional arguments to git
|
28
|
+
# :max_count is the maximum number of commits to fetch
|
29
|
+
# :skip is the number of commits to skip
|
30
|
+
#
|
31
|
+
# Returns assoc array [sha, Grit::Commit[] (baked)]
|
32
|
+
def self.find_all(repo, ref, options = {})
|
33
|
+
allowed_options = [:max_count, :skip, :since]
|
34
|
+
|
35
|
+
default_options = {:numstat => true}
|
36
|
+
actual_options = default_options.merge(options)
|
37
|
+
|
38
|
+
if ref
|
39
|
+
output = repo.git.log(actual_options, ref)
|
40
|
+
else
|
41
|
+
output = repo.git.log(actual_options.merge(:all => true))
|
42
|
+
end
|
43
|
+
|
44
|
+
self.list_from_string(repo, output)
|
45
|
+
end
|
46
|
+
|
47
|
+
# Parse out commit information into an array of baked Commit objects
|
48
|
+
# +repo+ is the Repo
|
49
|
+
# +text+ is the text output from the git command (raw format)
|
50
|
+
#
|
51
|
+
# Returns assoc array [sha, Grit::Commit[] (baked)]
|
52
|
+
def self.list_from_string(repo, text)
|
53
|
+
lines = text.split("\n")
|
54
|
+
|
55
|
+
commits = []
|
56
|
+
|
57
|
+
while !lines.empty?
|
58
|
+
id = lines.shift.split.last
|
59
|
+
|
60
|
+
lines.shift
|
61
|
+
lines.shift
|
62
|
+
lines.shift
|
63
|
+
|
64
|
+
message_lines = []
|
65
|
+
message_lines << lines.shift[4..-1] while lines.first =~ /^ {4}/
|
66
|
+
|
67
|
+
lines.shift while lines.first && lines.first.empty?
|
68
|
+
|
69
|
+
files = []
|
70
|
+
while lines.first =~ /^(\d+)\s+(\d+)\s+(.+)/
|
71
|
+
(additions, deletions, filename) = lines.shift.split
|
72
|
+
additions = additions.to_i
|
73
|
+
deletions = deletions.to_i
|
74
|
+
total = additions + deletions
|
75
|
+
files << [filename, additions, deletions, total]
|
76
|
+
end
|
77
|
+
|
78
|
+
lines.shift while lines.first && lines.first.empty?
|
79
|
+
|
80
|
+
commits << [id, CommitStats.new(repo, id, files)]
|
81
|
+
end
|
82
|
+
|
83
|
+
commits
|
84
|
+
end
|
85
|
+
|
86
|
+
# Pretty object inspection
|
87
|
+
def inspect
|
88
|
+
%Q{#<Grit::CommitStats "#{@id}">}
|
89
|
+
end
|
90
|
+
|
91
|
+
# private
|
92
|
+
|
93
|
+
def to_hash
|
94
|
+
{
|
95
|
+
'id' => id,
|
96
|
+
'files' => files,
|
97
|
+
'additions' => additions,
|
98
|
+
'deletions' => deletions,
|
99
|
+
'total' => total
|
100
|
+
}
|
101
|
+
end
|
102
|
+
end # CommitStats
|
103
|
+
|
104
|
+
end # Grit
|
@@ -0,0 +1,182 @@
|
|
1
|
+
require 'grit/git-ruby/repository'
|
2
|
+
require 'grit/git-ruby/file_index'
|
3
|
+
|
4
|
+
module Grit
|
5
|
+
|
6
|
+
# the functions in this module intercept the calls to git binary
|
7
|
+
# made buy the grit objects and attempts to run them in pure ruby
|
8
|
+
# if it will be faster, or if the git binary is not available (!!TODO!!)
|
9
|
+
module GitRuby
|
10
|
+
|
11
|
+
attr_accessor :ruby_git_repo, :git_file_index
|
12
|
+
|
13
|
+
def init(options)
|
14
|
+
if options.size == 0
|
15
|
+
Grit::GitRuby::Repository.init(@git_dir)
|
16
|
+
else
|
17
|
+
method_missing('init', options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def cat_file(options, ref)
|
22
|
+
if options[:t]
|
23
|
+
file_type(ref)
|
24
|
+
elsif options[:s]
|
25
|
+
file_size(ref)
|
26
|
+
elsif options[:p]
|
27
|
+
try_run { ruby_git.cat_file(ref) }
|
28
|
+
end
|
29
|
+
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
30
|
+
''
|
31
|
+
end
|
32
|
+
|
33
|
+
# lib/grit/tree.rb:16: output = repo.git.ls_tree({}, treeish, *paths)
|
34
|
+
def ls_tree(options, treeish, *paths)
|
35
|
+
sha = rev_parse({}, treeish)
|
36
|
+
ruby_git.ls_tree(sha, paths.flatten)
|
37
|
+
rescue Grit::GitRuby::Repository::NoSuchShaFound
|
38
|
+
''
|
39
|
+
end
|
40
|
+
|
41
|
+
# git diff --full-index 'ec037431382e83c3e95d4f2b3d145afbac8ea55d' 'f1ec1aea10986159456846b8a05615b87828d6c6'
|
42
|
+
def diff(options, sha1, sha2)
|
43
|
+
try_run { ruby_git.diff(sha1, sha2, options) }
|
44
|
+
end
|
45
|
+
|
46
|
+
def rev_list(options, ref = 'master')
|
47
|
+
options.delete(:skip) if options[:skip].to_i == 0
|
48
|
+
allowed_options = [:max_count, :since, :until, :pretty] # this is all I can do right now
|
49
|
+
if ((options.keys - allowed_options).size > 0)
|
50
|
+
return method_missing('rev-list', options, ref)
|
51
|
+
elsif (options.size == 0)
|
52
|
+
# pure rev-list
|
53
|
+
begin
|
54
|
+
return file_index.commits_from(rev_parse({}, ref)).join("\n")
|
55
|
+
rescue
|
56
|
+
return method_missing('rev-list', options, ref)
|
57
|
+
end
|
58
|
+
else
|
59
|
+
aref = rev_parse({}, ref)
|
60
|
+
if aref.is_a? Array
|
61
|
+
return method_missing('rev-list', options, ref)
|
62
|
+
else
|
63
|
+
return try_run { ruby_git.rev_list(aref, options) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def rev_parse(options, string)
|
69
|
+
if string =~ /\.\./
|
70
|
+
(sha1, sha2) = string.split('..')
|
71
|
+
return [rev_parse({}, sha1), rev_parse({}, sha2)]
|
72
|
+
end
|
73
|
+
|
74
|
+
if /\w{40}/.match(string) # passing in a sha - just no-op it
|
75
|
+
return string.chomp
|
76
|
+
end
|
77
|
+
|
78
|
+
head = File.join(@git_dir, 'refs', 'heads', string)
|
79
|
+
return File.read(head).chomp if File.file?(head)
|
80
|
+
|
81
|
+
head = File.join(@git_dir, 'refs', 'remotes', string)
|
82
|
+
return File.read(head).chomp if File.file?(head)
|
83
|
+
|
84
|
+
head = File.join(@git_dir, 'refs', 'tags', string)
|
85
|
+
return File.read(head).chomp if File.file?(head)
|
86
|
+
|
87
|
+
## check packed-refs file, too
|
88
|
+
packref = File.join(@git_dir, 'packed-refs')
|
89
|
+
if File.file?(packref)
|
90
|
+
File.readlines(packref).each do |line|
|
91
|
+
if m = /^(\w{40}) refs\/.+?\/(.*?)$/.match(line)
|
92
|
+
next if !Regexp.new(string + '$').match(m[3])
|
93
|
+
return m[1].chomp
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
## !! more - partials and such !!
|
99
|
+
|
100
|
+
# revert to calling git - grr
|
101
|
+
return method_missing('rev-parse', {}, string).chomp
|
102
|
+
end
|
103
|
+
|
104
|
+
def file_size(ref)
|
105
|
+
try_run { ruby_git.cat_file_size(ref).to_s }
|
106
|
+
end
|
107
|
+
|
108
|
+
def file_type(ref)
|
109
|
+
try_run { ruby_git.cat_file_type(ref).to_s }
|
110
|
+
end
|
111
|
+
|
112
|
+
def blame_tree(commit, path = nil)
|
113
|
+
begin
|
114
|
+
commits = file_index.last_commits(rev_parse({}, commit), looking_for(commit, path))
|
115
|
+
clean_paths(commits)
|
116
|
+
rescue FileIndex::IndexFileNotFound
|
117
|
+
{}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def file_index
|
122
|
+
@git_file_index ||= FileIndex.new(@git_dir)
|
123
|
+
end
|
124
|
+
|
125
|
+
def ruby_git
|
126
|
+
@ruby_git_repo ||= Repository.new(@git_dir)
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def try_run
|
132
|
+
ret = ''
|
133
|
+
Timeout.timeout(self.class.git_timeout) do
|
134
|
+
ret = yield
|
135
|
+
end
|
136
|
+
@bytes_read += ret.size
|
137
|
+
|
138
|
+
#if @bytes_read > 5242880 # 5.megabytes
|
139
|
+
# bytes = @bytes_read
|
140
|
+
# @bytes_read = 0
|
141
|
+
# raise Grit::Git::GitTimeout.new(command, bytes)
|
142
|
+
#end
|
143
|
+
|
144
|
+
ret
|
145
|
+
rescue Timeout::Error => e
|
146
|
+
bytes = @bytes_read
|
147
|
+
@bytes_read = 0
|
148
|
+
raise Grit::Git::GitTimeout.new(command, bytes)
|
149
|
+
end
|
150
|
+
|
151
|
+
def looking_for(commit, path = nil)
|
152
|
+
tree_sha = ruby_git.get_subtree(rev_parse({}, commit), path)
|
153
|
+
|
154
|
+
looking_for = []
|
155
|
+
ruby_git.get_object_by_sha1(tree_sha).entry.each do |e|
|
156
|
+
if path && !(path == '' || path == '.' || path == './')
|
157
|
+
file = File.join(path, e.name)
|
158
|
+
else
|
159
|
+
file = e.name
|
160
|
+
end
|
161
|
+
file += '/' if e.type == :directory
|
162
|
+
looking_for << file
|
163
|
+
end
|
164
|
+
looking_for
|
165
|
+
end
|
166
|
+
|
167
|
+
def clean_paths(commit_array)
|
168
|
+
new_commits = {}
|
169
|
+
commit_array.each do |file, sha|
|
170
|
+
file = file.chop if file[file.size - 1 , 1] == '/'
|
171
|
+
new_commits[file] = sha
|
172
|
+
end
|
173
|
+
new_commits
|
174
|
+
end
|
175
|
+
|
176
|
+
# TODO
|
177
|
+
# git grep -n 'foo' 'master'
|
178
|
+
# git log --pretty='raw' --max-count='1' 'master' -- 'LICENSE'
|
179
|
+
# git log --pretty='raw' --max-count='1' 'master' -- 'test'
|
180
|
+
|
181
|
+
end
|
182
|
+
end
|