gitrb 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +25 -1
- data/gitrb.gemspec +2 -1
- data/lib/gitrb/object.rb +3 -1
- data/lib/gitrb/pack.rb +4 -23
- data/lib/gitrb/repository.rb +33 -33
- data/lib/gitrb/tree.rb +48 -42
- data/lib/gitrb.rb +1 -0
- data/test/repository_spec.rb +8 -0
- metadata +3 -2
data/README.md
CHANGED
@@ -1 +1,25 @@
|
|
1
|
-
|
1
|
+
GitRb - Native ruby interface to git
|
2
|
+
====================================
|
3
|
+
|
4
|
+
GitRb is a native interface to git. It is based on git_store by Matthias Georgi.
|
5
|
+
|
6
|
+
### Installation
|
7
|
+
|
8
|
+
GitStore can be installed as gem easily:
|
9
|
+
|
10
|
+
$ gem sources -a http://gemcutter.org
|
11
|
+
$ sudo gem install gitrb
|
12
|
+
|
13
|
+
### Usage Example
|
14
|
+
|
15
|
+
require 'gitrb'
|
16
|
+
|
17
|
+
repo = Gitrb::Repository.new(:path => '/tmp/repository', :create => true)
|
18
|
+
repo.transaction do
|
19
|
+
repo.root['textfile1'] = Gitrb::Blob.new(:data => 'text')
|
20
|
+
repo.root['textfile2'] = Gitrb::Blob.new(:data => 'text')
|
21
|
+
end
|
22
|
+
|
23
|
+
puts repo.root['textfile1'].data
|
24
|
+
puts repo.root['textfile2'].data
|
25
|
+
|
data/gitrb.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'gitrb'
|
3
|
-
s.version = '0.0.
|
3
|
+
s.version = '0.0.2'
|
4
4
|
s.summary = 'Pure ruby git implementation'
|
5
5
|
s.author = 'Daniel Mendler'
|
6
6
|
s.email = 'mail@daniel-mendler.de'
|
@@ -17,6 +17,7 @@ LICENSE
|
|
17
17
|
README.md
|
18
18
|
Rakefile
|
19
19
|
gitrb.gemspec
|
20
|
+
lib/gitrb.rb
|
20
21
|
lib/gitrb/blob.rb
|
21
22
|
lib/gitrb/commit.rb
|
22
23
|
lib/gitrb/diff.rb
|
data/lib/gitrb/object.rb
CHANGED
@@ -25,6 +25,8 @@ module Gitrb
|
|
25
25
|
end
|
26
26
|
|
27
27
|
class Reference
|
28
|
+
undef_method :id, :type rescue nil
|
29
|
+
|
28
30
|
def initialize(properties = {})
|
29
31
|
@properties = properties
|
30
32
|
@object = nil
|
@@ -32,7 +34,7 @@ module Gitrb
|
|
32
34
|
|
33
35
|
def method_missing(name, *args, &block)
|
34
36
|
if @object
|
35
|
-
instance_eval
|
37
|
+
instance_eval %{def self.#{name}(*args, &block); @object.send("#{name}", *args, &block); end}
|
36
38
|
@object.send(name, *args, &block)
|
37
39
|
elsif name == :type && (mode = @properties['mode'] || @properties[:mode])
|
38
40
|
mode = mode.to_i(8)
|
data/lib/gitrb/pack.rb
CHANGED
@@ -40,29 +40,10 @@ module Gitrb
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def [](
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
offset = idx.first
|
48
|
-
len = idx.last - idx.first + idx.exclude_end? ? 0 : 1
|
49
|
-
when Fixnum
|
50
|
-
offset = idx
|
51
|
-
len = nil
|
52
|
-
when Array
|
53
|
-
offset, len = idx
|
54
|
-
else
|
55
|
-
raise RuntimeError, "invalid index param: #{idx.class}"
|
56
|
-
end
|
57
|
-
if @offset != offset
|
58
|
-
@file.seek(offset + @global_offset)
|
59
|
-
end
|
60
|
-
@offset = offset + len ? len : 1
|
61
|
-
if not len
|
62
|
-
@file.read(1).getord(0)
|
63
|
-
else
|
64
|
-
@file.read(len)
|
65
|
-
end
|
43
|
+
def [](offset, len)
|
44
|
+
@file.seek(offset + @global_offset) if @offset != offset
|
45
|
+
@offset = offset + len
|
46
|
+
@file.read(len)
|
66
47
|
end
|
67
48
|
end
|
68
49
|
|
data/lib/gitrb/repository.rb
CHANGED
@@ -81,47 +81,18 @@ module Gitrb
|
|
81
81
|
# Example:
|
82
82
|
# repository.transaction { repository['a'] = 'b' }
|
83
83
|
#
|
84
|
-
def transaction(message =
|
84
|
+
def transaction(message = '', author = nil, committer = nil)
|
85
85
|
start_transaction
|
86
86
|
result = yield
|
87
|
-
commit(message)
|
87
|
+
commit(message, author, committer)
|
88
88
|
result
|
89
89
|
rescue
|
90
|
-
|
90
|
+
rollback_transaction
|
91
91
|
raise
|
92
92
|
ensure
|
93
93
|
finish_transaction
|
94
94
|
end
|
95
95
|
|
96
|
-
# Start a transaction.
|
97
|
-
#
|
98
|
-
# Tries to get lock on lock file, load the this repository if
|
99
|
-
# has changed in the repository.
|
100
|
-
def start_transaction
|
101
|
-
file = File.open("#{head_path}.lock", "w")
|
102
|
-
file.flock(File::LOCK_EX)
|
103
|
-
Thread.current['gitrb_repository_lock'] = file
|
104
|
-
refresh
|
105
|
-
end
|
106
|
-
|
107
|
-
# Rerepository the state of the repository.
|
108
|
-
#
|
109
|
-
# Any changes made to the repository are discarded.
|
110
|
-
def rollback
|
111
|
-
@objects.clear
|
112
|
-
load
|
113
|
-
finish_transaction
|
114
|
-
end
|
115
|
-
|
116
|
-
# Finish the transaction.
|
117
|
-
#
|
118
|
-
# Release the lock file.
|
119
|
-
def finish_transaction
|
120
|
-
Thread.current['gitrb_repository_lock'].close rescue nil
|
121
|
-
Thread.current['gitrb_repository_lock'] = nil
|
122
|
-
File.unlink("#{head_path}.lock") rescue nil
|
123
|
-
end
|
124
|
-
|
125
96
|
# Write a commit object to disk and set the head of the current branch.
|
126
97
|
#
|
127
98
|
# Returns the commit object
|
@@ -150,7 +121,7 @@ module Gitrb
|
|
150
121
|
def log(limit = 10, start = nil, path = nil)
|
151
122
|
args = ['--format=tformat:%H%n%P%n%T%n%an%n%ae%n%at%n%cn%n%ce%n%ct%n%x00%s%n%b%x00', "-#{limit}", ]
|
152
123
|
args << start if start
|
153
|
-
args << "--" << path if path
|
124
|
+
args << "--" << path if path && !path.empty?
|
154
125
|
log = git_log(*args).split(/\n*\x00\n*/)
|
155
126
|
commits = []
|
156
127
|
log.each_slice(2) do |data, message|
|
@@ -294,6 +265,35 @@ module Gitrb
|
|
294
265
|
|
295
266
|
protected
|
296
267
|
|
268
|
+
# Start a transaction.
|
269
|
+
#
|
270
|
+
# Tries to get lock on lock file, load the this repository if
|
271
|
+
# has changed in the repository.
|
272
|
+
def start_transaction
|
273
|
+
file = File.open("#{head_path}.lock", "w")
|
274
|
+
file.flock(File::LOCK_EX)
|
275
|
+
Thread.current['gitrb_repository_lock'] = file
|
276
|
+
refresh
|
277
|
+
end
|
278
|
+
|
279
|
+
# Rerepository the state of the repository.
|
280
|
+
#
|
281
|
+
# Any changes made to the repository are discarded.
|
282
|
+
def rollback_transaction
|
283
|
+
@objects.clear
|
284
|
+
load
|
285
|
+
finish_transaction
|
286
|
+
end
|
287
|
+
|
288
|
+
# Finish the transaction.
|
289
|
+
#
|
290
|
+
# Release the lock file.
|
291
|
+
def finish_transaction
|
292
|
+
Thread.current['gitrb_repository_lock'].close rescue nil
|
293
|
+
Thread.current['gitrb_repository_lock'] = nil
|
294
|
+
File.unlink("#{head_path}.lock") rescue nil
|
295
|
+
end
|
296
|
+
|
297
297
|
def get_type(id, expected)
|
298
298
|
object = get(id)
|
299
299
|
raise NotFound, "Wrong type #{object.type}, expected #{expected}" if object && object.type != expected
|
data/lib/gitrb/tree.rb
CHANGED
@@ -68,63 +68,63 @@ module Gitrb
|
|
68
68
|
id
|
69
69
|
end
|
70
70
|
|
71
|
-
# Read entry with specified name.
|
72
|
-
def get(name)
|
73
|
-
@children[name]
|
74
|
-
end
|
75
|
-
|
76
|
-
# Write entry with specified name.
|
77
|
-
def put(name, value)
|
78
|
-
raise RuntimeError, "no blob or tree" if !(Blob === value || Tree === value)
|
79
|
-
value.repository = repository
|
80
|
-
@modified = true
|
81
|
-
@children[name] = value
|
82
|
-
value
|
83
|
-
end
|
84
|
-
|
85
|
-
# Remove entry with specified name.
|
86
|
-
def remove(name)
|
87
|
-
@modified = true
|
88
|
-
@children.delete(name.to_s)
|
89
|
-
end
|
90
|
-
|
91
71
|
# Does this key exist in the children?
|
92
|
-
def
|
93
|
-
|
94
|
-
end
|
95
|
-
|
96
|
-
def normalize_path(path)
|
97
|
-
(path[0, 1] == '/' ? path[1..-1] : path).split('/')
|
72
|
+
def exists?(name)
|
73
|
+
self[name] != nil
|
98
74
|
end
|
99
75
|
|
100
|
-
# Read
|
76
|
+
# Read an entry on specified path.
|
101
77
|
def [](path)
|
78
|
+
path = normalize_path(path)
|
102
79
|
return self if path.empty?
|
103
|
-
|
104
|
-
|
105
|
-
|
80
|
+
entry = @children[path.first]
|
81
|
+
if path.size == 1
|
82
|
+
entry
|
83
|
+
elsif entry
|
84
|
+
raise RuntimeError, 'Not a tree' if entry.type != 'tree'
|
85
|
+
entry[path[1..-1]]
|
106
86
|
end
|
107
87
|
end
|
108
88
|
|
109
|
-
# Write
|
110
|
-
def []=(path,
|
111
|
-
|
112
|
-
|
89
|
+
# Write an entry on specified path.
|
90
|
+
def []=(path, entry)
|
91
|
+
path = normalize_path(path)
|
92
|
+
if path.empty?
|
93
|
+
raise RuntimeError, 'Empty path'
|
94
|
+
elsif path.size == 1
|
95
|
+
raise RuntimeError, 'No blob or tree' if entry.type != 'tree' && entry.type != 'blob'
|
96
|
+
entry.repository = repository
|
97
|
+
@modified = true
|
98
|
+
@children[path.first] = entry
|
99
|
+
else
|
100
|
+
tree = @children[path.first]
|
101
|
+
if !tree
|
102
|
+
tree = @children[path.first] = Tree.new(:repository => repository)
|
103
|
+
@modified = true
|
104
|
+
end
|
113
105
|
raise RuntimeError, 'Not a tree' if tree.type != 'tree'
|
114
|
-
tree
|
106
|
+
tree[path[1..-1]] = entry
|
115
107
|
end
|
116
|
-
tree.put(list.last, value)
|
117
108
|
end
|
118
109
|
|
119
|
-
# Delete a
|
110
|
+
# Delete a entry on specified path.
|
120
111
|
def delete(path)
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
112
|
+
path = normalize_path(path)
|
113
|
+
if path.empty?
|
114
|
+
raise RuntimeError, 'Empty path'
|
115
|
+
elsif path.size == 1
|
116
|
+
@modified = true
|
117
|
+
@children.delete(path.first)
|
118
|
+
else
|
119
|
+
tree = @children[path.first]
|
120
|
+
raise RuntimeError, 'Not a tree' if tree.type != 'tree'
|
121
|
+
tree.delete(path[1..-1])
|
125
122
|
end
|
123
|
+
end
|
126
124
|
|
127
|
-
|
125
|
+
# Move a entry
|
126
|
+
def move(path, dest)
|
127
|
+
self[dest] = delete(path)
|
128
128
|
end
|
129
129
|
|
130
130
|
# Iterate over all children
|
@@ -146,6 +146,12 @@ module Gitrb
|
|
146
146
|
|
147
147
|
private
|
148
148
|
|
149
|
+
def normalize_path(path)
|
150
|
+
return path if Array === path
|
151
|
+
path = path.to_s
|
152
|
+
(path[0, 1] == '/' ? path[1..-1] : path).split('/')
|
153
|
+
end
|
154
|
+
|
149
155
|
# Read the contents of a raw git object.
|
150
156
|
def parse(data)
|
151
157
|
@children.clear
|
data/lib/gitrb.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gitrb/repository'
|
data/test/repository_spec.rb
CHANGED
@@ -105,6 +105,14 @@ describe Gitrb do
|
|
105
105
|
repo.root['a'].should be_nil
|
106
106
|
end
|
107
107
|
|
108
|
+
it 'should move entries' do
|
109
|
+
repo.root['a/b/c'] = Gitrb::Blob.new(:data => 'Hello')
|
110
|
+
repo.root['a/b/c'].data.should == 'Hello'
|
111
|
+
repo.root.move('a/b/c', 'x/y/z')
|
112
|
+
repo.root['a/b/c'].should be_nil
|
113
|
+
repo.root['x/y/z'].data.should == 'Hello'
|
114
|
+
end
|
115
|
+
|
108
116
|
it 'should have a head commit' do
|
109
117
|
file 'a', 'Hello'
|
110
118
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gitrb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Mendler
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-12-
|
12
|
+
date: 2009-12-15 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -26,6 +26,7 @@ files:
|
|
26
26
|
- README.md
|
27
27
|
- Rakefile
|
28
28
|
- gitrb.gemspec
|
29
|
+
- lib/gitrb.rb
|
29
30
|
- lib/gitrb/blob.rb
|
30
31
|
- lib/gitrb/commit.rb
|
31
32
|
- lib/gitrb/diff.rb
|