gitrb 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +4 -20
- data/gitrb.gemspec +11 -11
- data/lib/gitrb/repository.rb +29 -19
- data/lib/gitrb/trie.rb +59 -40
- data/lib/gitrb/util.rb +8 -8
- data/test/{bare_repository_spec.rb → bare_repository_test.rb} +4 -8
- data/test/benchmark.rb +0 -2
- data/test/{commit_spec.rb → commit_test.rb} +8 -33
- data/test/helper.rb +23 -0
- data/test/profile.rb +26 -0
- data/test/{repository_spec.rb → repository_test.rb} +83 -76
- data/test/{tree_spec.rb → tree_test.rb} +9 -15
- data/test/trie_test.rb +96 -0
- metadata +24 -13
- data/test/trie_spec.rb +0 -26
data/Rakefile
CHANGED
@@ -1,24 +1,11 @@
|
|
1
1
|
require 'rake'
|
2
2
|
require 'rake/rdoctask'
|
3
3
|
|
4
|
-
|
5
|
-
require 'spec/rake/spectask'
|
6
|
-
rescue LoadError
|
7
|
-
puts %{To use rspec for testing you must install the rspec gem:
|
8
|
-
gem install rspec}
|
9
|
-
exit 0
|
10
|
-
end
|
11
|
-
|
12
|
-
desc "Run all specs"
|
13
|
-
Spec::Rake::SpecTask.new(:spec) do |t|
|
14
|
-
t.spec_opts = ['-cfs', '--backtrace']
|
15
|
-
t.spec_files = FileList['test/**/*_spec.rb']
|
16
|
-
end
|
4
|
+
task :default => :test
|
17
5
|
|
18
|
-
desc
|
19
|
-
|
20
|
-
t.
|
21
|
-
t.spec_files = FileList['test/*_spec.rb']
|
6
|
+
desc 'Run tests with bacon'
|
7
|
+
task :test => FileList['test/*_test.rb'] do |t|
|
8
|
+
sh "bacon -q -Ilib:test #{t.prerequisites.join(' ')}"
|
22
9
|
end
|
23
10
|
|
24
11
|
desc "Generate the RDoc"
|
@@ -28,6 +15,3 @@ Rake::RDocTask.new do |rdoc|
|
|
28
15
|
rdoc.main = "README.md"
|
29
16
|
rdoc.title = "Gitrb"
|
30
17
|
end
|
31
|
-
|
32
|
-
desc "Run the rspec"
|
33
|
-
task :default => :spec
|
data/gitrb.gemspec
CHANGED
@@ -1,17 +1,15 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'gitrb'
|
3
|
-
s.version = '0.1.
|
3
|
+
s.version = '0.1.6'
|
4
4
|
s.summary = 'Pure ruby git implementation'
|
5
5
|
s.author = 'Daniel Mendler'
|
6
6
|
s.email = 'mail@daniel-mendler.de'
|
7
7
|
s.homepage = 'https://github.com/minad/gitrb'
|
8
8
|
s.rubyforge_project = %q{gitrb}
|
9
|
-
s.description =
|
10
|
-
Pure ruby git implementation similar to grit.
|
11
|
-
END
|
9
|
+
s.description = 'Fast and lightweight ruby git implementation'
|
12
10
|
s.require_path = 'lib'
|
13
11
|
s.has_rdoc = true
|
14
|
-
s.extra_rdoc_files = ['README.md']
|
12
|
+
s.extra_rdoc_files = ['README.md']
|
15
13
|
s.files = %w{
|
16
14
|
LICENSE
|
17
15
|
README.md
|
@@ -30,12 +28,14 @@ lib/gitrb/tree.rb
|
|
30
28
|
lib/gitrb/trie.rb
|
31
29
|
lib/gitrb/user.rb
|
32
30
|
lib/gitrb/util.rb
|
33
|
-
test/
|
31
|
+
test/bare_repository_test.rb
|
34
32
|
test/benchmark.rb
|
35
|
-
test/
|
36
|
-
test/
|
37
|
-
test/
|
38
|
-
test/
|
33
|
+
test/commit_test.rb
|
34
|
+
test/helper.rb
|
35
|
+
test/profile.rb
|
36
|
+
test/repository_test.rb
|
37
|
+
test/trie_test.rb
|
38
|
+
test/tree_test.rb
|
39
39
|
}
|
40
|
+
s.add_development_dependency('bacon')
|
40
41
|
end
|
41
|
-
|
data/lib/gitrb/repository.rb
CHANGED
@@ -83,7 +83,14 @@ module Gitrb
|
|
83
83
|
end
|
84
84
|
|
85
85
|
# Diff
|
86
|
-
|
86
|
+
# Options:
|
87
|
+
# :to - Required target commit
|
88
|
+
# :from - Optional source commit (otherwise comparision with empty tree)
|
89
|
+
# :path - Restrict to path
|
90
|
+
# :detect_renames - Detect renames O(n^2)
|
91
|
+
# :detect_copies - Detect copies O(n^2), very slow
|
92
|
+
def diff(opts)
|
93
|
+
from, to = opts[:from], opts[:to]
|
87
94
|
if from && !(Commit === from)
|
88
95
|
raise ArgumentError, "Invalid sha: #{from}" if from !~ SHA_PATTERN
|
89
96
|
from = Reference.new(:repository => self, :id => from)
|
@@ -92,7 +99,10 @@ module Gitrb
|
|
92
99
|
raise ArgumentError, "Invalid sha: #{to}" if to !~ SHA_PATTERN
|
93
100
|
to = Reference.new(:repository => self, :id => to)
|
94
101
|
end
|
95
|
-
Diff.new(from, to, git_diff_tree('--root', '
|
102
|
+
Diff.new(from, to, git_diff_tree('--root', '--full-index', '-u',
|
103
|
+
opts[:detect_renames] ? '-M' : nil,
|
104
|
+
opts[:detect_copies] ? '-C' : nil,
|
105
|
+
from ? from.id : nil, to.id, '--', opts[:path]))
|
96
106
|
end
|
97
107
|
|
98
108
|
# All changes made inside a transaction are atomic. If some
|
@@ -145,12 +155,11 @@ module Gitrb
|
|
145
155
|
def log(limit = 10, start = nil, path = nil)
|
146
156
|
limit = limit.to_s
|
147
157
|
start = start.to_s
|
158
|
+
path = path.to_s
|
148
159
|
raise ArgumentError, "Invalid limit: #{limit}" if limit !~ /^\d+$/
|
149
160
|
raise ArgumentError, "Invalid commit: #{start}" if start =~ /^\-/
|
150
|
-
|
151
|
-
|
152
|
-
args << '--' << path if path && !path.empty?
|
153
|
-
log = git_log(*args).split(/\n*\x00\n*/)
|
161
|
+
log = git_log('--pretty=tformat:%H%n%P%n%T%n%an%n%ae%n%at%n%cn%n%ce%n%ct%n%x00%s%n%b%x00',
|
162
|
+
"-#{limit}", start.empty? ? nil : start, '--', path.empty? ? nil : path).split(/\n*\x00\n*/)
|
154
163
|
commits = []
|
155
164
|
log.each_slice(2) do |data, message|
|
156
165
|
data = data.split("\n")
|
@@ -176,15 +185,20 @@ module Gitrb
|
|
176
185
|
raise ArgumentError, 'No id given' if !(String === id)
|
177
186
|
|
178
187
|
if id =~ SHA_PATTERN
|
179
|
-
raise
|
180
|
-
|
181
|
-
|
182
|
-
|
188
|
+
raise ArgumentError, "Sha too short: #{id}" if id.length < 5
|
189
|
+
|
190
|
+
trie = @objects.find(id)
|
191
|
+
raise NotFound, "Sha is ambiguous: #{id}" if trie.size > 1
|
192
|
+
return trie.value if !trie.empty?
|
183
193
|
elsif id =~ REVISION_PATTERN
|
184
194
|
list = git_rev_parse(id).split("\n") rescue nil
|
185
195
|
raise NotFound, "Revision not found: #{id}" if !list || list.empty?
|
186
196
|
raise NotFound, "Revision is ambiguous: #{id}" if list.size > 1
|
187
197
|
id = list.first
|
198
|
+
|
199
|
+
trie = @objects.find(id)
|
200
|
+
raise NotFound, "Sha is ambiguous: #{id}" if trie.size > 1
|
201
|
+
return trie.value if !trie.empty?
|
188
202
|
end
|
189
203
|
|
190
204
|
@logger.debug "gitrb: Loading #{id}"
|
@@ -207,14 +221,10 @@ module Gitrb
|
|
207
221
|
raise NotFound, "Bad object: #{id}" if content.length != size.to_i
|
208
222
|
else
|
209
223
|
trie = @packs.find(id)
|
210
|
-
raise NotFound, "Object not found: #{id}" if
|
211
|
-
|
212
|
-
id
|
213
|
-
|
214
|
-
list = trie.to_a
|
215
|
-
raise NotFound, "Sha is ambiguous: #{id}" if list.size > 1
|
216
|
-
|
217
|
-
pack, offset = list.first
|
224
|
+
raise NotFound, "Object not found: #{id}" if trie.empty?
|
225
|
+
raise NotFound, "Sha is ambiguous: #{id}" if trie.size > 1
|
226
|
+
id = trie.key
|
227
|
+
pack, offset = trie.value
|
218
228
|
content, type = pack.get_object(offset)
|
219
229
|
end
|
220
230
|
|
@@ -365,7 +375,7 @@ module Gitrb
|
|
365
375
|
|
366
376
|
def load_packs
|
367
377
|
@packs = Trie.new
|
368
|
-
@objects = Synchronized.new(Trie.new)
|
378
|
+
@objects = Util::Synchronized.new(Trie.new)
|
369
379
|
|
370
380
|
packs_path = "#{@path}/objects/pack"
|
371
381
|
if File.directory?(packs_path)
|
data/lib/gitrb/trie.rb
CHANGED
@@ -4,72 +4,91 @@ module Gitrb
|
|
4
4
|
|
5
5
|
attr_reader :key, :value
|
6
6
|
|
7
|
-
def initialize(key =
|
7
|
+
def initialize(key = nil, value = nil, children = [])
|
8
8
|
@key = key
|
9
9
|
@value = value
|
10
10
|
@children = children
|
11
11
|
end
|
12
12
|
|
13
|
+
def children
|
14
|
+
@children.compact
|
15
|
+
end
|
16
|
+
|
13
17
|
def clear
|
14
|
-
@key =
|
15
|
-
@
|
16
|
-
|
18
|
+
@key = @value = nil
|
19
|
+
@children = []
|
20
|
+
end
|
21
|
+
|
22
|
+
def empty?
|
23
|
+
self.size == 0
|
24
|
+
end
|
25
|
+
|
26
|
+
def each(&block)
|
27
|
+
yield(@value) if @value
|
28
|
+
children.each {|child| child.each(&block) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def size
|
32
|
+
children.inject(@value ? 1 : 0) {|sum, child| sum + child.size }
|
17
33
|
end
|
18
34
|
|
19
35
|
def find(key)
|
20
|
-
if key
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
child.find(key
|
36
|
+
if @key
|
37
|
+
if @key.index(key) == 0
|
38
|
+
self
|
39
|
+
elsif key.index(@key) == 0
|
40
|
+
child = @children[index(key)]
|
41
|
+
child ? child.find(key) : Trie.new
|
26
42
|
else
|
27
|
-
|
43
|
+
Trie.new
|
28
44
|
end
|
45
|
+
else
|
46
|
+
self
|
29
47
|
end
|
30
48
|
end
|
31
49
|
|
32
50
|
def insert(key, value)
|
33
|
-
if key
|
51
|
+
if !@key
|
52
|
+
@key = key
|
34
53
|
@value = value
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
child = @children
|
39
|
-
|
40
|
-
|
41
|
-
|
54
|
+
elsif @key == key
|
55
|
+
@value = value
|
56
|
+
elsif @key.index(key) == 0
|
57
|
+
child = Trie.new(@key, @value, @children)
|
58
|
+
@children = []
|
59
|
+
@children[@key[key.length].ord] = child
|
60
|
+
@key = key
|
61
|
+
@value = value
|
62
|
+
elsif key.index(@key) == 0
|
63
|
+
i = index(key)
|
64
|
+
if @children[i]
|
65
|
+
@children[i].insert(key, value)
|
42
66
|
else
|
43
|
-
@children[
|
67
|
+
@children[i] = Trie.new(key, value)
|
44
68
|
end
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
def each(&block)
|
49
|
-
yield(@value) if !@key.empty?
|
50
|
-
@children.compact.each {|c| c.each(&block) }
|
51
|
-
end
|
69
|
+
else
|
70
|
+
n = 0
|
71
|
+
n += 1 while key[n] == @key[n]
|
52
72
|
|
53
|
-
|
54
|
-
|
55
|
-
end
|
73
|
+
child1 = Trie.new(@key, @value, @children)
|
74
|
+
child2 = Trie.new(key, value)
|
56
75
|
|
57
|
-
|
58
|
-
|
76
|
+
@value = nil
|
77
|
+
@key = @key[0...n]
|
78
|
+
@children = []
|
79
|
+
@children[index(child1.key)] = child1
|
80
|
+
@children[index(child2.key)] = child2
|
81
|
+
end
|
59
82
|
end
|
60
83
|
|
61
84
|
def inspect
|
62
85
|
"#<Gitrb::Trie @key=#{@key.inspect}, @value=#{@value.inspect}, @children=#{@children.compact.inspect}>"
|
63
86
|
end
|
64
87
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
@children = []
|
70
|
-
@children[@key[prefix].ord] = child
|
71
|
-
@key = @key[0...prefix]
|
72
|
-
@value = nil
|
88
|
+
private
|
89
|
+
|
90
|
+
def index(key)
|
91
|
+
key[@key.length].ord
|
73
92
|
end
|
74
93
|
end
|
75
94
|
end
|
data/lib/gitrb/util.rb
CHANGED
@@ -17,16 +17,16 @@ module Gitrb
|
|
17
17
|
str
|
18
18
|
end
|
19
19
|
end
|
20
|
-
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
21
|
+
class Synchronized
|
22
|
+
def initialize(obj)
|
23
|
+
@obj = obj
|
24
|
+
@mutex = Mutex.new
|
25
|
+
end
|
27
26
|
|
28
|
-
|
29
|
-
|
27
|
+
def method_missing(*args)
|
28
|
+
@mutex.synchronize { @obj.send(*args) }
|
29
|
+
end
|
30
30
|
end
|
31
31
|
end
|
32
32
|
end
|
@@ -1,14 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require "#{File.dirname(__FILE__)}/helper"
|
3
|
-
require 'pp'
|
1
|
+
require 'helper'
|
4
2
|
|
5
3
|
describe Gitrb do
|
6
4
|
|
7
5
|
REPO = '/tmp/gitrb_test.git'
|
8
6
|
|
9
|
-
|
10
|
-
|
11
|
-
before(:each) do
|
7
|
+
before do
|
12
8
|
FileUtils.rm_rf REPO
|
13
9
|
Dir.mkdir REPO
|
14
10
|
|
@@ -18,13 +14,13 @@ describe Gitrb do
|
|
18
14
|
it 'should fail to initialize without a valid git repository' do
|
19
15
|
lambda {
|
20
16
|
Gitrb::Repository.new('/foo', 'master', true)
|
21
|
-
}.should
|
17
|
+
}.should.raise(ArgumentError)
|
22
18
|
end
|
23
19
|
|
24
20
|
it 'should save and load entries' do
|
25
21
|
repo.root['a'] = Gitrb::Blob.new(:data => 'Hello')
|
26
22
|
repo.commit
|
27
23
|
|
28
|
-
repo.root['a'].data.should
|
24
|
+
repo.root['a'].data.should.equal 'Hello'
|
29
25
|
end
|
30
26
|
end
|
data/test/benchmark.rb
CHANGED
@@ -1,13 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require 'pp'
|
1
|
+
require 'helper'
|
3
2
|
|
4
3
|
describe Gitrb::Commit do
|
5
4
|
|
6
5
|
REPO = '/tmp/gitrb_test'
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
before(:each) do
|
7
|
+
before do
|
11
8
|
FileUtils.rm_rf REPO
|
12
9
|
Dir.mkdir REPO
|
13
10
|
|
@@ -25,7 +22,7 @@ describe Gitrb::Commit do
|
|
25
22
|
|
26
23
|
content = commit.dump
|
27
24
|
|
28
|
-
content.should
|
25
|
+
content.should.equal "tree #{@repo.root.id}
|
29
26
|
author #{user.dump}
|
30
27
|
committer #{user.dump}
|
31
28
|
|
@@ -40,34 +37,12 @@ This is a message"
|
|
40
37
|
commit = repo.commit("Commit Message", author, author)
|
41
38
|
|
42
39
|
IO.popen("git log") do |io|
|
43
|
-
io.gets.should
|
44
|
-
io.gets.should
|
45
|
-
io.gets.should
|
46
|
-
io.gets.should
|
47
|
-
io.gets.should
|
40
|
+
io.gets.should.equal "commit #{commit.id}\n"
|
41
|
+
io.gets.should.equal "Author: hans <hans@email.de>\n"
|
42
|
+
io.gets.should.equal "Date: Mon Apr 20 00:00:00 2009 #{Time.now.strftime('%z')}\n"
|
43
|
+
io.gets.should.equal "\n"
|
44
|
+
io.gets.should.equal " Commit Message\n"
|
48
45
|
end
|
49
46
|
end
|
50
47
|
|
51
|
-
it "should diff 2 commits" do
|
52
|
-
repo.root['x'] = Gitrb::Blob.new(:data => 'a')
|
53
|
-
repo.root['y'] = Gitrb::Blob.new(:data => "
|
54
|
-
First Line.
|
55
|
-
Second Line.
|
56
|
-
Last Line.
|
57
|
-
")
|
58
|
-
a = repo.commit
|
59
|
-
|
60
|
-
repo.root.delete('x')
|
61
|
-
repo.root['y'] = Gitrb::Blob.new(:data => "
|
62
|
-
First Line.
|
63
|
-
Last Line.
|
64
|
-
Another Line.
|
65
|
-
")
|
66
|
-
repo.root['z'] = Gitrb::Blob.new(:data => 'c')
|
67
|
-
|
68
|
-
b = repo.commit
|
69
|
-
|
70
|
-
diff = repo.diff(a, b)
|
71
|
-
end
|
72
|
-
|
73
48
|
end
|
data/test/helper.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'gitrb'
|
2
|
+
|
3
|
+
module TestHelper
|
4
|
+
def ls_tree(id)
|
5
|
+
repo.git_ls_tree(id).split("\n").map {|line| line.split(" ") }
|
6
|
+
end
|
7
|
+
|
8
|
+
def file(file, data)
|
9
|
+
Dir.chdir(repo.path[0..-6]) do
|
10
|
+
FileUtils.mkpath(File.dirname(file))
|
11
|
+
open(file, 'w') { |io| io << data }
|
12
|
+
|
13
|
+
repo.git_add(file)
|
14
|
+
repo.git_commit('-m', 'added #{file}')
|
15
|
+
File.unlink(file)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Bacon::Context
|
21
|
+
include TestHelper
|
22
|
+
attr_reader :repo
|
23
|
+
end
|
data/test/profile.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'gitrb'
|
2
|
+
require 'fileutils'
|
3
|
+
require 'grit'
|
4
|
+
require 'ruby-prof'
|
5
|
+
|
6
|
+
REPO = '/tmp/gitrb'
|
7
|
+
|
8
|
+
FileUtils.rm_rf REPO
|
9
|
+
FileUtils.mkpath REPO
|
10
|
+
|
11
|
+
repo = Gitrb::Repository.new(:path => REPO, :create => true)
|
12
|
+
repo.transaction { 'aaa'.upto('jjj') { |key| repo.root[key] = Gitrb::Blob.new(:data => rand.to_s) } }
|
13
|
+
|
14
|
+
result = RubyProf.profile do
|
15
|
+
Gitrb::Repository.new(:path => '.').root.values { |v| v }
|
16
|
+
end
|
17
|
+
|
18
|
+
printer = RubyProf::GraphHtmlPrinter.new(result)
|
19
|
+
printer.print(File.open('gitrb.html', 'w'), :min_percent => 10)
|
20
|
+
|
21
|
+
result = RubyProf.profile do
|
22
|
+
Grit::Repo.new(:path => '.').tree.contents.each { |e| e.data }
|
23
|
+
end
|
24
|
+
|
25
|
+
printer = RubyProf::GraphHtmlPrinter.new(result)
|
26
|
+
printer.print(File.open('grit.html', 'w'), :min_percent => 10)
|
@@ -1,16 +1,10 @@
|
|
1
|
-
require
|
2
|
-
require "#{File.dirname(__FILE__)}/helper"
|
3
|
-
require 'pp'
|
1
|
+
require 'helper'
|
4
2
|
|
5
3
|
describe Gitrb do
|
6
4
|
|
7
|
-
include Helper
|
8
|
-
|
9
5
|
REPO = '/tmp/gitrb_test'
|
10
6
|
|
11
|
-
|
12
|
-
|
13
|
-
before(:each) do
|
7
|
+
before do
|
14
8
|
FileUtils.rm_rf REPO
|
15
9
|
Dir.mkdir REPO
|
16
10
|
@repo = Gitrb::Repository.new(:path => REPO, :create => true)
|
@@ -19,52 +13,52 @@ describe Gitrb do
|
|
19
13
|
it 'should fail to initialize without a valid git repository' do
|
20
14
|
lambda do
|
21
15
|
Gitrb::Repository.new(:path => '/')
|
22
|
-
end.should
|
16
|
+
end.should.raise(ArgumentError)
|
23
17
|
end
|
24
18
|
|
25
19
|
it 'should put and get objects by sha' do
|
26
20
|
blob1 = repo.put(Gitrb::Blob.new(:data => 'Hello'))
|
27
21
|
blob2 = repo.put(Gitrb::Blob.new(:data => 'World'))
|
28
22
|
|
29
|
-
repo.get(blob1.id).should
|
30
|
-
repo.get(blob1.id[0..4]).should
|
31
|
-
repo.get(blob1.id[0..10]).should
|
23
|
+
repo.get(blob1.id).should.be.identical_to blob1
|
24
|
+
repo.get(blob1.id[0..4]).should.be.identical_to blob1
|
25
|
+
repo.get(blob1.id[0..10]).should.be.identical_to blob1
|
32
26
|
|
33
|
-
repo.get(blob2.id).should
|
34
|
-
repo.get(blob2.id[0..4]).should
|
35
|
-
repo.get(blob2.id[0..10]).should
|
27
|
+
repo.get(blob2.id).should.be.identical_to blob2
|
28
|
+
repo.get(blob2.id[0..4]).should.be.identical_to blob2
|
29
|
+
repo.get(blob2.id[0..10]).should.be.identical_to blob2
|
36
30
|
end
|
37
31
|
|
38
32
|
it 'should find commits by revision' do
|
39
33
|
repo.root['a'] = Gitrb::Blob.new(:data => 'Hello')
|
40
34
|
commit1 = repo.commit
|
41
35
|
|
42
|
-
repo.get('HEAD').should
|
43
|
-
repo.get('master').should
|
44
|
-
lambda { repo.get('HEAD^') }.should
|
36
|
+
repo.get('HEAD').should.be.identical_to commit1
|
37
|
+
repo.get('master').should.be.identical_to commit1
|
38
|
+
lambda { repo.get('HEAD^') }.should.raise(Gitrb::NotFound)
|
45
39
|
|
46
40
|
repo.root['a'] = Gitrb::Blob.new(:data => 'World')
|
47
41
|
commit2 = repo.commit
|
48
42
|
|
49
|
-
repo.get('master').should
|
50
|
-
repo.get('HEAD').should
|
51
|
-
repo.get('HEAD^').should
|
52
|
-
repo.get('HEAD~').should
|
53
|
-
lambda { repo.get('HEAD^^') }.should
|
43
|
+
repo.get('master').should.be.identical_to commit2
|
44
|
+
repo.get('HEAD').should.be.identical_to commit2
|
45
|
+
repo.get('HEAD^').should.be.identical_to commit1
|
46
|
+
repo.get('HEAD~').should.be.identical_to commit1
|
47
|
+
lambda { repo.get('HEAD^^') }.should.raise(Gitrb::NotFound)
|
54
48
|
end
|
55
49
|
|
56
50
|
it 'should find modified entries' do
|
57
51
|
repo.root['a'] = Gitrb::Blob.new(:data => 'Hello')
|
58
52
|
|
59
|
-
repo.root.should
|
53
|
+
repo.root.should.be.modified
|
60
54
|
|
61
55
|
repo.commit
|
62
56
|
|
63
|
-
repo.root.
|
57
|
+
repo.root.should.not.be.modified
|
64
58
|
|
65
59
|
repo.root['a'] = Gitrb::Blob.new(:data => 'Bello')
|
66
60
|
|
67
|
-
repo.root.should
|
61
|
+
repo.root.should.be.modified
|
68
62
|
end
|
69
63
|
|
70
64
|
it 'should load a repo' do
|
@@ -73,8 +67,8 @@ describe Gitrb do
|
|
73
67
|
|
74
68
|
repo.refresh
|
75
69
|
|
76
|
-
repo.root['a'].data.should
|
77
|
-
repo.root['b'].data.should
|
70
|
+
repo.root['a'].data.should.equal 'Hello'
|
71
|
+
repo.root['b'].data.should.equal 'World'
|
78
72
|
end
|
79
73
|
|
80
74
|
it 'should load folders' do
|
@@ -83,11 +77,11 @@ describe Gitrb do
|
|
83
77
|
|
84
78
|
repo.refresh
|
85
79
|
|
86
|
-
repo.root['x'].object.should
|
87
|
-
repo.root['y'].object.should
|
80
|
+
repo.root['x'].object.should.be.kind_of(Gitrb::Tree)
|
81
|
+
repo.root['y'].object.should.be.kind_of(Gitrb::Tree)
|
88
82
|
|
89
|
-
repo.root['x']['a'].data.should
|
90
|
-
repo.root['y']['b'].data.should
|
83
|
+
repo.root['x']['a'].data.should.equal 'Hello'
|
84
|
+
repo.root['y']['b'].data.should.equal 'World'
|
91
85
|
end
|
92
86
|
|
93
87
|
it 'should detect modification' do
|
@@ -97,17 +91,17 @@ describe Gitrb do
|
|
97
91
|
|
98
92
|
repo.refresh
|
99
93
|
|
100
|
-
repo.root['x/a'].data.should
|
94
|
+
repo.root['x/a'].data.should.equal 'a'
|
101
95
|
|
102
96
|
repo.transaction do
|
103
97
|
repo.root['x/a'] = Gitrb::Blob.new(:data => 'b')
|
104
|
-
repo.root['x'].should
|
105
|
-
repo.root.should
|
98
|
+
repo.root['x'].should.be.modified
|
99
|
+
repo.root.should.be.modified
|
106
100
|
end
|
107
101
|
|
108
102
|
repo.refresh
|
109
103
|
|
110
|
-
repo.root['x/a'].data.should
|
104
|
+
repo.root['x/a'].data.should.equal 'b'
|
111
105
|
end
|
112
106
|
|
113
107
|
it 'should resolve paths' do
|
@@ -116,39 +110,39 @@ describe Gitrb do
|
|
116
110
|
|
117
111
|
repo.refresh
|
118
112
|
|
119
|
-
repo.root['x/a'].data.should
|
120
|
-
repo.root['y/b'].data.should
|
113
|
+
repo.root['x/a'].data.should.equal 'Hello'
|
114
|
+
repo.root['y/b'].data.should.equal 'World'
|
121
115
|
|
122
116
|
repo.root['y/b'] = Gitrb::Blob.new(:data => 'Now this')
|
123
117
|
|
124
|
-
repo.root['y']['b'].data.should
|
118
|
+
repo.root['y']['b'].data.should.equal 'Now this'
|
125
119
|
end
|
126
120
|
|
127
121
|
it 'should create new trees' do
|
128
122
|
repo.root['new/tree'] = Gitrb::Blob.new(:data => 'This tree')
|
129
|
-
repo.root['new/tree'].data.should
|
123
|
+
repo.root['new/tree'].data.should.equal 'This tree'
|
130
124
|
end
|
131
125
|
|
132
126
|
it 'should delete entries' do
|
133
127
|
repo.root['a'] = Gitrb::Blob.new(:data => 'Hello')
|
134
128
|
repo.root.delete('a')
|
135
129
|
|
136
|
-
repo.root['a'].should
|
130
|
+
repo.root['a'].should.be.nil
|
137
131
|
end
|
138
132
|
|
139
133
|
it 'should move entries' do
|
140
134
|
repo.root['a/b/c'] = Gitrb::Blob.new(:data => 'Hello')
|
141
|
-
repo.root['a/b/c'].data.should
|
135
|
+
repo.root['a/b/c'].data.should.equal 'Hello'
|
142
136
|
repo.root.move('a/b/c', 'x/y/z')
|
143
|
-
repo.root['a/b/c'].should
|
144
|
-
repo.root['x/y/z'].data.should
|
137
|
+
repo.root['a/b/c'].should.be.nil
|
138
|
+
repo.root['x/y/z'].data.should.equal 'Hello'
|
145
139
|
end
|
146
140
|
|
147
141
|
it 'should have a head commit' do
|
148
142
|
file 'a', 'Hello'
|
149
143
|
|
150
144
|
repo.refresh
|
151
|
-
repo.head.
|
145
|
+
repo.head.should.not.be.nil
|
152
146
|
end
|
153
147
|
|
154
148
|
it 'should rollback a transaction' do
|
@@ -164,9 +158,9 @@ describe Gitrb do
|
|
164
158
|
rescue
|
165
159
|
end
|
166
160
|
|
167
|
-
repo.root['a/b'].data.should
|
168
|
-
repo.root['c/d'].data.should
|
169
|
-
repo.root['x/a'].should
|
161
|
+
repo.root['a/b'].data.should.equal 'Hello'
|
162
|
+
repo.root['c/d'].data.should.equal 'World'
|
163
|
+
repo.root['x/a'].should.be.nil
|
170
164
|
end
|
171
165
|
|
172
166
|
it 'should commit a transaction' do
|
@@ -181,11 +175,11 @@ describe Gitrb do
|
|
181
175
|
a = ls_tree(repo.root['a'].object.id)
|
182
176
|
x = ls_tree(repo.root['x'].object.id)
|
183
177
|
|
184
|
-
a.should
|
185
|
-
x.should
|
178
|
+
a.should.equal [["100644", "blob", "b653cf27cef08de46da49a11fa5016421e9e3b32", "b"]]
|
179
|
+
x.should.equal [["100644", "blob", "87d2b203800386b1cc8735a7d540a33e246357fa", "a"]]
|
186
180
|
|
187
|
-
repo.git_show(a[0][2]).should
|
188
|
-
repo.git_show(x[0][2]).should
|
181
|
+
repo.git_show(a[0][2]).should.equal 'Changed'
|
182
|
+
repo.git_show(x[0][2]).should.equal 'Added'
|
189
183
|
end
|
190
184
|
|
191
185
|
it "should save blobs" do
|
@@ -199,9 +193,9 @@ describe Gitrb do
|
|
199
193
|
b = repo.root['b'].id
|
200
194
|
c = repo.root['c'].id
|
201
195
|
|
202
|
-
repo.git_show(a).should
|
203
|
-
repo.git_show(b).should
|
204
|
-
repo.git_show(c).should
|
196
|
+
repo.git_show(a).should.equal 'a'
|
197
|
+
repo.git_show(b).should.equal 'b'
|
198
|
+
repo.git_show(c).should.equal 'c'
|
205
199
|
end
|
206
200
|
|
207
201
|
it 'should allow only one transaction' do
|
@@ -223,7 +217,7 @@ describe Gitrb do
|
|
223
217
|
|
224
218
|
repo.refresh
|
225
219
|
|
226
|
-
repo.root['a/b'].data.should
|
220
|
+
repo.root['a/b'].data.should.equal 'Changed by second thread'
|
227
221
|
end
|
228
222
|
|
229
223
|
it 'should find all objects' do
|
@@ -232,8 +226,8 @@ describe Gitrb do
|
|
232
226
|
repo.root['d'] = Gitrb::Blob.new(:data => 'World')
|
233
227
|
repo.commit
|
234
228
|
|
235
|
-
repo.root.to_a[0][1].data.should
|
236
|
-
repo.root.to_a[1][1].data.should
|
229
|
+
repo.root.to_a[0][1].data.should.equal 'Hello'
|
230
|
+
repo.root.to_a[1][1].data.should.equal 'World'
|
237
231
|
end
|
238
232
|
|
239
233
|
it "should load log" do
|
@@ -243,8 +237,8 @@ describe Gitrb do
|
|
243
237
|
repo.root['b'] = Gitrb::Blob.new(:data => 'b')
|
244
238
|
repo.commit 'added b'
|
245
239
|
|
246
|
-
repo.log[0].message.should
|
247
|
-
repo.log[1].message.should
|
240
|
+
repo.log[0].message.should.equal 'added b'
|
241
|
+
repo.log[1].message.should.equal 'added a'
|
248
242
|
end
|
249
243
|
|
250
244
|
it "should load tags" do
|
@@ -258,54 +252,67 @@ describe Gitrb do
|
|
258
252
|
id = File.read(repo.path + '/refs/tags/0.1')
|
259
253
|
tag = repo.get(id)
|
260
254
|
|
261
|
-
tag.tagtype.should
|
262
|
-
tag.object.object.should
|
263
|
-
tag.tagger.name.should
|
264
|
-
tag.tagger.email.should
|
255
|
+
tag.tagtype.should.equal 'commit'
|
256
|
+
tag.object.object.should.equal repo.head
|
257
|
+
tag.tagger.name.should.equal user.name
|
258
|
+
tag.tagger.email.should.equal user.email
|
265
259
|
tag.message.should =~ /message/
|
266
260
|
end
|
267
261
|
|
268
262
|
it 'should detect changes and refresh' do
|
269
263
|
file 'a', 'data'
|
270
|
-
repo.root['a'].should
|
271
|
-
repo.should
|
264
|
+
repo.root['a'].should.be.nil
|
265
|
+
repo.should.be.changed
|
272
266
|
repo.refresh
|
273
|
-
repo.
|
274
|
-
repo.root['a'].data.should
|
267
|
+
repo.should.not.be.changed
|
268
|
+
repo.root['a'].data.should.equal 'data'
|
275
269
|
end
|
276
270
|
|
277
271
|
it 'should clear cache' do
|
278
272
|
file 'a', 'data'
|
279
273
|
repo.refresh
|
280
|
-
repo.root['a'].data.should
|
274
|
+
repo.root['a'].data.should.equal 'data'
|
281
275
|
repo.clear
|
282
|
-
repo.root['a'].data.should
|
276
|
+
repo.root['a'].data.should.equal 'data'
|
283
277
|
end
|
284
278
|
|
285
279
|
it 'should forbid branch switching from within transaction' do
|
286
280
|
repo.transaction do
|
287
|
-
lambda { repo.branch = 'test' }.should
|
281
|
+
lambda { repo.branch = 'test' }.should.raise(ThreadError)
|
288
282
|
end
|
289
283
|
end
|
290
284
|
|
291
285
|
it 'should forbid clearing from within transaction' do
|
292
286
|
repo.transaction do
|
293
|
-
lambda { repo.clear }.should
|
287
|
+
lambda { repo.clear }.should.raise(ThreadError)
|
294
288
|
end
|
295
289
|
end
|
296
290
|
|
297
291
|
it 'should forbid nested transactions' do
|
298
292
|
repo.transaction do
|
299
|
-
lambda { repo.transaction {} }.should
|
293
|
+
lambda { repo.transaction {} }.should.raise(ThreadError)
|
300
294
|
end
|
301
295
|
end
|
302
296
|
|
303
297
|
it 'should be in transaction' do
|
304
|
-
repo.
|
298
|
+
repo.should.not.be.in_transaction
|
305
299
|
repo.transaction do
|
306
|
-
repo.should
|
300
|
+
repo.should.be.in_transaction
|
307
301
|
end
|
308
|
-
repo.
|
302
|
+
repo.should.not.be.in_transaction
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should diff 2 commits" do
|
306
|
+
repo.root['x'] = Gitrb::Blob.new(:data => 'a')
|
307
|
+
repo.root['y'] = Gitrb::Blob.new(:data => "\nFirst Line.\nSecond Line.\nLast Line.\n")
|
308
|
+
a = repo.commit
|
309
|
+
|
310
|
+
repo.diff(:to => a).patch.should.include "+First Line.\n+Second Line.\n+Last Line."
|
311
|
+
repo.root['y'] = Gitrb::Blob.new(:data => "\nFirst Line.\nLast Line.\nAnother Line.\n")
|
312
|
+
b = repo.commit
|
313
|
+
|
314
|
+
repo.diff(:from => a, :to => b).patch.should.include '+Another Line.'
|
315
|
+
repo.diff(:from => a, :to => b).patch.should.include '-Second Line.'
|
309
316
|
end
|
310
317
|
|
311
318
|
end
|
@@ -1,15 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require "#{File.dirname(__FILE__)}/helper"
|
3
|
-
require 'pp'
|
1
|
+
require 'helper'
|
4
2
|
|
5
3
|
describe Gitrb::Tree do
|
6
4
|
REPO = '/tmp/gitrb_test'
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
attr_reader :repo, :tree
|
11
|
-
|
12
|
-
before(:each) do
|
6
|
+
before do
|
13
7
|
FileUtils.rm_rf REPO
|
14
8
|
Dir.mkdir REPO
|
15
9
|
|
@@ -34,10 +28,10 @@ describe Gitrb::Tree do
|
|
34
28
|
"100644 b\0#{b}" +
|
35
29
|
"100644 c\0#{c}"
|
36
30
|
|
37
|
-
repo.get(id).should
|
38
|
-
repo.get(id).names.should
|
39
|
-
repo.get(id).names.should
|
40
|
-
repo.get(id).names.should
|
31
|
+
repo.get(id).should.be.instance_of(Gitrb::Tree)
|
32
|
+
repo.get(id).names.should.include('a')
|
33
|
+
repo.get(id).names.should.include('b')
|
34
|
+
repo.get(id).names.should.include('c')
|
41
35
|
end
|
42
36
|
|
43
37
|
it "should save trees" do
|
@@ -49,7 +43,7 @@ describe Gitrb::Tree do
|
|
49
43
|
|
50
44
|
tree.save
|
51
45
|
|
52
|
-
ls_tree(tree.id).should
|
46
|
+
ls_tree(tree.id).should.equal\
|
53
47
|
[["100644", "blob", "2e65efe2a145dda7ee51d1741299f848e5bf752e", "a"],
|
54
48
|
["100644", "blob", "63d8dbd40c23542e740659a7168a0ce3138ea748", "b"],
|
55
49
|
["100644", "blob", "3410062ba67c5ed59b854387a8bc0ec012479368", "c"]]
|
@@ -64,10 +58,10 @@ describe Gitrb::Tree do
|
|
64
58
|
|
65
59
|
tree.save
|
66
60
|
|
67
|
-
ls_tree(tree.id).should
|
61
|
+
ls_tree(tree.id).should.equal\
|
68
62
|
[["040000", "tree", "24e88cb96c396400000ef706d1ca1ed9a88251aa", "x"]]
|
69
63
|
|
70
|
-
ls_tree("24e88cb96c396400000ef706d1ca1ed9a88251aa").should
|
64
|
+
ls_tree("24e88cb96c396400000ef706d1ca1ed9a88251aa").should.equal\
|
71
65
|
[["100644", "blob", "2e65efe2a145dda7ee51d1741299f848e5bf752e", "a"],
|
72
66
|
["100644", "blob", "63d8dbd40c23542e740659a7168a0ce3138ea748", "b"],
|
73
67
|
["100644", "blob", "3410062ba67c5ed59b854387a8bc0ec012479368", "c"]]
|
data/test/trie_test.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'gitrb'
|
2
|
+
|
3
|
+
describe Gitrb::Trie do
|
4
|
+
|
5
|
+
before do
|
6
|
+
@trie = Gitrb::Trie.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'should be empty' do
|
10
|
+
@trie.should.be.empty
|
11
|
+
@trie.to_a.should.be.empty
|
12
|
+
@trie.size.should.equal 0
|
13
|
+
@trie.find('').should.be.identical_to @trie
|
14
|
+
@trie.find('abc').should.be.identical_to @trie
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should find by prefix' do
|
18
|
+
@trie.insert('abcdef', 1)
|
19
|
+
@trie.find('a').should.be.identical_to @trie.find('abcdef')
|
20
|
+
@trie.find('abc').should.be.identical_to @trie.find('abcdef')
|
21
|
+
@trie.find('abc').key.should.equal 'abcdef'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should have clear' do
|
25
|
+
@trie.insert('abc', 1)
|
26
|
+
@trie.should.not.be.empty
|
27
|
+
@trie.clear
|
28
|
+
@trie.should.be.empty
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'should split shorter node' do
|
32
|
+
@trie.insert('a', 1)
|
33
|
+
@trie.key.should.equal 'a'
|
34
|
+
@trie.value.should.equal 1
|
35
|
+
@trie.size.should.equal 1
|
36
|
+
@trie.find('a').should.be.identical_to @trie
|
37
|
+
|
38
|
+
@trie.insert('b', 2)
|
39
|
+
@trie.children.size.should.equal 2
|
40
|
+
@trie.key.should.equal ''
|
41
|
+
@trie.value.should.be.nil
|
42
|
+
@trie.size.should.equal 2
|
43
|
+
@trie.find('a').key.should.equal 'a'
|
44
|
+
@trie.find('b').key.should.equal 'b'
|
45
|
+
@trie.size.should.equal 2
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should add child' do
|
49
|
+
@trie.insert('a', 1)
|
50
|
+
|
51
|
+
@trie.insert('ab', 2)
|
52
|
+
@trie.size.should.equal 2
|
53
|
+
@trie.children.size.should.equal 1
|
54
|
+
@trie.find('a').children.size.should.equal 1
|
55
|
+
@trie.find('a').key.should.equal 'a'
|
56
|
+
@trie.find('a').value.should.equal 1
|
57
|
+
@trie.find('ab').key.should.equal 'ab'
|
58
|
+
@trie.find('ab').value.should.equal 2
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should overwrite value' do
|
62
|
+
@trie.insert('a', 1)
|
63
|
+
@trie.insert('a', 2)
|
64
|
+
@trie.find('a').value.should.equal 2
|
65
|
+
@trie.size.should.equal 1
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should add second-level child' do
|
69
|
+
@trie.insert('a', 1)
|
70
|
+
@trie.insert('ab', 2)
|
71
|
+
@trie.insert('abc', 3)
|
72
|
+
|
73
|
+
@trie.find('a').children.size.should.equal 1
|
74
|
+
@trie.find('ab').children.size.should.equal 1
|
75
|
+
@trie.find('abc').value.should.equal 3
|
76
|
+
@trie.size.should.equal 3
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'set value of empty node' do
|
80
|
+
@trie.insert('a', 1)
|
81
|
+
@trie.insert('b', 2)
|
82
|
+
@trie.size.should.equal 2
|
83
|
+
@trie.insert('', 3)
|
84
|
+
@trie.value.should.equal 3
|
85
|
+
@trie.size.should.equal 3
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'should split longer node' do
|
89
|
+
@trie.insert('ab', 1)
|
90
|
+
@trie.size.should.equal 1
|
91
|
+
@trie.insert('a', 2)
|
92
|
+
@trie.size.should.equal 2
|
93
|
+
@trie.find('ab').value.should.equal 1
|
94
|
+
@trie.find('a').value.should.equal 2
|
95
|
+
end
|
96
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 6
|
9
|
+
version: 0.1.6
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Daniel Mendler
|
@@ -14,13 +14,22 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-08-
|
17
|
+
date: 2010-08-13 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
|
-
dependencies:
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bacon
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :development
|
31
|
+
version_requirements: *id001
|
32
|
+
description: Fast and lightweight ruby git implementation
|
24
33
|
email: mail@daniel-mendler.de
|
25
34
|
executables: []
|
26
35
|
|
@@ -46,12 +55,14 @@ files:
|
|
46
55
|
- lib/gitrb/trie.rb
|
47
56
|
- lib/gitrb/user.rb
|
48
57
|
- lib/gitrb/util.rb
|
49
|
-
- test/
|
58
|
+
- test/bare_repository_test.rb
|
50
59
|
- test/benchmark.rb
|
51
|
-
- test/
|
52
|
-
- test/
|
53
|
-
- test/
|
54
|
-
- test/
|
60
|
+
- test/commit_test.rb
|
61
|
+
- test/helper.rb
|
62
|
+
- test/profile.rb
|
63
|
+
- test/repository_test.rb
|
64
|
+
- test/trie_test.rb
|
65
|
+
- test/tree_test.rb
|
55
66
|
has_rdoc: true
|
56
67
|
homepage: https://github.com/minad/gitrb
|
57
68
|
licenses: []
|
data/test/trie_spec.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
require "#{File.dirname(__FILE__)}/../lib/gitrb"
|
2
|
-
require 'pp'
|
3
|
-
|
4
|
-
describe Gitrb::Trie do
|
5
|
-
|
6
|
-
it "should add children" do
|
7
|
-
trie = Gitrb::Trie.new
|
8
|
-
0.upto(100) do |i|
|
9
|
-
trie.insert('a' * i, i)
|
10
|
-
end
|
11
|
-
trie.find('').key.should == ''
|
12
|
-
trie.find('').value.should == 0
|
13
|
-
1.upto(100) do |i|
|
14
|
-
trie.find('a' * i).key.should == 'a'
|
15
|
-
trie.find('a' * i).value.should == i
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should split node" do
|
20
|
-
trie = Gitrb::Trie.new
|
21
|
-
trie.insert("abc", 1)
|
22
|
-
trie.insert("ab", 2)
|
23
|
-
trie.insert("ac", 3)
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|