multi_git 0.0.1.alpha1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/lib/multi_git/backend.rb +100 -0
  2. data/lib/multi_git/backend_set.rb +42 -0
  3. data/lib/multi_git/blob.rb +52 -0
  4. data/lib/multi_git/builder.rb +19 -0
  5. data/lib/multi_git/commit.rb +185 -0
  6. data/lib/multi_git/directory.rb +67 -0
  7. data/lib/multi_git/error.rb +67 -0
  8. data/lib/multi_git/executeable.rb +12 -0
  9. data/lib/multi_git/file.rb +35 -0
  10. data/lib/multi_git/git_backend/blob.rb +11 -0
  11. data/lib/multi_git/git_backend/cmd.rb +117 -0
  12. data/lib/multi_git/git_backend/commit.rb +75 -0
  13. data/lib/multi_git/git_backend/object.rb +34 -0
  14. data/lib/multi_git/git_backend/ref.rb +36 -0
  15. data/lib/multi_git/git_backend/repository.rb +162 -0
  16. data/lib/multi_git/git_backend/tree.rb +22 -0
  17. data/lib/multi_git/git_backend.rb +19 -0
  18. data/lib/multi_git/handle.rb +33 -0
  19. data/lib/multi_git/jgit_backend/blob.rb +10 -0
  20. data/lib/multi_git/jgit_backend/commit.rb +45 -0
  21. data/lib/multi_git/jgit_backend/object.rb +48 -0
  22. data/lib/multi_git/jgit_backend/ref.rb +117 -0
  23. data/lib/multi_git/jgit_backend/repository.rb +223 -0
  24. data/lib/multi_git/jgit_backend/rewindeable_io.rb +33 -0
  25. data/lib/multi_git/jgit_backend/tree.rb +28 -0
  26. data/lib/multi_git/jgit_backend.rb +15 -0
  27. data/lib/multi_git/object.rb +59 -0
  28. data/lib/multi_git/ref.rb +381 -0
  29. data/lib/multi_git/repository.rb +190 -0
  30. data/lib/multi_git/rugged_backend/blob.rb +8 -0
  31. data/lib/multi_git/rugged_backend/commit.rb +38 -0
  32. data/lib/multi_git/rugged_backend/object.rb +38 -0
  33. data/lib/multi_git/rugged_backend/ref.rb +32 -0
  34. data/lib/multi_git/rugged_backend/repository.rb +160 -0
  35. data/lib/multi_git/rugged_backend/tree.rb +18 -0
  36. data/lib/multi_git/rugged_backend.rb +16 -0
  37. data/lib/multi_git/submodule.rb +7 -0
  38. data/lib/multi_git/symlink.rb +42 -0
  39. data/lib/multi_git/tree/builder.rb +184 -0
  40. data/lib/multi_git/tree.rb +144 -0
  41. data/lib/multi_git/tree_entry.rb +86 -0
  42. data/lib/multi_git/utils.rb +57 -0
  43. data/lib/multi_git/version.rb +3 -0
  44. data/lib/multi_git.rb +44 -0
  45. 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,15 @@
1
+ module MultiGit
2
+ module JGitBackend
3
+ class << self
4
+
5
+ def load!
6
+ end
7
+
8
+ def open(path, options = {})
9
+ Repository.new(path, options)
10
+ end
11
+
12
+ end
13
+ end
14
+ end
15
+ require 'multi_git/jgit_backend/repository'
@@ -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