schleyfox-grit 2.3.0
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 +117 -0
- data/LICENSE +22 -0
- data/PURE_TODO +35 -0
- data/README.md +242 -0
- data/Rakefile +149 -0
- data/benchmarks.rb +129 -0
- data/benchmarks.txt +21 -0
- data/examples/ex_add_commit.rb +13 -0
- data/examples/ex_index.rb +21 -0
- data/lib/grit.rb +83 -0
- data/lib/grit/actor.rb +52 -0
- data/lib/grit/blame.rb +61 -0
- data/lib/grit/blob.rb +126 -0
- data/lib/grit/commit.rb +294 -0
- data/lib/grit/commit_stats.rb +128 -0
- data/lib/grit/config.rb +44 -0
- data/lib/grit/diff.rb +79 -0
- data/lib/grit/errors.rb +10 -0
- data/lib/grit/git-ruby.rb +272 -0
- data/lib/grit/git-ruby/commit_db.rb +52 -0
- data/lib/grit/git-ruby/file_index.rb +193 -0
- data/lib/grit/git-ruby/git_object.rb +350 -0
- data/lib/grit/git-ruby/internal/file_window.rb +58 -0
- data/lib/grit/git-ruby/internal/loose.rb +137 -0
- data/lib/grit/git-ruby/internal/pack.rb +384 -0
- data/lib/grit/git-ruby/internal/raw_object.rb +37 -0
- data/lib/grit/git-ruby/object.rb +325 -0
- data/lib/grit/git-ruby/repository.rb +775 -0
- data/lib/grit/git.rb +324 -0
- data/lib/grit/index.rb +197 -0
- data/lib/grit/lazy.rb +35 -0
- data/lib/grit/merge.rb +45 -0
- data/lib/grit/open3_detach.rb +46 -0
- data/lib/grit/ref.rb +78 -0
- data/lib/grit/repo.rb +657 -0
- data/lib/grit/ruby1.9.rb +7 -0
- data/lib/grit/status.rb +153 -0
- data/lib/grit/submodule.rb +88 -0
- data/lib/grit/tag.rb +71 -0
- data/lib/grit/tree.rb +125 -0
- metadata +141 -0
data/Rakefile
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
#############################################################################
|
6
|
+
#
|
7
|
+
# Helper functions
|
8
|
+
#
|
9
|
+
#############################################################################
|
10
|
+
|
11
|
+
def name
|
12
|
+
@name ||= Dir['*.gemspec'].first.split('.').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def version
|
16
|
+
line = File.read("lib/grit.rb")[/^\s*VERSION\s*=\s*.*/]
|
17
|
+
line.match(/.*VERSION\s*=\s*['"](.*)['"]/)[1]
|
18
|
+
end
|
19
|
+
|
20
|
+
def date
|
21
|
+
Date.today.to_s
|
22
|
+
end
|
23
|
+
|
24
|
+
def rubyforge_project
|
25
|
+
name
|
26
|
+
end
|
27
|
+
|
28
|
+
def gemspec_file
|
29
|
+
"#{name}.gemspec"
|
30
|
+
end
|
31
|
+
|
32
|
+
def gem_file
|
33
|
+
"#{name}-#{version}.gem"
|
34
|
+
end
|
35
|
+
|
36
|
+
def replace_header(head, header_name)
|
37
|
+
head.sub!(/(\.#{header_name}\s*= ').*'/) { "#{$1}#{send(header_name)}'"}
|
38
|
+
end
|
39
|
+
|
40
|
+
#############################################################################
|
41
|
+
#
|
42
|
+
# Standard tasks
|
43
|
+
#
|
44
|
+
#############################################################################
|
45
|
+
|
46
|
+
task :default => :test
|
47
|
+
|
48
|
+
require 'rake/testtask'
|
49
|
+
Rake::TestTask.new(:test) do |test|
|
50
|
+
test.libs << 'lib' << 'test' << '.'
|
51
|
+
test.pattern = 'test/**/test_*.rb'
|
52
|
+
test.verbose = true
|
53
|
+
end
|
54
|
+
|
55
|
+
desc "Generate RCov test coverage and open in your browser"
|
56
|
+
task :coverage do
|
57
|
+
require 'rcov'
|
58
|
+
sh "rm -fr coverage"
|
59
|
+
sh "rcov test/test_*.rb"
|
60
|
+
sh "open coverage/index.html"
|
61
|
+
end
|
62
|
+
|
63
|
+
require 'rake/rdoctask'
|
64
|
+
Rake::RDocTask.new do |rdoc|
|
65
|
+
rdoc.rdoc_dir = 'rdoc'
|
66
|
+
rdoc.title = "#{name} #{version}"
|
67
|
+
rdoc.rdoc_files.include('README*')
|
68
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Open an irb session preloaded with this library"
|
72
|
+
task :console do
|
73
|
+
sh "irb -rubygems -r ./lib/#{name}.rb"
|
74
|
+
end
|
75
|
+
|
76
|
+
#############################################################################
|
77
|
+
#
|
78
|
+
# Custom tasks (add your own tasks here)
|
79
|
+
#
|
80
|
+
#############################################################################
|
81
|
+
|
82
|
+
desc "Upload site to Rubyforge"
|
83
|
+
task :site do
|
84
|
+
sh "scp -r doc/* mojombo@grit.rubyforge.org:/var/www/gforge-projects/grit"
|
85
|
+
end
|
86
|
+
|
87
|
+
#############################################################################
|
88
|
+
#
|
89
|
+
# Packaging tasks
|
90
|
+
#
|
91
|
+
#############################################################################
|
92
|
+
|
93
|
+
task :release => :build do
|
94
|
+
unless `git branch` =~ /^\* master$/
|
95
|
+
puts "You must be on the master branch to release!"
|
96
|
+
exit!
|
97
|
+
end
|
98
|
+
sh "git commit --allow-empty -a -m 'Release #{version}'"
|
99
|
+
sh "git tag v#{version}"
|
100
|
+
sh "git push origin master"
|
101
|
+
sh "git push origin v#{version}"
|
102
|
+
sh "gem push pkg/#{name}-#{version}.gem"
|
103
|
+
end
|
104
|
+
|
105
|
+
task :build => :gemspec do
|
106
|
+
sh "mkdir -p pkg"
|
107
|
+
sh "gem build #{gemspec_file}"
|
108
|
+
sh "mv #{gem_file} pkg"
|
109
|
+
end
|
110
|
+
|
111
|
+
task :gemspec => :validate do
|
112
|
+
# read spec file and split out manifest section
|
113
|
+
spec = File.read(gemspec_file)
|
114
|
+
head, manifest, tail = spec.split(" # = MANIFEST =\n")
|
115
|
+
|
116
|
+
# replace name version and date
|
117
|
+
replace_header(head, :name)
|
118
|
+
replace_header(head, :version)
|
119
|
+
replace_header(head, :date)
|
120
|
+
#comment this out if your rubyforge_project has a different name
|
121
|
+
replace_header(head, :rubyforge_project)
|
122
|
+
|
123
|
+
# determine file list from git ls-files
|
124
|
+
files = `git ls-files`.
|
125
|
+
split("\n").
|
126
|
+
sort.
|
127
|
+
reject { |file| file =~ /^\./ }.
|
128
|
+
reject { |file| file =~ /^(rdoc|pkg|test)/ }.
|
129
|
+
map { |file| " #{file}" }.
|
130
|
+
join("\n")
|
131
|
+
|
132
|
+
# piece file back together and write
|
133
|
+
manifest = " s.files = %w[\n#{files}\n ]\n"
|
134
|
+
spec = [head, manifest, tail].join(" # = MANIFEST =\n")
|
135
|
+
File.open(gemspec_file, 'w') { |io| io.write(spec) }
|
136
|
+
puts "Updated #{gemspec_file}"
|
137
|
+
end
|
138
|
+
|
139
|
+
task :validate do
|
140
|
+
libfiles = Dir['lib/*'] - ["lib/grit.rb", "lib/grit"]
|
141
|
+
unless libfiles.empty?
|
142
|
+
puts "Directory `lib` should only contain a `#{name}.rb` file and `#{name}` dir."
|
143
|
+
exit!
|
144
|
+
end
|
145
|
+
unless Dir['VERSION*'].empty?
|
146
|
+
puts "A `VERSION` file at root level violates Gem best practices."
|
147
|
+
exit!
|
148
|
+
end
|
149
|
+
end
|
data/benchmarks.rb
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'benchmark'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'ruby-prof'
|
5
|
+
require 'memcache'
|
6
|
+
require 'pp'
|
7
|
+
|
8
|
+
|
9
|
+
#require 'grit'
|
10
|
+
require 'lib/grit'
|
11
|
+
|
12
|
+
def main
|
13
|
+
@wbare = File.expand_path(File.join('test', 'dot_git'))
|
14
|
+
|
15
|
+
in_temp_dir do
|
16
|
+
#result = RubyProf.profile do
|
17
|
+
|
18
|
+
git = Grit::Repo.new('.')
|
19
|
+
puts Grit::VERSION
|
20
|
+
|
21
|
+
Grit::GitRuby.use_commit_db = true
|
22
|
+
#Grit::GitRuby.cache_client = MemCache.new 'localhost:11211', :namespace => 'grit'
|
23
|
+
#Grit.debug = true
|
24
|
+
|
25
|
+
#pp Grit::GitRuby.cache_client.stats
|
26
|
+
|
27
|
+
commit1 = '5e3ee1198672257164ce3fe31dea3e40848e68d5'
|
28
|
+
commit2 = 'ca8a30f5a7f0f163bbe3b6f0abf18a6c83b0687a'
|
29
|
+
|
30
|
+
Benchmark.bm(8) do |x|
|
31
|
+
|
32
|
+
run_code(x, 'packobj') do
|
33
|
+
@commit = git.commit('5e3ee1198672257164ce3fe31dea3e40848e68d5')
|
34
|
+
@tree = git.tree('cd7422af5a2e0fff3e94d6fb1a8fff03b2841881')
|
35
|
+
@blob = git.blob('4232d073306f01cf0b895864e5a5cfad7dd76fce')
|
36
|
+
@commit.parents[0].parents[0].parents[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
run_code(x, 'commits 1') do
|
40
|
+
git.commits.size
|
41
|
+
end
|
42
|
+
|
43
|
+
run_code(x, 'commits 2') do
|
44
|
+
log = git.commits('master', 15)
|
45
|
+
log.size
|
46
|
+
log.size
|
47
|
+
log.first
|
48
|
+
git.commits('testing').map { |c| c.message }
|
49
|
+
end
|
50
|
+
|
51
|
+
run_code(x, 'big revlist') do
|
52
|
+
c = git.commits('master', 200)
|
53
|
+
end
|
54
|
+
|
55
|
+
run_code(x, 'log') do
|
56
|
+
log = git.log('master')
|
57
|
+
log.size
|
58
|
+
log.size
|
59
|
+
log.first
|
60
|
+
end
|
61
|
+
|
62
|
+
run_code(x, 'diff') do
|
63
|
+
c = git.diff(commit1, commit2)
|
64
|
+
end
|
65
|
+
|
66
|
+
run_code(x, 'commit-diff') do
|
67
|
+
c = git.commit_diff(commit1)
|
68
|
+
end
|
69
|
+
|
70
|
+
run_code(x, 'heads') do
|
71
|
+
c = git.heads.collect { |b| b.commit.id }
|
72
|
+
end
|
73
|
+
|
74
|
+
# run_code(x, 'config', 100) do
|
75
|
+
# c = git.config['user.name']
|
76
|
+
# c = git.config['user.email']
|
77
|
+
# end
|
78
|
+
|
79
|
+
#run_code(x, 'commit count') do
|
80
|
+
# c = git.commit_count('testing')
|
81
|
+
#end
|
82
|
+
|
83
|
+
|
84
|
+
end
|
85
|
+
#end
|
86
|
+
|
87
|
+
#printer = RubyProf::FlatPrinter.new(result)
|
88
|
+
#printer.print(STDOUT, 0)
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def run_code(x, name, times = 30)
|
97
|
+
x.report(name.ljust(12)) do
|
98
|
+
for i in 1..times do
|
99
|
+
yield i
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
#end
|
104
|
+
|
105
|
+
# Print a graph profile to text
|
106
|
+
end
|
107
|
+
|
108
|
+
def new_file(name, contents)
|
109
|
+
File.open(name, 'w') do |f|
|
110
|
+
f.puts contents
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
|
115
|
+
def in_temp_dir(remove_after = true)
|
116
|
+
filename = 'git_test' + Time.now.to_i.to_s + rand(300).to_s.rjust(3, '0')
|
117
|
+
tmp_path = File.join("/tmp/", filename)
|
118
|
+
FileUtils.mkdir(tmp_path)
|
119
|
+
Dir.chdir tmp_path do
|
120
|
+
FileUtils.cp_r(@wbare, File.join(tmp_path, '.git'))
|
121
|
+
yield tmp_path
|
122
|
+
end
|
123
|
+
puts tmp_path
|
124
|
+
#FileUtils.rm_r(tmp_path) if remove_after
|
125
|
+
end
|
126
|
+
|
127
|
+
main()
|
128
|
+
|
129
|
+
##pp Grit::GitRuby.cache_client.stats
|
data/benchmarks.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Grit :
|
2
|
+
user system total real
|
3
|
+
packobj 0.030000 0.270000 1.380000 ( 1.507250)
|
4
|
+
commits 1 0.030000 0.070000 0.390000 ( 0.409931)
|
5
|
+
commits 2 0.110000 0.170000 0.860000 ( 0.896371)
|
6
|
+
log 0.350000 0.130000 0.850000 ( 0.875035)
|
7
|
+
diff 0.190000 0.140000 1.940000 ( 2.031911)
|
8
|
+
commit-diff 0.540000 0.220000 1.390000 ( 1.463839)
|
9
|
+
heads 0.010000 0.070000 0.390000 ( 0.413918)
|
10
|
+
|
11
|
+
|
12
|
+
Grit (with GitRuby) :
|
13
|
+
|
14
|
+
user system total real
|
15
|
+
packobj 0.050000 0.010000 0.060000 ( 0.078318)
|
16
|
+
commits 1 0.150000 0.010000 0.160000 ( 0.174296)
|
17
|
+
commits 2 0.440000 0.040000 0.480000 ( 0.522310)
|
18
|
+
log 0.490000 0.040000 0.530000 ( 0.538128)
|
19
|
+
diff 0.370000 0.230000 2.250000 ( 2.255974)
|
20
|
+
commit-diff 0.580000 0.260000 1.500000 ( 1.553000)
|
21
|
+
heads 0.020000 0.100000 0.430000 ( 0.455464)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require '../lib/grit'
|
2
|
+
|
3
|
+
count = 1
|
4
|
+
Dir.chdir("/Users/schacon/projects/atest") do
|
5
|
+
r = Grit::Repo.new('.')
|
6
|
+
while(count < 10) do
|
7
|
+
fname = Time.now.to_i.to_s + count.to_s
|
8
|
+
File.open(fname, 'w') { |f| f.write('hellor ' + fname) }
|
9
|
+
r.add(fname)
|
10
|
+
count += 1
|
11
|
+
end
|
12
|
+
r.commit_index('my commit')
|
13
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require '../lib/grit'
|
2
|
+
|
3
|
+
count = 1
|
4
|
+
Dir.chdir("/Users/schacon/projects/atest") do
|
5
|
+
r = Grit::Repo.new('.')
|
6
|
+
i = r.index
|
7
|
+
while(count < 10) do
|
8
|
+
fname = Time.now.to_i.to_s + count.to_s
|
9
|
+
i.add(fname, 'hello ' + fname)
|
10
|
+
count += 1
|
11
|
+
end
|
12
|
+
count = 5
|
13
|
+
while(count < 10) do
|
14
|
+
puts "HELLO"
|
15
|
+
fname = Time.now.to_i.to_s + count.to_s
|
16
|
+
i.add('test/' + fname, 'hello ' + fname)
|
17
|
+
count += 1
|
18
|
+
end
|
19
|
+
puts i.commit('my commit')
|
20
|
+
puts i.inspect
|
21
|
+
end
|
data/lib/grit.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) # For use/testing when no gem is installed
|
2
|
+
|
3
|
+
# core
|
4
|
+
require 'fileutils'
|
5
|
+
require 'time'
|
6
|
+
|
7
|
+
# stdlib
|
8
|
+
require 'timeout'
|
9
|
+
require 'logger'
|
10
|
+
require 'digest/sha1'
|
11
|
+
|
12
|
+
if defined? RUBY_ENGINE && RUBY_ENGINE == 'jruby'
|
13
|
+
require 'open3'
|
14
|
+
elsif RUBY_PLATFORM.downcase =~ /mswin(?!ce)|mingw|bccwin/
|
15
|
+
require 'win32/open3'
|
16
|
+
else
|
17
|
+
require 'grit/open3_detach'
|
18
|
+
end
|
19
|
+
|
20
|
+
# third party
|
21
|
+
|
22
|
+
begin
|
23
|
+
require 'mime/types'
|
24
|
+
require 'rubygems'
|
25
|
+
rescue LoadError
|
26
|
+
require 'rubygems'
|
27
|
+
begin
|
28
|
+
gem "mime-types", ">=0"
|
29
|
+
require 'mime/types'
|
30
|
+
rescue Gem::LoadError => e
|
31
|
+
puts "WARNING: Gem LoadError: #{e.message}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# ruby 1.9 compatibility
|
36
|
+
require 'grit/ruby1.9'
|
37
|
+
|
38
|
+
# internal requires
|
39
|
+
require 'grit/lazy'
|
40
|
+
require 'grit/errors'
|
41
|
+
require 'grit/git-ruby'
|
42
|
+
require 'grit/git' unless defined? Grit::Git
|
43
|
+
require 'grit/ref'
|
44
|
+
require 'grit/tag'
|
45
|
+
require 'grit/commit'
|
46
|
+
require 'grit/commit_stats'
|
47
|
+
require 'grit/tree'
|
48
|
+
require 'grit/blob'
|
49
|
+
require 'grit/actor'
|
50
|
+
require 'grit/diff'
|
51
|
+
require 'grit/config'
|
52
|
+
require 'grit/repo'
|
53
|
+
require 'grit/index'
|
54
|
+
require 'grit/status'
|
55
|
+
require 'grit/submodule'
|
56
|
+
require 'grit/blame'
|
57
|
+
require 'grit/merge'
|
58
|
+
|
59
|
+
module Grit
|
60
|
+
VERSION = '2.3.0'
|
61
|
+
|
62
|
+
class << self
|
63
|
+
# Set +debug+ to true to log all git calls and responses
|
64
|
+
attr_accessor :debug
|
65
|
+
attr_accessor :use_git_ruby
|
66
|
+
attr_accessor :no_quote
|
67
|
+
|
68
|
+
# The standard +logger+ for debugging git calls - this defaults to a plain STDOUT logger
|
69
|
+
attr_accessor :logger
|
70
|
+
def log(str)
|
71
|
+
logger.debug { str }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
self.debug = false
|
75
|
+
self.use_git_ruby = true
|
76
|
+
self.no_quote = false
|
77
|
+
|
78
|
+
@logger ||= ::Logger.new(STDOUT)
|
79
|
+
|
80
|
+
def self.version
|
81
|
+
VERSION
|
82
|
+
end
|
83
|
+
end
|
data/lib/grit/actor.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
module Grit
|
2
|
+
|
3
|
+
class Actor
|
4
|
+
attr_reader :name
|
5
|
+
attr_reader :email
|
6
|
+
|
7
|
+
def initialize(name, email)
|
8
|
+
@name = name
|
9
|
+
@email = email
|
10
|
+
end
|
11
|
+
alias_method :to_s, :name
|
12
|
+
|
13
|
+
# Create an Actor from a string.
|
14
|
+
#
|
15
|
+
# str - The String in this format: 'John Doe <jdoe@example.com>'
|
16
|
+
#
|
17
|
+
# Returns Git::Actor.
|
18
|
+
def self.from_string(str)
|
19
|
+
case str
|
20
|
+
when /<.+>/
|
21
|
+
m, name, email = *str.match(/(.*) <(.+?)>/)
|
22
|
+
return self.new(name, email)
|
23
|
+
else
|
24
|
+
return self.new(str, nil)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Outputs an actor string for Git commits.
|
29
|
+
#
|
30
|
+
# actor = Actor.new('bob', 'bob@email.com')
|
31
|
+
# actor.output(time) # => "bob <bob@email.com> UNIX_TIME +0700"
|
32
|
+
#
|
33
|
+
# time - The Time the commit was authored or committed.
|
34
|
+
#
|
35
|
+
# Returns a String.
|
36
|
+
def output(time)
|
37
|
+
out = @name.to_s.dup
|
38
|
+
if @email
|
39
|
+
out << " <#{@email}>"
|
40
|
+
end
|
41
|
+
hours = (time.utc_offset.to_f / 3600).to_i # 60 * 60, seconds to hours
|
42
|
+
rem = time.utc_offset.abs % 3600
|
43
|
+
out << " #{time.to_i} #{hours >= 0 ? :+ : :-}#{hours.abs.to_s.rjust(2, '0')}#{rem.to_s.rjust(2, '0')}"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Pretty object inspection
|
47
|
+
def inspect
|
48
|
+
%Q{#<Grit::Actor "#{@name} <#{@email}>">}
|
49
|
+
end
|
50
|
+
end # Actor
|
51
|
+
|
52
|
+
end # Grit
|