multi_git 0.0.1.alpha2 → 0.0.1.beta1
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.
- checksums.yaml +7 -0
- data/lib/multi_git/config/default_schema.rb +26 -0
- data/lib/multi_git/config/schema.rb +141 -0
- data/lib/multi_git/config.rb +170 -0
- data/lib/multi_git/error.rb +4 -0
- data/lib/multi_git/git_backend/cmd.rb +9 -4
- data/lib/multi_git/git_backend/commit.rb +1 -1
- data/lib/multi_git/git_backend/config.rb +47 -0
- data/lib/multi_git/git_backend/ref.rb +9 -8
- data/lib/multi_git/git_backend/remote.rb +47 -0
- data/lib/multi_git/git_backend/repository.rb +16 -1
- data/lib/multi_git/jgit_backend/config.rb +52 -0
- data/lib/multi_git/jgit_backend/remote.rb +74 -0
- data/lib/multi_git/jgit_backend/repository.rb +15 -0
- data/lib/multi_git/ref.rb +82 -38
- data/lib/multi_git/refspec.rb +118 -0
- data/lib/multi_git/remote.rb +66 -0
- data/lib/multi_git/repository.rb +17 -0
- data/lib/multi_git/rugged_backend/config.rb +43 -0
- data/lib/multi_git/rugged_backend/remote.rb +66 -0
- data/lib/multi_git/rugged_backend/repository.rb +25 -0
- data/lib/multi_git/tree.rb +28 -9
- data/lib/multi_git/tree_entry.rb +1 -1
- data/lib/multi_git/version.rb +1 -1
- data/lib/multi_git.rb +1 -0
- metadata +16 -13
@@ -4,6 +4,8 @@ require 'multi_git/jgit_backend/blob'
|
|
4
4
|
require 'multi_git/jgit_backend/tree'
|
5
5
|
require 'multi_git/jgit_backend/commit'
|
6
6
|
require 'multi_git/jgit_backend/ref'
|
7
|
+
require 'multi_git/jgit_backend/config'
|
8
|
+
require 'multi_git/jgit_backend/remote'
|
7
9
|
module MultiGit::JGitBackend
|
8
10
|
class Repository < MultiGit::Repository
|
9
11
|
|
@@ -114,6 +116,10 @@ module MultiGit::JGitBackend
|
|
114
116
|
Ref.new(self, name)
|
115
117
|
end
|
116
118
|
|
119
|
+
def config
|
120
|
+
@config ||= Config.new(@git.config)
|
121
|
+
end
|
122
|
+
|
117
123
|
private
|
118
124
|
ALL_FILTER = %r{\Arefs/(?:heads|remotes)}
|
119
125
|
LOCAL_FILTER = %r{\Arefs/heads}
|
@@ -212,6 +218,15 @@ module MultiGit::JGitBackend
|
|
212
218
|
return Java::OrgEclipseJgitLib::ObjectId.toString(parse_java(ref))
|
213
219
|
end
|
214
220
|
|
221
|
+
def remote( name_or_url )
|
222
|
+
if looks_like_remote_url? name_or_url
|
223
|
+
remote = Remote.new(self, name_or_url)
|
224
|
+
else
|
225
|
+
remote = Remote::Persistent.new(self, name_or_url)
|
226
|
+
end
|
227
|
+
return remote
|
228
|
+
end
|
229
|
+
|
215
230
|
# @visibility private
|
216
231
|
# @api private
|
217
232
|
def parse_java(oidish)
|
data/lib/multi_git/ref.rb
CHANGED
@@ -157,7 +157,6 @@ module MultiGit
|
|
157
157
|
def destroy!
|
158
158
|
release_lock(@lock)
|
159
159
|
end
|
160
|
-
|
161
160
|
end
|
162
161
|
|
163
162
|
# @api developer
|
@@ -197,9 +196,17 @@ module MultiGit
|
|
197
196
|
release_lock( lock ) if lock
|
198
197
|
end
|
199
198
|
end
|
199
|
+
end
|
200
200
|
|
201
|
-
|
202
|
-
|
201
|
+
class RecklessUpdater < Updater
|
202
|
+
def update( new )
|
203
|
+
pu = PessimisticFileUpdater.new( ref )
|
204
|
+
begin
|
205
|
+
pu.update( new )
|
206
|
+
ensure
|
207
|
+
pu.destroy!
|
208
|
+
end
|
209
|
+
end
|
203
210
|
end
|
204
211
|
|
205
212
|
extend MultiGit::Utils::AbstractMethods
|
@@ -254,12 +261,6 @@ module MultiGit
|
|
254
261
|
|
255
262
|
alias / []
|
256
263
|
|
257
|
-
def []=(path, options = {}, value)
|
258
|
-
resolve.update(options.fetch(:lock, :pessimistic) ) do |commit|
|
259
|
-
|
260
|
-
end
|
261
|
-
end
|
262
|
-
|
263
264
|
# @!endgroup
|
264
265
|
|
265
266
|
# @!group Utility methods
|
@@ -272,6 +273,10 @@ module MultiGit
|
|
272
273
|
!direct?
|
273
274
|
end
|
274
275
|
|
276
|
+
def detached?
|
277
|
+
symbolic? && !target.kind_of?(Ref)
|
278
|
+
end
|
279
|
+
|
275
280
|
def exists?
|
276
281
|
!target.nil?
|
277
282
|
end
|
@@ -285,22 +290,31 @@ module MultiGit
|
|
285
290
|
# The new target of this reference is the result of the passed block. If
|
286
291
|
# you return nil, the ref will be deleted.
|
287
292
|
#
|
288
|
-
#
|
293
|
+
# @overload update( lock = :optimistic )
|
294
|
+
# By using the lock param you can control the isolation:
|
295
|
+
#
|
296
|
+
# [:reckless] Updates the reference the hard way. Only locks enough
|
297
|
+
# to ensure the integrity of the repository and simply
|
298
|
+
# overwrites concurrent changes.
|
299
|
+
# [:optimistic] If the target is altered during the execution of the
|
300
|
+
# block, a {MultiGit::Error::ConcurrentRefUpdate} is
|
301
|
+
# raised. This is the default as it holds hard locks
|
302
|
+
# only as long as necessary while providing pointfull
|
303
|
+
# isolation.
|
304
|
+
# [:pessimistic] A lock is acquired and held during the execution of the
|
305
|
+
# block. Concurrent updates will wait or fail. This is
|
306
|
+
# good if the block is not retry-able or very small.
|
289
307
|
#
|
290
|
-
# [:optimistic]
|
291
|
-
#
|
292
|
-
#
|
293
|
-
#
|
294
|
-
#
|
295
|
-
# [:pessimistic] A lock is acquired and held during the execution of the
|
296
|
-
# block. Concurrent updates will wait or fail. This is
|
297
|
-
# good if the block is not retry-able or very small.
|
308
|
+
# @param lock [:reckless, :optimistic, :pessimistic]
|
309
|
+
# @yield [current_target] Yields the current target and expects the block to return the new target
|
310
|
+
# @yieldparam current_target [MultiGit::Ref, MultiGit::Object, nil] current target
|
311
|
+
# @yieldreturn [MultiGit::Ref, MultiGit::Object, nil] new target
|
312
|
+
# @return [MultiGit::Ref] The altered ref
|
298
313
|
#
|
299
|
-
# @
|
300
|
-
#
|
301
|
-
#
|
302
|
-
#
|
303
|
-
# @return [MultiGit::Ref] The altered ref
|
314
|
+
# @overload update( value )
|
315
|
+
#
|
316
|
+
# @param value [Commit, Ref, nil] new target for this ref
|
317
|
+
# @return [MultiGit::Ref] The altered ref
|
304
318
|
#
|
305
319
|
# @example
|
306
320
|
# # setup:
|
@@ -320,26 +334,40 @@ module MultiGit
|
|
320
334
|
# repository.ref('refs/heads/master').target #=> eql commit
|
321
335
|
# # teardown:
|
322
336
|
# `rm -rf #{dir}`
|
323
|
-
def update(
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
updater = updater_class.new(self)
|
330
|
-
updater.update( yield(updater.target) )
|
331
|
-
return reload
|
332
|
-
ensure
|
333
|
-
updater.destroy! if updater
|
334
|
-
end
|
337
|
+
def update( value_or_lock = :optimistic )
|
338
|
+
updater = updater_class(block_given?, value_or_lock).new(self)
|
339
|
+
updater.update( block_given? ? yield(updater.target) : value_or_lock )
|
340
|
+
return reload
|
341
|
+
ensure
|
342
|
+
updater.destroy! if updater
|
335
343
|
end
|
336
344
|
|
345
|
+
# Shorthand for deleting this ref.
|
346
|
+
# @return [Ref]
|
337
347
|
def delete
|
338
|
-
update(
|
348
|
+
update( nil )
|
339
349
|
end
|
340
350
|
|
341
|
-
|
342
|
-
|
351
|
+
# Shorthand method to directly create a commit and update the given ref.
|
352
|
+
#
|
353
|
+
# @example
|
354
|
+
# # setup:
|
355
|
+
# dir = `mktemp -d`
|
356
|
+
# repository = MultiGit.open(dir, init: true)
|
357
|
+
# # insert a commit:
|
358
|
+
# repository.head.commit do
|
359
|
+
# tree['a_file'] = 'some_content'
|
360
|
+
# end
|
361
|
+
# # check result:
|
362
|
+
# repository.head['a_file'].content #=> eql 'some_content'
|
363
|
+
# # teardown:
|
364
|
+
# `rm -rf #{dir}`
|
365
|
+
#
|
366
|
+
# @option options :lock [:optimistic, :pessimistic] How to lock during the commit.
|
367
|
+
# @yield
|
368
|
+
# @return [Ref]
|
369
|
+
def commit(options = {}, &block)
|
370
|
+
resolve.update(options.fetch(:lock, :optimistic)) do |current|
|
343
371
|
Commit::Builder.new(current, &block)
|
344
372
|
end
|
345
373
|
return reload
|
@@ -382,6 +410,22 @@ module MultiGit
|
|
382
410
|
PessimisticFileUpdater
|
383
411
|
end
|
384
412
|
|
413
|
+
def reckless_updater
|
414
|
+
RecklessUpdater
|
415
|
+
end
|
416
|
+
|
417
|
+
def updater_class( block_given, lock )
|
418
|
+
if block_given
|
419
|
+
case lock
|
420
|
+
when :optimistic then optimistic_updater
|
421
|
+
when :pessimistic then pessimistic_updater
|
422
|
+
when :reckless then reckless_updater
|
423
|
+
end
|
424
|
+
else
|
425
|
+
pessimistic_updater
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
385
429
|
end
|
386
430
|
|
387
431
|
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module MultiGit
|
2
|
+
|
3
|
+
# A RefSpec describes which and how references are updated during
|
4
|
+
# push and pull.
|
5
|
+
#
|
6
|
+
# It basically says: set the "to" ref to the target of "from"
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# refspecs = MultiGit::RefSpec.parse('master')
|
10
|
+
#
|
11
|
+
class RefSpec < Struct.new(:from,:to,:forced)
|
12
|
+
|
13
|
+
extend Utils::AbstractMethods
|
14
|
+
|
15
|
+
# @!attribute from
|
16
|
+
# @return [String]
|
17
|
+
|
18
|
+
# @!attribute to
|
19
|
+
# @return [String]
|
20
|
+
|
21
|
+
# @!attribute forced
|
22
|
+
# @return [Boolean]
|
23
|
+
|
24
|
+
alias forced? forced
|
25
|
+
|
26
|
+
# @param from [String]
|
27
|
+
# @param to [String]
|
28
|
+
# @param forced [Boolean]
|
29
|
+
def initialize(from,to,forced = false)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
def inspect
|
34
|
+
['#<',self.class,' ',forced ? '+':'',from,':',to,'>'].join
|
35
|
+
end
|
36
|
+
|
37
|
+
def to_s
|
38
|
+
[forced ? '+':'',from,':',to].join
|
39
|
+
end
|
40
|
+
|
41
|
+
class Parser
|
42
|
+
|
43
|
+
REF = %r{\A(\+?)([a-zA-Z/0-9_*]+)?(?:(:)([a-zA-Z/0-9_*]+)?)?\z}
|
44
|
+
|
45
|
+
attr :from_base, :to_base
|
46
|
+
|
47
|
+
def initialize(from_base = 'refs/heads/', to_base )
|
48
|
+
@from_base = from_base
|
49
|
+
@to_base = to_base
|
50
|
+
end
|
51
|
+
|
52
|
+
#
|
53
|
+
# @param args [RefSpec, String, Hash, Range, ...]
|
54
|
+
# @return [Array<RefSpec>]
|
55
|
+
def [](*args)
|
56
|
+
args.collect_concat do |arg|
|
57
|
+
if arg.kind_of? RefSpec
|
58
|
+
[arg]
|
59
|
+
elsif arg.kind_of? String
|
60
|
+
[parse_string(arg)]
|
61
|
+
elsif arg.kind_of? Hash
|
62
|
+
arg.map{|k,v| parse_pair(k,v) }
|
63
|
+
elsif arg.kind_of? Range
|
64
|
+
[parse_pair(arg.begin, arg.end)]
|
65
|
+
else
|
66
|
+
raise ArgumentError, "Expected a String, Hash or Range. Got #{arg.inspect}"
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
def parse_string(string)
|
73
|
+
if ma = REF.match(string)
|
74
|
+
if ma[2]
|
75
|
+
from = normalize(from_base, ma[2])
|
76
|
+
end
|
77
|
+
if ma[3]
|
78
|
+
to = normalize(to_base, ma[4])
|
79
|
+
else
|
80
|
+
to = normalize(to_base, ma[2])
|
81
|
+
end
|
82
|
+
RefSpec.new( from, to, ma[1] == '+' )
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_pair(a,b)
|
87
|
+
RefSpec.new( normalize(from_base,a.to_s), normalize(to_base,b.to_s) )
|
88
|
+
end
|
89
|
+
|
90
|
+
def normalize(base, name)
|
91
|
+
ns = name.split(SLASH, -1)
|
92
|
+
bs = base.split(SLASH, -1)
|
93
|
+
fill_reverse(bs, ns)
|
94
|
+
return bs.join(SLASH)
|
95
|
+
end
|
96
|
+
|
97
|
+
def fill_reverse(a,b)
|
98
|
+
s = a.size - b.size
|
99
|
+
b.each_with_index do |e, i|
|
100
|
+
a[s+i] = e
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
|
106
|
+
DEFAULT_PARSER = Parser.new('refs/remotes/origin/')
|
107
|
+
|
108
|
+
class << self
|
109
|
+
|
110
|
+
def parse(arg)
|
111
|
+
DEFAULT_PARSER[arg].first
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'multi_git/refspec'
|
2
|
+
module MultiGit
|
3
|
+
|
4
|
+
module Remote
|
5
|
+
|
6
|
+
extend Utils::AbstractMethods
|
7
|
+
|
8
|
+
# @!attribute repository
|
9
|
+
# @return [Repository]
|
10
|
+
abstract :repository
|
11
|
+
|
12
|
+
# @!attribute fetch_urls
|
13
|
+
# @return [Enumerable<URI>]
|
14
|
+
abstract :fetch_urls
|
15
|
+
|
16
|
+
# @!attribute push_urls
|
17
|
+
# @return [Enumerable<URI>]
|
18
|
+
abstract :push_urls
|
19
|
+
|
20
|
+
# @!method fetch( *refspecs )
|
21
|
+
# @param refspecs [RefSpec, String, Range, Hash, ...]
|
22
|
+
abstract :fetch
|
23
|
+
|
24
|
+
# @!method push( *refspecs )
|
25
|
+
# @param refspecs [RefSpec, String, Range, Hash, ...]
|
26
|
+
abstract :push
|
27
|
+
|
28
|
+
# @!method save( name )
|
29
|
+
# @param name [String]
|
30
|
+
# @return [Persistent]
|
31
|
+
abstract :save
|
32
|
+
|
33
|
+
module Persistent
|
34
|
+
include Remote
|
35
|
+
extend Utils::AbstractMethods
|
36
|
+
|
37
|
+
# @!attribute name
|
38
|
+
# @return [String, nil]
|
39
|
+
abstract :name
|
40
|
+
|
41
|
+
# @!method save( name = name )
|
42
|
+
# @param name [String]
|
43
|
+
# @return [Persistent]
|
44
|
+
abstract :save
|
45
|
+
|
46
|
+
protected
|
47
|
+
|
48
|
+
def refspec_parser
|
49
|
+
RefSpec::Parser.new("refs/remotes/#{name}/")
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
protected
|
55
|
+
|
56
|
+
def parse_fetch_refspec(*refspecs)
|
57
|
+
refspec_parser[*refspecs]
|
58
|
+
end
|
59
|
+
|
60
|
+
def refspec_parser
|
61
|
+
RefSpec::Parser.new("refs/remotes//")
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
data/lib/multi_git/repository.rb
CHANGED
@@ -21,6 +21,12 @@ protected
|
|
21
21
|
public
|
22
22
|
extend Utils::AbstractMethods
|
23
23
|
|
24
|
+
# @!method config
|
25
|
+
# @abstract
|
26
|
+
# Returns the config
|
27
|
+
# @return [Config]
|
28
|
+
abstract :config
|
29
|
+
|
24
30
|
# @!method git_dir
|
25
31
|
# @abstract
|
26
32
|
# Return the repository base directory
|
@@ -101,6 +107,12 @@ public
|
|
101
107
|
# @return [MultiGit::Ref] ref
|
102
108
|
abstract :ref
|
103
109
|
|
110
|
+
# Gets the ref
|
111
|
+
# @return [Ref] head
|
112
|
+
def head
|
113
|
+
return ref('HEAD')
|
114
|
+
end
|
115
|
+
|
104
116
|
# Opens a branch
|
105
117
|
#
|
106
118
|
# @param name [String] branch name
|
@@ -236,4 +248,9 @@ protected
|
|
236
248
|
raise Error::InvalidObjectType, type.inspect unless VALID_TYPES.include?(type)
|
237
249
|
end
|
238
250
|
|
251
|
+
def looks_like_remote_url?(string)
|
252
|
+
# poor but efficient
|
253
|
+
string.include? '/'
|
254
|
+
end
|
255
|
+
|
239
256
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'forwardable'
|
2
|
+
require 'multi_git/config'
|
3
|
+
module MultiGit
|
4
|
+
module RuggedBackend
|
5
|
+
class Config
|
6
|
+
|
7
|
+
include MultiGit::Config
|
8
|
+
|
9
|
+
def initialize(rugged_config)
|
10
|
+
@rugged_config = rugged_config
|
11
|
+
@config = Hash.new([])
|
12
|
+
rugged_config.each_pair do |qk, value|
|
13
|
+
key = split_key(qk)
|
14
|
+
@config.fetch(key){ @config[key] = [] } << value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def get(section, subsection, key)
|
19
|
+
s = schema_for(section, subsection, key)
|
20
|
+
v = @config[ [section, subsection,key] ]
|
21
|
+
if v.size == 0
|
22
|
+
s.default
|
23
|
+
elsif s.list?
|
24
|
+
s.convert(v)
|
25
|
+
else
|
26
|
+
s.convert(v.last)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def each_explicit_key
|
31
|
+
return to_enum(:each_explicit_key) unless block_given?
|
32
|
+
@config.each_key do |k|
|
33
|
+
yield *k
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
attr :rugged_config
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'multi_git/remote'
|
2
|
+
require 'forwardable'
|
3
|
+
module MultiGit
|
4
|
+
module RuggedBackend
|
5
|
+
class Remote
|
6
|
+
|
7
|
+
include MultiGit::Remote
|
8
|
+
extend Forwardable
|
9
|
+
|
10
|
+
attr :repository
|
11
|
+
|
12
|
+
attr :rugged_remote
|
13
|
+
protected :rugged_remote
|
14
|
+
|
15
|
+
def fetch_urls
|
16
|
+
[rugged_remote.url]
|
17
|
+
end
|
18
|
+
|
19
|
+
# :nocov:
|
20
|
+
if Rugged::Remote.instance_methods.include? :push_url
|
21
|
+
def push_urls
|
22
|
+
[rugged_remote.push_url || rugged_remote.url]
|
23
|
+
end
|
24
|
+
else
|
25
|
+
def push_urls
|
26
|
+
raise Error::NotYetImplemented, 'Rugged::Remote#push_urls is only available in bleeding edge rugged'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# :nocov:
|
30
|
+
|
31
|
+
def initialize( repository, remote )
|
32
|
+
@repository = repository
|
33
|
+
@rugged_remote = remote
|
34
|
+
end
|
35
|
+
|
36
|
+
class Persistent < self
|
37
|
+
|
38
|
+
include MultiGit::Remote::Persistent
|
39
|
+
extend Forwardable
|
40
|
+
|
41
|
+
def_instance_delegator :rugged_remote, :name
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
if Rugged::Remote.instance_methods.include? :clear_refspecs
|
46
|
+
def fetch(*refspecs)
|
47
|
+
rs = parse_fetch_refspec(*refspecs)
|
48
|
+
cl = Rugged::Remote.new(repository.__backend__, fetch_urls.first)
|
49
|
+
cl.clear_refspecs
|
50
|
+
rs.each do |spec|
|
51
|
+
cl.add_fetch(spec.to_s)
|
52
|
+
end
|
53
|
+
cl.connect(:fetch) do |r|
|
54
|
+
r.download
|
55
|
+
end
|
56
|
+
cl.update_tips!
|
57
|
+
end
|
58
|
+
else
|
59
|
+
def fetch(*_)
|
60
|
+
raise Error::NotYetImplemented, 'This rugged version doesn\'t seem to support fetching. You may want to install from HEAD.'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -4,6 +4,8 @@ require 'multi_git/rugged_backend/blob'
|
|
4
4
|
require 'multi_git/rugged_backend/tree'
|
5
5
|
require 'multi_git/rugged_backend/commit'
|
6
6
|
require 'multi_git/rugged_backend/ref'
|
7
|
+
require 'multi_git/rugged_backend/config'
|
8
|
+
require 'multi_git/rugged_backend/remote'
|
7
9
|
module MultiGit::RuggedBackend
|
8
10
|
|
9
11
|
class Repository < MultiGit::Repository
|
@@ -45,6 +47,7 @@ module MultiGit::RuggedBackend
|
|
45
47
|
raise MultiGit::Error::NotARepository, path
|
46
48
|
end
|
47
49
|
end
|
50
|
+
@git.config = Rugged::Config.new(::File.join(@git.path, 'config'))
|
48
51
|
verify_bareness(path, options)
|
49
52
|
end
|
50
53
|
|
@@ -115,6 +118,10 @@ module MultiGit::RuggedBackend
|
|
115
118
|
@git.include?(oid)
|
116
119
|
end
|
117
120
|
|
121
|
+
def config
|
122
|
+
@config ||= Config.new(@git.config)
|
123
|
+
end
|
124
|
+
|
118
125
|
TRUE_LAMBDA = proc{ true }
|
119
126
|
|
120
127
|
def each_branch(filter = :all)
|
@@ -181,6 +188,24 @@ module MultiGit::RuggedBackend
|
|
181
188
|
return read(oid)
|
182
189
|
end
|
183
190
|
|
191
|
+
#
|
192
|
+
def remote( name_or_url )
|
193
|
+
if looks_like_remote_url? name_or_url
|
194
|
+
remote = Rugged::Remote.new(__backend__, name_or_url)
|
195
|
+
else
|
196
|
+
remote = Rugged::Remote.lookup(__backend__, name_or_url)
|
197
|
+
end
|
198
|
+
if remote
|
199
|
+
if remote.name
|
200
|
+
return Remote::Persistent.new(self, remote)
|
201
|
+
else
|
202
|
+
return Remote.new(self, remote)
|
203
|
+
end
|
204
|
+
else
|
205
|
+
return nil
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
184
209
|
private
|
185
210
|
|
186
211
|
def strip_slash(path)
|
data/lib/multi_git/tree.rb
CHANGED
@@ -94,14 +94,37 @@ module MultiGit
|
|
94
94
|
alias / traverse
|
95
95
|
alias [] traverse
|
96
96
|
|
97
|
+
# Works like the builtin Dir.glob
|
98
|
+
#
|
99
|
+
# @param pattern [String] A glob pattern
|
100
|
+
# @param flags [Integer] glob flags
|
101
|
+
# @yield [MultiGit::TreeEntry]
|
102
|
+
# @return [Enumerator] if called without a block
|
103
|
+
# @return self if called with a block
|
104
|
+
#
|
105
|
+
# @example
|
106
|
+
# bld = MultiGit::Tree::Builder.new do
|
107
|
+
# file "file"
|
108
|
+
# directory "folder" do
|
109
|
+
# file "file"
|
110
|
+
# end
|
111
|
+
# end
|
112
|
+
# bld.glob( '**/file' ).map(&:path) #=> eq ['file','folder/file']
|
113
|
+
#
|
114
|
+
# @see http://ruby-doc.org/core/Dir.html#method-c-glob
|
97
115
|
def glob( pattern, flags = 0 )
|
98
116
|
return to_enum(:glob, pattern, flags) unless block_given?
|
99
|
-
l = path.size
|
117
|
+
l = respond_to?(:path) ? path.size : 0
|
100
118
|
flags |= ::File::FNM_PATHNAME
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
119
|
+
if ::File.fnmatch(pattern, '.', flags)
|
120
|
+
yield self
|
121
|
+
end
|
122
|
+
each do |entry|
|
123
|
+
entry.walk_pre do |sub_entry|
|
124
|
+
if ::File.fnmatch(pattern, sub_entry.path[l..-1], flags)
|
125
|
+
yield sub_entry
|
126
|
+
false
|
127
|
+
end
|
105
128
|
end
|
106
129
|
end
|
107
130
|
return self
|
@@ -161,10 +184,6 @@ module MultiGit
|
|
161
184
|
['#<',self.class.name,' ',oid,' repository:', repository.inspect,'>'].join
|
162
185
|
end
|
163
186
|
|
164
|
-
def path
|
165
|
-
''
|
166
|
-
end
|
167
|
-
|
168
187
|
protected
|
169
188
|
# @return [Hash<String, MultiGit::TreeEntry>]
|
170
189
|
def entries
|
data/lib/multi_git/tree_entry.rb
CHANGED
data/lib/multi_git/version.rb
CHANGED