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.
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