multi_git 0.0.1.alpha1
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/lib/multi_git/backend.rb +100 -0
- data/lib/multi_git/backend_set.rb +42 -0
- data/lib/multi_git/blob.rb +52 -0
- data/lib/multi_git/builder.rb +19 -0
- data/lib/multi_git/commit.rb +185 -0
- data/lib/multi_git/directory.rb +67 -0
- data/lib/multi_git/error.rb +67 -0
- data/lib/multi_git/executeable.rb +12 -0
- data/lib/multi_git/file.rb +35 -0
- data/lib/multi_git/git_backend/blob.rb +11 -0
- data/lib/multi_git/git_backend/cmd.rb +117 -0
- data/lib/multi_git/git_backend/commit.rb +75 -0
- data/lib/multi_git/git_backend/object.rb +34 -0
- data/lib/multi_git/git_backend/ref.rb +36 -0
- data/lib/multi_git/git_backend/repository.rb +162 -0
- data/lib/multi_git/git_backend/tree.rb +22 -0
- data/lib/multi_git/git_backend.rb +19 -0
- data/lib/multi_git/handle.rb +33 -0
- data/lib/multi_git/jgit_backend/blob.rb +10 -0
- data/lib/multi_git/jgit_backend/commit.rb +45 -0
- data/lib/multi_git/jgit_backend/object.rb +48 -0
- data/lib/multi_git/jgit_backend/ref.rb +117 -0
- data/lib/multi_git/jgit_backend/repository.rb +223 -0
- data/lib/multi_git/jgit_backend/rewindeable_io.rb +33 -0
- data/lib/multi_git/jgit_backend/tree.rb +28 -0
- data/lib/multi_git/jgit_backend.rb +15 -0
- data/lib/multi_git/object.rb +59 -0
- data/lib/multi_git/ref.rb +381 -0
- data/lib/multi_git/repository.rb +190 -0
- data/lib/multi_git/rugged_backend/blob.rb +8 -0
- data/lib/multi_git/rugged_backend/commit.rb +38 -0
- data/lib/multi_git/rugged_backend/object.rb +38 -0
- data/lib/multi_git/rugged_backend/ref.rb +32 -0
- data/lib/multi_git/rugged_backend/repository.rb +160 -0
- data/lib/multi_git/rugged_backend/tree.rb +18 -0
- data/lib/multi_git/rugged_backend.rb +16 -0
- data/lib/multi_git/submodule.rb +7 -0
- data/lib/multi_git/symlink.rb +42 -0
- data/lib/multi_git/tree/builder.rb +184 -0
- data/lib/multi_git/tree.rb +144 -0
- data/lib/multi_git/tree_entry.rb +86 -0
- data/lib/multi_git/utils.rb +57 -0
- data/lib/multi_git/version.rb +3 -0
- data/lib/multi_git.rb +44 -0
- metadata +138 -0
@@ -0,0 +1,223 @@
|
|
1
|
+
require 'multi_git/repository'
|
2
|
+
require 'multi_git/tree_entry'
|
3
|
+
require 'multi_git/jgit_backend/blob'
|
4
|
+
require 'multi_git/jgit_backend/tree'
|
5
|
+
require 'multi_git/jgit_backend/commit'
|
6
|
+
require 'multi_git/jgit_backend/ref'
|
7
|
+
module MultiGit::JGitBackend
|
8
|
+
class Repository < MultiGit::Repository
|
9
|
+
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
private
|
13
|
+
OBJECT_CLASSES = {
|
14
|
+
:blob => Blob,
|
15
|
+
:tree => Tree,
|
16
|
+
:commit => Commit
|
17
|
+
}
|
18
|
+
|
19
|
+
# These IDs are magic numbers
|
20
|
+
# from the Jgit code:
|
21
|
+
OBJECT_TYPE_IDS = {
|
22
|
+
:commit => 1,
|
23
|
+
:tree => 2,
|
24
|
+
:blob => 3,
|
25
|
+
:tag => 4
|
26
|
+
}
|
27
|
+
|
28
|
+
REVERSE_OBJECT_TYPE_IDS = Hash[ OBJECT_TYPE_IDS.map{|k,v| [v,k]} ]
|
29
|
+
public
|
30
|
+
|
31
|
+
delegate "bare?" => "@git"
|
32
|
+
|
33
|
+
def git_dir
|
34
|
+
@git.getDirectory.to_s
|
35
|
+
end
|
36
|
+
|
37
|
+
def git_work_tree
|
38
|
+
bare? ? nil : @git.getWorkTree.to_s
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(path, options = {})
|
42
|
+
options = initialize_options(path,options)
|
43
|
+
builder = Java::OrgEclipseJgitStorageFile::FileRepositoryBuilder.new
|
44
|
+
builder.setGitDir(Java::JavaIO::File.new(options[:repository]))
|
45
|
+
if options[:working_directory]
|
46
|
+
builder.setWorkTree(Java::JavaIO::File.new(options[:working_directory]))
|
47
|
+
end
|
48
|
+
if options[:index]
|
49
|
+
builder.setIndexFile(Java::JavaIO::File.new(options[:index]))
|
50
|
+
end
|
51
|
+
@git = builder.build
|
52
|
+
if !@git.getObjectDatabase().exists
|
53
|
+
if options[:init]
|
54
|
+
@git.create(!!options[:bare])
|
55
|
+
else
|
56
|
+
raise MultiGit::Error::NotARepository, path
|
57
|
+
end
|
58
|
+
end
|
59
|
+
verify_bareness(path, options)
|
60
|
+
end
|
61
|
+
|
62
|
+
# {include:MultiGit::Repository#write}
|
63
|
+
# @param (see MultiGit::Repository#write)
|
64
|
+
# @raise (see MultiGit::Repository#write)
|
65
|
+
# @return (see MultiGit::Repository#write)
|
66
|
+
def write(content, type = :blob)
|
67
|
+
if content.kind_of? MultiGit::Builder
|
68
|
+
return content >> self
|
69
|
+
end
|
70
|
+
validate_type(type)
|
71
|
+
if content.kind_of? MultiGit::Object
|
72
|
+
if include?(content.oid)
|
73
|
+
return read(content.oid)
|
74
|
+
end
|
75
|
+
content = content.to_io
|
76
|
+
end
|
77
|
+
use_inserter do |inserter|
|
78
|
+
begin
|
79
|
+
t_id = OBJECT_TYPE_IDS[type]
|
80
|
+
reader = nil
|
81
|
+
if content.respond_to? :path
|
82
|
+
path = content.path
|
83
|
+
reader = Java::JavaIO::FileInputStream.new(path)
|
84
|
+
oid = inserter.insert(t_id.to_java(:int), ::File.size(content.path).to_java(:long), reader)
|
85
|
+
else
|
86
|
+
content = content.read if content.respond_to? :read
|
87
|
+
oid = inserter.insert(t_id, content.bytes.to_a.to_java(:byte))
|
88
|
+
end
|
89
|
+
return OBJECT_CLASSES[type].new(self, oid)
|
90
|
+
ensure
|
91
|
+
reader.close if reader
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# {include:MultiGit::Repository#read}
|
97
|
+
# @param (see MultiGit::Repository#read)
|
98
|
+
# @raise (see MultiGit::Repository#read)
|
99
|
+
# @return (see MultiGit::Repository#read)
|
100
|
+
def read(read)
|
101
|
+
java_oid = parse_java(read)
|
102
|
+
object = use_reader{|rdr| rdr.open(java_oid) }
|
103
|
+
type = REVERSE_OBJECT_TYPE_IDS.fetch(object.getType)
|
104
|
+
return OBJECT_CLASSES[type].new(self, java_oid, object)
|
105
|
+
end
|
106
|
+
|
107
|
+
# {include:MultiGit::Repository#ref}
|
108
|
+
# @param (see MultiGit::Repository#ref)
|
109
|
+
# @raise (see MultiGit::Repository#ref)
|
110
|
+
# @return (see MultiGit::Repository#ref)
|
111
|
+
def ref(name)
|
112
|
+
Ref.new(self, name)
|
113
|
+
end
|
114
|
+
|
115
|
+
# @visibility private
|
116
|
+
# @api private
|
117
|
+
def make_tree(entries)
|
118
|
+
fmt = Java::OrgEclipseJgitLib::TreeFormatter.new
|
119
|
+
# git mktree and rugged tree builder sort entries by name
|
120
|
+
# jgit tree builder doesn't
|
121
|
+
entries.sort_by{|name, _, _| name }.each do |name, mode, oid|
|
122
|
+
fmt.append(name,
|
123
|
+
Java::OrgEclipseJgitLib::FileMode.fromBits(mode),
|
124
|
+
Java::OrgEclipseJgitLib::ObjectId.fromString(oid))
|
125
|
+
end
|
126
|
+
use_inserter do |ins|
|
127
|
+
oid = fmt.insertTo(ins)
|
128
|
+
return read(oid)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# @visibility private
|
133
|
+
# @api private
|
134
|
+
def make_commit(commit)
|
135
|
+
bld = Java::OrgEclipseJgitLib::CommitBuilder.new
|
136
|
+
commit[:parents].each do |p|
|
137
|
+
bld.addParentId(oid_to_java p)
|
138
|
+
end
|
139
|
+
bld.setTreeId(oid_to_java commit[:tree])
|
140
|
+
bld.setMessage(commit[:message])
|
141
|
+
bld.setCommitter(person_ident(commit[:committer], commit[:commit_time]))
|
142
|
+
bld.setAuthor(person_ident(commit[:author], commit[:time]))
|
143
|
+
read( use_inserter{|i| i.insert(bld) } )
|
144
|
+
end
|
145
|
+
|
146
|
+
def oid_to_java(oid)
|
147
|
+
Java::OrgEclipseJgitLib::ObjectId.fromString(oid)
|
148
|
+
end
|
149
|
+
|
150
|
+
def person_ident(handle, time)
|
151
|
+
tj = time.to_java(Java::OrgJodaTime::DateTime)
|
152
|
+
Java::OrgEclipseJgitLib::PersonIdent.new(
|
153
|
+
handle.name,
|
154
|
+
handle.email,
|
155
|
+
tj.toDate,
|
156
|
+
tj.getZone.toTimeZone)
|
157
|
+
end
|
158
|
+
|
159
|
+
private :person_ident, :oid_to_java
|
160
|
+
|
161
|
+
# {include:MultiGit::Repository#include?}
|
162
|
+
# @param (see MultiGit::Repository#include?)
|
163
|
+
# @raise (see MultiGit::Repository#include?)
|
164
|
+
# @return (see MultiGit::Repository#include?)
|
165
|
+
def include?(oid)
|
166
|
+
@git.hasObject(Java::OrgEclipseJgitLib::ObjectId.fromString(oid))
|
167
|
+
end
|
168
|
+
|
169
|
+
# {include:MultiGit::Repository#parse}
|
170
|
+
# @param (see MultiGit::Repository#parse)
|
171
|
+
# @raise (see MultiGit::Repository#parse)
|
172
|
+
# @return (see MultiGit::Repository#parse)
|
173
|
+
def parse(ref)
|
174
|
+
return Java::OrgEclipseJgitLib::ObjectId.toString(parse_java(ref))
|
175
|
+
end
|
176
|
+
|
177
|
+
# @visibility private
|
178
|
+
# @api private
|
179
|
+
def parse_java(oidish)
|
180
|
+
return oidish if oidish.kind_of? Java::OrgEclipseJgitLib::AnyObjectId
|
181
|
+
begin
|
182
|
+
oid = @git.resolve(oidish)
|
183
|
+
if oid.nil?
|
184
|
+
raise MultiGit::Error::InvalidReference, oidish
|
185
|
+
end
|
186
|
+
return oid
|
187
|
+
rescue Java::OrgEclipseJgitErrors::AmbiguousObjectException => e
|
188
|
+
raise MultiGit::Error::AmbiguousReference, e
|
189
|
+
rescue Java::OrgEclipseJgitErrors::RevisionSyntaxException => e
|
190
|
+
raise MultiGit::Error::BadRevisionSyntax, e
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
# @visibility private
|
195
|
+
# @api private
|
196
|
+
def use_reader
|
197
|
+
begin
|
198
|
+
rdr = @git.getObjectDatabase.newReader
|
199
|
+
result = yield rdr
|
200
|
+
ensure
|
201
|
+
rdr.release if rdr
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
# @visibility private
|
206
|
+
# @api private
|
207
|
+
def use_inserter
|
208
|
+
begin
|
209
|
+
rdr = @git.getObjectDatabase.newInserter
|
210
|
+
result = yield rdr
|
211
|
+
ensure
|
212
|
+
rdr.release if rdr
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
# @visibility private
|
217
|
+
# @api private
|
218
|
+
def __backend__
|
219
|
+
@git
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# A IO subclass that implements
|
2
|
+
# rewind for java streams with mark set.
|
3
|
+
#
|
4
|
+
# @note This is a Hack
|
5
|
+
# @note Remember to mark the stream before you build this.
|
6
|
+
# @api private
|
7
|
+
class MultiGit::JGitBackend::RewindeableIO < IO
|
8
|
+
import "org.jruby.RubyIO"
|
9
|
+
import "org.jruby.util.io.OpenFile"
|
10
|
+
import "org.jruby.util.io.ChannelStream"
|
11
|
+
import "org.jruby.util.io.ChannelDescriptor"
|
12
|
+
import "java.nio.channels.Channels"
|
13
|
+
def self.new(inputStream)
|
14
|
+
jruby_io = RubyIO.new(JRuby.runtime, self)
|
15
|
+
jruby_io.openFile.setMainStream(
|
16
|
+
ChannelStream.open(
|
17
|
+
JRuby.runtime,
|
18
|
+
ChannelDescriptor.new(
|
19
|
+
Channels.newChannel(inputStream)
|
20
|
+
)
|
21
|
+
)
|
22
|
+
)
|
23
|
+
jruby_io.openFile.setMode(OpenFile::READABLE)
|
24
|
+
io = JRuby.dereference(jruby_io)
|
25
|
+
io.instance_variable_set(:@backend, inputStream)
|
26
|
+
return io
|
27
|
+
end
|
28
|
+
|
29
|
+
def rewind
|
30
|
+
@backend.reset
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'multi_git/tree'
|
2
|
+
require 'multi_git/jgit_backend/object'
|
3
|
+
module MultiGit::JGitBackend
|
4
|
+
|
5
|
+
class Tree < Object
|
6
|
+
|
7
|
+
EMPTY_BYTES = [].to_java :byte
|
8
|
+
|
9
|
+
import 'org.eclipse.jgit.treewalk.CanonicalTreeParser'
|
10
|
+
|
11
|
+
include MultiGit::Tree
|
12
|
+
|
13
|
+
def raw_entries
|
14
|
+
return @raw_entries if @raw_entries
|
15
|
+
repository.use_reader do |reader|
|
16
|
+
entries = []
|
17
|
+
it = CanonicalTreeParser.new(EMPTY_BYTES, reader, java_oid)
|
18
|
+
until it.eof
|
19
|
+
mode = it.getEntryRawMode
|
20
|
+
entries << [it.getEntryPathString, mode, ObjectId.toString(it.getEntryObjectId)]
|
21
|
+
it.next
|
22
|
+
end
|
23
|
+
@raw_entries = entries
|
24
|
+
end
|
25
|
+
return @raw_entries
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'multi_git/utils'
|
2
|
+
module MultiGit
|
3
|
+
|
4
|
+
# This is a base-module for all objects.
|
5
|
+
module Object
|
6
|
+
|
7
|
+
extend Utils::AbstractMethods
|
8
|
+
|
9
|
+
# @return [Repository]
|
10
|
+
attr :repository
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
attr :oid
|
14
|
+
|
15
|
+
# @visibility private
|
16
|
+
def hash
|
17
|
+
oid.hash
|
18
|
+
end
|
19
|
+
|
20
|
+
# @visibility private
|
21
|
+
def ==(other)
|
22
|
+
if other.respond_to? :oid
|
23
|
+
return oid == other.oid
|
24
|
+
end
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
|
28
|
+
alias eql? ==
|
29
|
+
|
30
|
+
# @visibility private
|
31
|
+
def inspect
|
32
|
+
['#<', self.class.name,' ', oid, '>'].join
|
33
|
+
end
|
34
|
+
|
35
|
+
# @!method to_builder
|
36
|
+
# @abstract
|
37
|
+
# Creates a builder which contains everything this object contains.
|
38
|
+
# @return [MultiGit::Builder] a builder
|
39
|
+
abstract :to_builder
|
40
|
+
|
41
|
+
# @!method content
|
42
|
+
# @abstract
|
43
|
+
# Returns an String containing the content of this object.
|
44
|
+
# @return [String]
|
45
|
+
abstract :content
|
46
|
+
|
47
|
+
# @!method to_io
|
48
|
+
# @abstract
|
49
|
+
# Returns an IO with the content of this object.
|
50
|
+
# @return [IO]
|
51
|
+
abstract :to_io
|
52
|
+
|
53
|
+
# @!method bytesize
|
54
|
+
# @abstract
|
55
|
+
# @return [Integer] size in bytes
|
56
|
+
abstract :bytesize
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|