multi_git 0.0.1.rc1 → 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 568f2ff3c702a98fe88e7f5ac6a1d80f2eae7b17
4
- data.tar.gz: fac8b206478b5fef7c8ebd2e0872832415da0ec4
3
+ metadata.gz: ea6b7b8a649a9690089663d09a517b3be10a73e6
4
+ data.tar.gz: 54172a19b99fec2efe32e090d4f26f7625afd38f
5
5
  SHA512:
6
- metadata.gz: d0092bb34f79f968ded7539c858a72daaf309c5c772130433001d8088ab2519224e0ea72e6d606136e925bbf99770c678b33385d06fbc72ea6f541063ab57645
7
- data.tar.gz: 4ad11a12904c0de1560345983ccac9b5fc6fecf71f63f0fc3183d501b78f02cda0e0de4568c4b8fa5a4b3278d9290204a61fbdb45e28eae828f8436bd128de6a
6
+ metadata.gz: a31a18773445a3a64ff24b5bcccde2925af8b104911cc182c81b087c7e3ea83fbab63a5ba3df6133b64ca7ecb6f9dfe144de1339e750a397cb4f98dc2bfca5e8
7
+ data.tar.gz: e0b1465cc4df5b5e356f5b7304bd3ea0abcd678dc3f7964ee88a006a600a376ee6b5e9bdc4af4a9110c57c0226beea41939ef7381536ebe1eb490710d688a5af
data/lib/multi_git.rb CHANGED
@@ -37,11 +37,11 @@ public
37
37
  # # teardown:
38
38
  # `rm -rf #{dir}`
39
39
  #
40
- #
40
+ # @param [String] directory
41
+ # @param [Hash] options
42
+ # @option options [Boolean] :init if true the repository is automatically created (defaults to: false)
43
+ # @option options [Boolean] :bare if true the repository is expected to be bare
41
44
  # @return [Repository]
42
- #
43
- # @see Backend
44
- #
45
45
  delegate :open => 'best'
46
46
 
47
47
  end
@@ -2,8 +2,10 @@ require 'multi_git/utils'
2
2
  require 'multi_git/error'
3
3
  module MultiGit
4
4
 
5
+ # Backend is an abstract base class for all other Backends.
5
6
  module Backend
6
7
 
8
+ #@!visibility private
7
9
  attr :failed, :exception
8
10
 
9
11
  def check(description, &check)
@@ -28,6 +30,7 @@ module MultiGit
28
30
 
29
31
  private :check, :check!
30
32
 
33
+ # @api developer
31
34
  # @abstract
32
35
  #
33
36
  # This method implements loading the backend files.
@@ -37,6 +40,10 @@ module MultiGit
37
40
 
38
41
  # Opens a git repository.
39
42
  #
43
+ # @param [String] directory
44
+ # @param [Hash] options
45
+ # @option options [Boolean] :init if true the repository is automatically created (defaults to: false)
46
+ # @option options [Boolean] :bare if true the repository is expected to be bare
40
47
  # @return [Repository]
41
48
  def open(directory, options = {})
42
49
  load!
@@ -10,15 +10,18 @@ module MultiGit
10
10
  :blob
11
11
  end
12
12
 
13
+ # @visibility private
13
14
  def ==(other)
14
15
  return false unless other.respond_to? :oid
15
16
  return oid == other.oid
16
17
  end
17
18
 
19
+ # @visibility private
18
20
  def inspect
19
21
  ['<',self.class,' ',oid,'>'].join
20
22
  end
21
23
 
24
+ # @visibility private
22
25
  alias to_s inspect
23
26
  end
24
27
 
@@ -39,9 +42,7 @@ module MultiGit
39
42
  end
40
43
  end
41
44
 
42
- def content
43
- string
44
- end
45
+ alias content string
45
46
 
46
47
  def content=(value)
47
48
  self.string = value.dup
@@ -58,14 +59,32 @@ module MultiGit
58
59
  dig << content
59
60
  return dig.hexdigest
60
61
  end
62
+
63
+ # Turns the blob into a file using the given parent and filename.
64
+ # @param [Object] parent
65
+ # @param [String] name
66
+ # @return [File::Builder]
67
+ def with_parent(parent, name)
68
+ File::Builder.new(parent, name, self)
69
+ end
61
70
  end
62
71
 
63
72
  include Object
64
73
  include Base
65
74
 
75
+ # @return [Builder]
66
76
  def to_builder
67
77
  Builder.new(self)
68
78
  end
69
79
 
80
+ # Turns the blob into a file using the given parent and filename.
81
+ # @param [Object] parent
82
+ # @param [String] name
83
+ # @return [File]
84
+ def with_parent(parent, name)
85
+ File.new(parent, name, self)
86
+ end
87
+
70
88
  end
71
89
  end
90
+ require 'multi_git/file'
@@ -2,6 +2,7 @@ require 'forwardable'
2
2
  require 'multi_git/utils'
3
3
  require 'multi_git/handle'
4
4
  require 'multi_git/builder'
5
+ require 'multi_git/object'
5
6
  module MultiGit
6
7
 
7
8
  module Commit
@@ -10,26 +11,41 @@ module MultiGit
10
11
  extend Utils::AbstractMethods
11
12
  extend Forwardable
12
13
 
13
- # @return String
14
+ # @!attribute message
15
+ # @return [String]
14
16
  abstract :message
15
17
 
16
- # @return Tree
18
+ # @!attribute tree
19
+ # @return [Tree]
17
20
  abstract :tree
18
21
 
19
- # @return [Array<Commit>]
22
+ # @!attribute parents
23
+ # @return [Array<Commit>]
20
24
  abstract :parents
21
25
 
22
- # @return [Time]
26
+ # @!attribute time
27
+ # @return [Time]
23
28
  abstract :time
24
- # @return [Handle]
29
+
30
+ # @!attribute author
31
+ # @return [Handle]
25
32
  abstract :author
26
33
 
27
- # @return [Time]
34
+ # @!attribute commit_time
35
+ # @return [Time]
28
36
  abstract :commit_time
29
- # @return [Handle]
37
+
38
+ # @!attribute committer
39
+ # @return [Handle]
30
40
  abstract :committer
31
41
 
32
- delegate [:[], :/] => :tree
42
+ # @!method [](path)
43
+ # @see (MultiGit::Tree#[])
44
+ delegate :[] => :tree
45
+
46
+ # @!parse alias / []
47
+ delegate :/ => :tree
48
+
33
49
 
34
50
  def type
35
51
  :commit
@@ -49,11 +65,11 @@ module MultiGit
49
65
  # builder = MultiGit::Commit::Builder.new
50
66
  # builder.message = "My first commit"
51
67
  # builder.by "me@example.com"
52
- # builder.tree["a_file"] = "some content"
68
+ # builder["a_file"] = "some content"
53
69
  # # builder is now ready to be inserted
54
70
  # repository = MultiGit.open(dir, init: true)
55
71
  # commit = repository << builder #=> be_a MultiGit::Commit
56
- # commit.tree['a_file'].content #=> eql "some content"
72
+ # commit['a_file'].content #=> eql "some content"
57
73
  # # teardown:
58
74
  # `rm -rf #{dir}`
59
75
  class Builder
@@ -128,6 +144,11 @@ module MultiGit
128
144
  return self
129
145
  end
130
146
 
147
+ extend Forwardable
148
+ # @!method []=(path, content)
149
+ # @see (MultiGit::TreeBuilder#[]=)
150
+ delegate :[]= => :tree
151
+
131
152
  def initialize(from = nil, &block)
132
153
  @parents = []
133
154
  if from.kind_of? Tree
@@ -178,6 +199,7 @@ module MultiGit
178
199
 
179
200
  end
180
201
 
202
+ include Object
181
203
  include Base
182
204
 
183
205
  end
@@ -10,14 +10,12 @@ module MultiGit
10
10
  Utils::MODE_DIRECTORY
11
11
  end
12
12
 
13
- def parent?
14
- !@parent.nil?
15
- end
16
-
17
13
  def size
18
14
  object.size
19
15
  end
20
16
 
17
+ # @param [String] key
18
+ # @return [TreeEntry, nil]
21
19
  def entry(key)
22
20
  e = object.entry(key)
23
21
  e.with_parent(self) if e
@@ -52,23 +50,7 @@ module MultiGit
52
50
  include Tree::Builder::DSL
53
51
  include Base
54
52
 
55
- def make_inner(*args)
56
- if args.any?
57
- if args[0].kind_of?(Tree::Builder)
58
- return args[0]
59
- elsif args[0].kind_of?(Directory)
60
- return args[0].object.to_builder
61
- elsif args[0].kind_of?(Tree)
62
- return args[0].to_builder
63
- end
64
- end
65
- Tree::Builder.new(*args)
66
- end
67
-
68
- def entry_set(key, value)
69
- object.entry_set(key, make_entry(key, value))
70
- end
71
-
53
+ # @return [Hash<String, TreeEntry::Builder>]
72
54
  def entries
73
55
  Hash[
74
56
  object.map{|entry| [entry.name, entry.with_parent(self) ] }
@@ -79,12 +61,32 @@ module MultiGit
79
61
 
80
62
  delegate (Tree::Builder.instance_methods - self.instance_methods) => :object
81
63
 
64
+ # @return [TreeEntry, nil]
82
65
  def from
83
66
  defined?(@from) ? @from : @from = make_from
84
67
  end
85
68
 
69
+ # @visibility private
70
+ # @api private
71
+ def entry_set(key, value)
72
+ object.entry_set(key, make_entry(key, value))
73
+ end
74
+
86
75
  private
87
76
 
77
+ def make_inner(*args)
78
+ if args.any?
79
+ if args[0].kind_of?(Tree::Builder)
80
+ return args[0]
81
+ elsif args[0].kind_of?(Directory)
82
+ return args[0].object.to_builder
83
+ elsif args[0].kind_of?(Tree)
84
+ return args[0].to_builder
85
+ end
86
+ end
87
+ Tree::Builder.new(*args)
88
+ end
89
+
88
90
  def make_from
89
91
  if object.from.nil?
90
92
  nil
@@ -96,6 +98,7 @@ module MultiGit
96
98
 
97
99
  include Base
98
100
 
101
+ # @return [Hash<String, TreeEntry>]
99
102
  def entries
100
103
  @entries ||= Hash[
101
104
  object.map{|entry| [entry.name, entry.with_parent(self) ] }
@@ -67,11 +67,19 @@ module MultiGit
67
67
 
68
68
  def initialize
69
69
  super 'Another process has updated the ref you are currently updating.
70
- This is unlikely to be a problem, no data got lost. You may simply retry the update.
70
+ This is unlikely a problem, no data got lost. You may simply retry the update.
71
71
  If this happens frequently, you may have want to run "git gc" to remove clobber.'
72
72
  end
73
73
  end
74
74
 
75
+ class InvalidReferenceTarget < ArgumentError
76
+ include Error
77
+
78
+ def initialize(supplied_value)
79
+ super "References can only point to instances of MultiGit::Ref, MultiGit::Object, MultiGit::Builder or nil. You supplied: #{supplied_value.inspect}"
80
+ end
81
+ end
82
+
75
83
  class DuplicateConfigKey < Exception
76
84
  include Error
77
85
  end
@@ -13,7 +13,11 @@ module MultiGit
13
13
 
14
14
  class Builder < TreeEntry::Builder
15
15
  include Base
16
+ extend Forwardable
17
+
18
+ delegate (Blob::Builder.instance_methods - self.instance_methods) => :object
16
19
 
20
+ private
17
21
  def make_inner(*args)
18
22
  if args.any?
19
23
  if args[0].kind_of? Blob::Builder
@@ -24,10 +28,6 @@ module MultiGit
24
28
  end
25
29
  Blob::Builder.new(*args)
26
30
  end
27
-
28
- extend Forwardable
29
-
30
- delegate (Blob::Builder.instance_methods - self.instance_methods) => :object
31
31
  end
32
32
 
33
33
  include Base
@@ -9,6 +9,10 @@ module MultiGit
9
9
  true
10
10
  end
11
11
 
12
+ # @param (see MultiGit#open)
13
+ # @raise (see MultiGit#open)
14
+ # @option (see MultiGit#open)
15
+ # @return (see MultiGit#open)
12
16
  def open(directory, options = {})
13
17
  Repository.new(directory, options)
14
18
  end
@@ -5,6 +5,10 @@ module MultiGit
5
5
  def load!
6
6
  end
7
7
 
8
+ # @param (see MultiGit#open)
9
+ # @raise (see MultiGit#open)
10
+ # @option (see MultiGit#open)
11
+ # @return (see MultiGit#open)
8
12
  def open(path, options = {})
9
13
  Repository.new(path, options)
10
14
  end
@@ -20,11 +20,11 @@ module MultiGit
20
20
  end
21
21
 
22
22
  def time
23
- @time ||= java_commit.author_ident.when
23
+ @time ||= date_to_ruby(java_commit.author_ident.when).freeze
24
24
  end
25
25
 
26
26
  def commit_time
27
- @time ||= java_commit.committer_ident.when
27
+ @time ||= date_to_ruby(java_commit.committer_ident.when).freeze
28
28
  end
29
29
 
30
30
  def author
@@ -36,6 +36,10 @@ module MultiGit
36
36
  end
37
37
  private
38
38
 
39
+ def date_to_ruby( date )
40
+ Java::OrgJruby::RubyTime.newTime(JRuby.runtime,Java::OrgJodaTime::DateTime.new(date))
41
+ end
42
+
39
43
  def java_commit
40
44
  @java_commit ||= repository.use_reader{|rd| RevWalk.new(rd).parseCommit(java_oid) }
41
45
  end
@@ -32,9 +32,7 @@ class MultiGit::JGitBackend::Object
32
32
  private
33
33
 
34
34
  def java_stream
35
- stream = java_object.openStream
36
- stream.mark(bytesize)
37
- stream
35
+ java_object.openStream
38
36
  end
39
37
 
40
38
  protected
@@ -5,10 +5,10 @@ module MultiGit
5
5
 
6
6
  include MultiGit::Ref
7
7
 
8
- # HACK!
9
- # @api private
10
- # @visibility private
11
8
  if defined? Java::OrgEclipseJgitStorageFile::RefDirectoryUpdate
9
+ # HACK!
10
+ # @api private
11
+ # @visibility private
12
12
  class Java::OrgEclipseJgitStorageFile::RefDirectoryUpdate
13
13
  public :tryLock, :unlock, :doUpdate, :doDelete
14
14
  end
@@ -10,17 +10,29 @@ class MultiGit::JGitBackend::RewindeableIO < IO
10
10
  import "org.jruby.util.io.ChannelStream"
11
11
  import "org.jruby.util.io.ChannelDescriptor"
12
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)
13
+
14
+ class JavaRewindeableIO < RubyIO
15
+ private
16
+ field_reader :openFile
17
+ field_writer :openFile
18
+
19
+ def initialize(inputStream)
20
+ super(JRuby.runtime, MultiGit::JGitBackend::RewindeableIO)
21
+ self.openFile = OpenFile.new
22
+ openFile.setMainStream(
23
+ ChannelStream.open(
24
+ JRuby.runtime,
25
+ ChannelDescriptor.new(
26
+ Channels.newChannel(inputStream)
27
+ )
20
28
  )
21
- )
22
- )
23
- jruby_io.openFile.setMode(OpenFile::READABLE)
29
+ )
30
+ openFile.setMode(OpenFile::READABLE)
31
+ end
32
+ end
33
+
34
+ def self.new(inputStream)
35
+ jruby_io = JavaRewindeableIO.new(inputStream)
24
36
  io = JRuby.dereference(jruby_io)
25
37
  io.instance_variable_set(:@backend, inputStream)
26
38
  return io
@@ -25,6 +25,7 @@ module MultiGit
25
25
  return false
26
26
  end
27
27
 
28
+ # @visibility private
28
29
  alias eql? ==
29
30
 
30
31
  # @visibility private
data/lib/multi_git/ref.rb CHANGED
@@ -53,7 +53,7 @@ module MultiGit
53
53
  nx = case new
54
54
  when Ref, nil then new
55
55
  when Object, Builder then repository.write(new)
56
- else raise
56
+ else raise Error::InvalidReferenceTarget, new
57
57
  end
58
58
  @target = nx
59
59
  return nx
@@ -224,8 +224,18 @@ module MultiGit
224
224
  end
225
225
 
226
226
  class RecklessUpdater < Updater
227
+ class << self
228
+ attr :updater
229
+ end
230
+
231
+ SUBCLASSES = Hash.new{|hsh,key|
232
+ hsh[key] = Class.new(self) do
233
+ @updater = key
234
+ end
235
+ }
236
+
227
237
  def update( new )
228
- pu = PessimisticFileUpdater.new( ref )
238
+ pu = self.class.updater.new( ref )
229
239
  begin
230
240
  pu.update( new )
231
241
  ensure
@@ -266,10 +276,10 @@ module MultiGit
266
276
  #
267
277
  # @return [MultGit::Ref]
268
278
  def resolve
269
- @leaf = begin
279
+ @leaf ||= begin
270
280
  ref = self
271
281
  loop do
272
- break ref unless ref.symbolic?
282
+ break ref unless ref.target.kind_of? MultiGit::Ref
273
283
  ref = ref.target
274
284
  end
275
285
  end
@@ -333,12 +343,12 @@ module MultiGit
333
343
  # @param lock [:reckless, :optimistic, :pessimistic]
334
344
  # @yield [current_target] Yields the current target and expects the block to return the new target
335
345
  # @yieldparam current_target [MultiGit::Ref, MultiGit::Object, nil] current target
336
- # @yieldreturn [MultiGit::Ref, MultiGit::Object, nil] new target
346
+ # @yieldreturn [MultiGit::Ref, MultiGit::Object, MultiGit::Builder, nil] new target
337
347
  # @return [MultiGit::Ref] The altered ref
338
348
  #
339
349
  # @overload update( value )
340
350
  #
341
- # @param value [Commit, Ref, nil] new target for this ref
351
+ # @param value [MultiGit::Commit, MultiGit::Ref, MultiGit::Builder, nil] new target for this ref
342
352
  # @return [MultiGit::Ref] The altered ref
343
353
  #
344
354
  # @example
@@ -436,7 +446,7 @@ module MultiGit
436
446
  end
437
447
 
438
448
  def reckless_updater
439
- RecklessUpdater
449
+ RecklessUpdater::SUBCLASSES[pessimistic_updater]
440
450
  end
441
451
 
442
452
  def updater_class( block_given, lock )
@@ -445,6 +455,8 @@ module MultiGit
445
455
  when :optimistic then optimistic_updater
446
456
  when :pessimistic then pessimistic_updater
447
457
  when :reckless then reckless_updater
458
+ else
459
+ raise ArgumentError, "Locking method must be either :optimistic, :pessimistic or :reckless. You supplied: #{lock.inspect}"
448
460
  end
449
461
  else
450
462
  pessimistic_updater
@@ -10,6 +10,22 @@ require 'multi_git/executeable'
10
10
  require 'multi_git/submodule'
11
11
 
12
12
  # Abstract base class for all repository implementations.
13
+ #
14
+ # @example Creating a new repository
15
+ # # setup:
16
+ # dir = `mktemp -d`
17
+ # # example:
18
+ # repo = MultiGit.open(dir, init: true) #=> be_a MultiGit::Repository
19
+ # repo.bare? #=> eql false
20
+ # repo.git_dir #=> eql dir + '/.git'
21
+ # repo.git_work_tree #=> eql dir
22
+ # # creating a first commit:
23
+ # repo.branch('master').commit do
24
+ # tree['file'] = 'content'
25
+ # end
26
+ # # teardown:
27
+ # `rm -rf #{dir}`
28
+ #
13
29
  # @abstract
14
30
  class MultiGit::Repository
15
31
 
@@ -29,29 +45,33 @@ public
29
45
 
30
46
  # @!method git_dir
31
47
  # @abstract
32
- # Return the repository base directory
48
+ # Returns the repository directory (the place where the internal stuff is stored)
33
49
  # @return [String]
34
50
  abstract :git_dir
35
51
 
52
+ # @!method git_work_tree
53
+ # @abstract
54
+ # Returns the working directory (the place where your files are)
55
+ # @return [String]
56
+ abstract :git_work_tree
57
+
36
58
  # @!method bare?
37
59
  # @abstract
38
60
  # Is this repository bare?
39
61
  abstract :bare?
40
62
 
41
- # @!method initialize(directory, options = {})
42
- # @param directory [String] a directory
43
- # @option options [Boolean] :init init the repository if it doesn't exist
44
- # @option options [Boolean] :bare open/init the repository bare
63
+ # @!group Object interface
45
64
 
46
- # @!method read(ref)
47
- # Reads a reference.
65
+ # @!method read(expression)
66
+ # Reads an object from the database.
48
67
  #
68
+ # @see http://git-scm.com/docs/git-rev-parse#_specifying_revisions Revision expression syntax
49
69
  # @abstract
50
70
  #
51
71
  # @raise [MultiGit::Error::InvalidReference] if ref is not a valid reference
52
72
  # @raise [MultiGit::Error::AmbiguousReference] if ref refers to multiple objects
53
73
  # @raise [MultiGit::Error::BadRevisionSyntax] if ref does not contain a valid ref-syntax
54
- # @param [String] ref
74
+ # @param [String] expression
55
75
  # @return [MultiGit::Object] object
56
76
  abstract :read
57
77
 
@@ -62,10 +82,12 @@ public
62
82
  # @return [Boolean]
63
83
  abstract :include?
64
84
 
65
- # @!method parse(ref)
66
- # Resolves a reference into an oid.
85
+ # @!method parse(expression)
86
+ # Resolves an expression into an oid.
67
87
  # @abstract
68
- # @param [String] rev
88
+ #
89
+ # @see http://git-scm.com/docs/git-rev-parse#_specifying_revisions Revision expression syntax
90
+ # @param [String] expression
69
91
  # @raise [MultiGit::Error::InvalidReference] if ref is not a valid reference
70
92
  # @raise [MultiGit::Error::AmbiguousReference] if ref refers to multiple objects
71
93
  # @raise [MultiGit::Error::BadRevisionSyntax] if ref does not contain a valid ref-syntax
@@ -78,10 +100,10 @@ public
78
100
  # If called with a String or an IO, this method creates a {MultiGit::Blob} with the
79
101
  # given content. This is the easiest way to create blobs.
80
102
  #
81
- # If called with a {MultiGit::Object}, this method determines if the object does already exist
103
+ # If called with a {MultiGit::Object}, this method determines if the object does already exist
82
104
  # and writes it otherwise.
83
105
  #
84
- # If called with a {MultiGit::Builder}, this method inserts the content of the builder to the
106
+ # If called with a {MultiGit::Builder}, this method inserts the content of the builder to the
85
107
  # repository. This is the easiest way to create trees/commits.
86
108
  #
87
109
  # @abstract
@@ -89,6 +111,14 @@ public
89
111
  # @return [MultiGit::Object] the resulting object
90
112
  abstract :write
91
113
 
114
+ # @!parse alias_method :<<, :write
115
+ def <<(*args,&block)
116
+ write(*args,&block)
117
+ end
118
+
119
+ # @!endgroup
120
+ # @!group References interface
121
+
92
122
  # @!method ref(name)
93
123
  # Opens a reference. A reference is usually known as branch or tag.
94
124
  #
@@ -107,7 +137,7 @@ public
107
137
  # @return [MultiGit::Ref] ref
108
138
  abstract :ref
109
139
 
110
- # Gets the ref
140
+ # Gets the HEAD ref.
111
141
  # @return [Ref] head
112
142
  def head
113
143
  return ref('HEAD')
@@ -115,6 +145,18 @@ public
115
145
 
116
146
  # Opens a branch
117
147
  #
148
+ # @example
149
+ # # setup:
150
+ # dir = `mktemp -d`
151
+ # # example:
152
+ # repository = MultiGit.open(dir, init: true)
153
+ # # getting a local branch
154
+ # repository.branch('master') #=> be_a MultiGit::Ref
155
+ # # getting a remote branch
156
+ # repository.branch('origin/master') #=> be_a MultiGit::Ref
157
+ # # teardown:
158
+ # `rm -rf #{dir}`
159
+ #
118
160
  # @param name [String] branch name
119
161
  # @return [Ref]
120
162
  def branch(name)
@@ -134,8 +176,8 @@ public
134
176
  end
135
177
 
136
178
  # @method each_branch( filter = :all )
137
- # Yields either all, local or remote branches. If called
138
- # with a regular expression it will be used to filter the
179
+ # Yields either all, local or remote branches. If called
180
+ # with a regular expression it will be used to filter the
139
181
  # branches by name.
140
182
  #
141
183
  # @param filter [:all, :local, :remote, Regexp]
@@ -145,7 +187,6 @@ public
145
187
  #
146
188
  abstract :each_branch
147
189
 
148
-
149
190
  # @method each_tag
150
191
  # Yields all tags.
151
192
  #
@@ -160,10 +201,7 @@ public
160
201
  ref(name)
161
202
  end
162
203
 
163
- # @!parse alias_method :<<, :write
164
- def <<(*args,&block)
165
- write(*args,&block)
166
- end
204
+ # !@endgroup
167
205
 
168
206
  # @visibility private
169
207
  def inspect
@@ -254,3 +292,4 @@ protected
254
292
  end
255
293
 
256
294
  end
295
+
@@ -6,6 +6,10 @@ module MultiGit
6
6
  def load!
7
7
  end
8
8
 
9
+ # @param (see MultiGit#open)
10
+ # @raise (see MultiGit#open)
11
+ # @option (see MultiGit#open)
12
+ # @return (see MultiGit#open)
9
13
  def open(path, options = {})
10
14
  Repository.new(path, options)
11
15
  end
@@ -18,6 +18,10 @@ module MultiGit
18
18
 
19
19
  include Base
20
20
 
21
+ def target=(t)
22
+ object.content = t
23
+ end
24
+ private
21
25
  def make_inner(*args)
22
26
  if args.any?
23
27
  if args[0].kind_of? Blob::Builder
@@ -28,11 +32,6 @@ module MultiGit
28
32
  end
29
33
  Blob::Builder.new(*args)
30
34
  end
31
-
32
- def target=(t)
33
- object.content = t
34
- end
35
-
36
35
  end
37
36
 
38
37
  include Base
@@ -16,10 +16,6 @@ module MultiGit
16
16
  :tree
17
17
  end
18
18
 
19
- def parent?
20
- false
21
- end
22
-
23
19
  def key?(key)
24
20
  if key.kind_of? String
25
21
  return entries.key?(key)
@@ -52,10 +48,10 @@ module MultiGit
52
48
  while parts.any?
53
49
  part = parts.pop
54
50
  if part == '..'
55
- unless current.parent?
51
+ unless current.respond_to?(:parent) && p = current.parent
56
52
  raise MultiGit::Error::InvalidTraversal, "Can't traverse to parent of #{current.inspect} since I don't know where it is."
57
53
  end
58
- current = current.parent
54
+ current = p
59
55
  elsif part == '.' || part == ''
60
56
  # do nothing
61
57
  else
@@ -130,10 +126,16 @@ module MultiGit
130
126
  return self
131
127
  end
132
128
 
133
- # @yield [MultiGit::TreeEntry]
129
+
130
+ # @overload each(&block)
131
+ # @yield [entry]
132
+ # @yieldparam entry [MultiGit::TreeEntry]
133
+ #
134
+ # @overload each
135
+ # @return [Enumerable]
134
136
  def each
135
137
  return to_enum unless block_given?
136
- entries.each do |name, entry|
138
+ entries.each do |_, entry|
137
139
  yield entry
138
140
  end
139
141
  return self
@@ -170,31 +172,44 @@ module MultiGit
170
172
  entries.keys
171
173
  end
172
174
 
175
+ # @api private
173
176
  def ==( other )
174
177
  return false unless other.respond_to? :entries
175
178
  entries == other.entries
176
179
  end
177
180
 
181
+ # @api private
182
+ alias eql? ==
183
+
184
+ # @api private
185
+ def hash
186
+ entries.hash
187
+ end
188
+
189
+ # @return [Hash<String, MultiGit::TreeEntry>]
190
+ def entries
191
+ @entries ||= Hash[ raw_entries.map{|name, mode, oid| [name, make_entry(name, mode, oid) ] } ]
192
+ end
178
193
  end
179
194
 
180
195
  include Base
181
196
  include Object
182
197
 
198
+ # @return [Builder]
183
199
  def to_builder
184
200
  Builder.new(self)
185
201
  end
186
202
 
203
+ # @return [Directory]
204
+ def with_parent(parent, name)
205
+ Directory.new(parent, name, self)
206
+ end
207
+
187
208
  # @visibility private
188
209
  def inspect
189
210
  ['#<',self.class.name,' ',oid,' repository:', repository.inspect,'>'].join
190
211
  end
191
-
192
212
  protected
193
- # @return [Hash<String, MultiGit::TreeEntry>]
194
- def entries
195
- @entries ||= Hash[ raw_entries.map{|name, mode, oid| [name, make_entry(name, mode, oid) ] } ]
196
- end
197
-
198
213
  def raw_entries
199
214
  raise Error::NotYetImplemented, "#{self.class}#each_entry"
200
215
  end
@@ -10,28 +10,40 @@ module MultiGit
10
10
  include MultiGit::Builder
11
11
  include Tree::Base
12
12
 
13
- attr :entries
13
+ # @return [Hash<String,MultiGit::TreeEntry::Base>]
14
+ attr :dirty_entries
15
+ private :dirty_entries
16
+
17
+ # @return [MultiGit::Tree::Base, nil]
14
18
  attr :from
15
19
 
16
20
  def initialize(from = nil, &block)
17
- @entries = {}
21
+ @dirty_entries = {}
18
22
  @from = from
19
23
  instance_eval(&block) if block
20
24
  end
21
25
 
26
+ # @param [String] key
27
+ # @return [TreeEntry::Builder, nil]
22
28
  def entry(key)
23
29
  if @from
24
- @entries.fetch(key) do
30
+ dirty_entries.fetch(key) do
25
31
  e = @from.entry(key)
26
32
  if e
27
- @entries[key] = e.to_builder.with_parent(self)
33
+ dirty_entries[key] = e.to_builder.with_parent(self)
28
34
  end
29
35
  end
30
36
  else
31
- @entries[key]
37
+ dirty_entries[key]
32
38
  end
33
39
  end
34
40
 
41
+ # @overload each(&block)
42
+ # @yield [entry]
43
+ # @yieldparam entry [MultiGit::TreeEntry]
44
+ #
45
+ # @overload each
46
+ # @return [Enumerable]
35
47
  def each
36
48
  return to_enum unless block_given?
37
49
  names.each do |name|
@@ -42,7 +54,7 @@ module MultiGit
42
54
  # TODO: cache
43
55
  def names
44
56
  names = @from ? @from.names.dup : []
45
- @entries.each do |k,v|
57
+ dirty_entries.each do |k,v|
46
58
  if v
47
59
  unless names.include? k
48
60
  names << k
@@ -54,13 +66,18 @@ module MultiGit
54
66
  return names
55
67
  end
56
68
 
69
+ # @return [Hash<String,MultiGit::TreeEntry::Builder>]
70
+ def entries
71
+ Hash[names.map do |n| [n, entry(n)] end ]
72
+ end
73
+
57
74
  def size
58
75
  names.size
59
76
  end
60
77
 
61
78
  def >>(repository)
62
79
  ent = []
63
- @entries.each do |name, entry|
80
+ dirty_entries.each do |name, entry|
64
81
  if entry
65
82
  object = repository.write(entry)
66
83
  ent << [name, object.mode, object.oid]
@@ -68,7 +85,7 @@ module MultiGit
68
85
  end
69
86
  if @from
70
87
  @from.each do |entry|
71
- unless @entries.key? entry.name
88
+ unless dirty_entries.key? entry.name
72
89
  ent << [entry.name, entry.mode, entry.oid]
73
90
  end
74
91
  end
@@ -76,8 +93,27 @@ module MultiGit
76
93
  return repository.make_tree(ent)
77
94
  end
78
95
 
96
+ # @param (see Object#with_parent)
97
+ # @return [Directory::Builder]
98
+ def with_parent(parent, name)
99
+ Directory::Builder.new(parent, name, self)
100
+ end
101
+
79
102
  module DSL
80
103
 
104
+ # @overload set(path, options = {:create => true }, &block)
105
+ # @param [String] path
106
+ # @param [Hash] options
107
+ # @yield [parent, name]
108
+ # @yieldparam parent [MultiGit::Tree, nil]
109
+ # @yieldparam name [String]
110
+ # @yieldreturn [#with_parent, nil]
111
+ #
112
+ # @overload set(path, options = {:create => true }, value)
113
+ # @param [String] path
114
+ # @param [Hash] options
115
+ # @param [#with_parent, nil] value
116
+ #
81
117
  def set(key, *args, &block)
82
118
  options = {}
83
119
  case(args.size)
@@ -108,8 +144,9 @@ module MultiGit
108
144
 
109
145
  alias []= set
110
146
 
147
+ # @api private
111
148
  def entry_set(key, value)
112
- entries[key] = make_entry(key, value)
149
+ dirty_entries[key] = make_entry(key, value)
113
150
  end
114
151
 
115
152
  def make_entry(key, value)
@@ -120,12 +157,13 @@ module MultiGit
120
157
  return value
121
158
  elsif value.kind_of? String
122
159
  return MultiGit::File::Builder.new(self, key, value)
123
- elsif value.kind_of? MultiGit::Builder
124
- return value.with_parent(self)
160
+ elsif value.respond_to? :with_parent
161
+ return value.with_parent(self, key)
125
162
  else
126
163
  raise ArgumentError, "No idea what to do with #{value.inspect}"
127
164
  end
128
165
  end
166
+ private :make_entry
129
167
 
130
168
  def traverse_set(current, parts, value, create)
131
169
  if parts.none?
@@ -157,6 +195,7 @@ module MultiGit
157
195
  current.entry_set(part, traverse_set(entry, rest, value, create))
158
196
  return current
159
197
  end
198
+ private :traverse_set
160
199
 
161
200
  def file(name, content = nil, &block)
162
201
  set(name){|parent, name|
@@ -186,6 +225,14 @@ module MultiGit
186
225
  set(name){ nil }
187
226
  end
188
227
 
228
+ def clear
229
+ names.each do |name|
230
+ delete(name)
231
+ end
232
+ return nil
233
+ end
234
+
235
+ # @return [self]
189
236
  def to_builder
190
237
  self
191
238
  end
@@ -199,7 +246,8 @@ module MultiGit
199
246
  # builder.file('a_file','some content')
200
247
  # builder.changed? 'a_file' #=> eq true
201
248
  # builder.changed? 'another_file' #=> eq false
202
- def changed?( path )
249
+ # builder.changed? #=> eq true
250
+ def changed?( path = '.' )
203
251
  begin
204
252
  new = traverse(path)
205
253
  rescue Error::EntryDoesNotExist
@@ -3,8 +3,10 @@ require 'multi_git/object'
3
3
  require 'multi_git/builder'
4
4
  require 'multi_git/walkable'
5
5
  module MultiGit
6
- # A tree entry is like a {MultiGit::Object} or a {MultiGit::Builder} but it
7
- # also has knows it's parent tree.
6
+ # A tree entry is a {MultiGit::Object} or a {MultiGit::Builder} that
7
+ # knows its parent tree and therefore supports several additional operations.
8
+ #
9
+ # @abstract
8
10
  class TreeEntry
9
11
 
10
12
  module Base
@@ -13,7 +15,7 @@ module MultiGit
13
15
 
14
16
  # @return [String]
15
17
  attr :name
16
- # @return [MultiGit::Tree::Base]
18
+ # @return [MultiGit::Tree::Base, nil]
17
19
  attr :parent
18
20
 
19
21
  extend MultiGit::Utils::AbstractMethods
@@ -36,6 +38,17 @@ module MultiGit
36
38
  self.class.new(parent, name, @object)
37
39
  end
38
40
 
41
+ # Returns the full path to this entry.
42
+ #
43
+ # @example
44
+ # tree = MultiGit::Tree::Builder.new do
45
+ # directory "a" do
46
+ # file "b", "content"
47
+ # end
48
+ # end
49
+ # tree['a/b'].path #=> eql 'a/b'
50
+ #
51
+ # @return [String]
39
52
  def path
40
53
  @path ||= begin
41
54
  if parent.respond_to? :path
@@ -46,17 +59,20 @@ module MultiGit
46
59
  end
47
60
  end
48
61
 
62
+ # @visibility private
49
63
  def ==(other)
50
64
  return false unless other.respond_to?(:path) && other.respond_to?(:object) && other.respond_to?(:mode)
51
65
  return (path == other.path) && (object == other.object) && (mode == other.mode)
52
66
  end
53
67
 
68
+ # @visibility private
54
69
  def inspect
55
70
  ['#<', self.class.name,'@',path,' ', object.inspect, '>'].join
56
71
  end
57
- end
72
+ end
58
73
 
59
- class Builder# < Base
74
+ # @abstract
75
+ class Builder
60
76
 
61
77
  include MultiGit::Builder
62
78
  include Base
@@ -93,7 +109,6 @@ module MultiGit
93
109
  self.class::Builder.new(parent, name, object)
94
110
  end
95
111
 
96
-
97
112
  end
98
113
 
99
114
  end
@@ -1,3 +1,3 @@
1
1
  module MultiGit
2
- VERSION = '0.0.1.rc1'
2
+ VERSION = '0.0.1'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: multi_git
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1.rc1
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Hannes Georg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-29 00:00:00.000000000 Z
11
+ date: 2013-10-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -100,62 +100,62 @@ executables: []
100
100
  extensions: []
101
101
  extra_rdoc_files: []
102
102
  files:
103
- - lib/multi_git/handle.rb
104
- - lib/multi_git/commit.rb
105
- - lib/multi_git/walkable.rb
106
- - lib/multi_git/executeable.rb
107
- - lib/multi_git/tree/builder.rb
108
- - lib/multi_git/submodule.rb
103
+ - lib/multi_git.rb
104
+ - lib/multi_git/backend.rb
105
+ - lib/multi_git/backend_set.rb
109
106
  - lib/multi_git/blob.rb
110
- - lib/multi_git/object.rb
107
+ - lib/multi_git/builder.rb
108
+ - lib/multi_git/commit.rb
109
+ - lib/multi_git/config.rb
110
+ - lib/multi_git/config/default_schema.rb
111
+ - lib/multi_git/config/schema.rb
111
112
  - lib/multi_git/directory.rb
112
- - lib/multi_git/jgit_backend.rb
113
- - lib/multi_git/version.rb
114
- - lib/multi_git/file.rb
115
113
  - lib/multi_git/error.rb
116
- - lib/multi_git/refspec.rb
117
- - lib/multi_git/backend.rb
118
- - lib/multi_git/tree.rb
119
- - lib/multi_git/config.rb
120
- - lib/multi_git/ref.rb
121
- - lib/multi_git/builder.rb
122
- - lib/multi_git/remote.rb
123
- - lib/multi_git/git_backend/commit.rb
114
+ - lib/multi_git/executeable.rb
115
+ - lib/multi_git/file.rb
116
+ - lib/multi_git/git_backend.rb
124
117
  - lib/multi_git/git_backend/blob.rb
125
- - lib/multi_git/git_backend/object.rb
126
118
  - lib/multi_git/git_backend/cmd.rb
127
- - lib/multi_git/git_backend/tree.rb
119
+ - lib/multi_git/git_backend/commit.rb
128
120
  - lib/multi_git/git_backend/config.rb
121
+ - lib/multi_git/git_backend/object.rb
129
122
  - lib/multi_git/git_backend/ref.rb
130
123
  - lib/multi_git/git_backend/remote.rb
131
124
  - lib/multi_git/git_backend/repository.rb
132
- - lib/multi_git/symlink.rb
125
+ - lib/multi_git/git_backend/tree.rb
126
+ - lib/multi_git/handle.rb
127
+ - lib/multi_git/jgit_backend.rb
128
+ - lib/multi_git/jgit_backend/blob.rb
129
+ - lib/multi_git/jgit_backend/commit.rb
130
+ - lib/multi_git/jgit_backend/config.rb
131
+ - lib/multi_git/jgit_backend/object.rb
132
+ - lib/multi_git/jgit_backend/ref.rb
133
+ - lib/multi_git/jgit_backend/remote.rb
134
+ - lib/multi_git/jgit_backend/repository.rb
135
+ - lib/multi_git/jgit_backend/rewindeable_io.rb
136
+ - lib/multi_git/jgit_backend/tree.rb
137
+ - lib/multi_git/object.rb
138
+ - lib/multi_git/ref.rb
139
+ - lib/multi_git/refspec.rb
140
+ - lib/multi_git/remote.rb
133
141
  - lib/multi_git/repository.rb
134
- - lib/multi_git/git_backend.rb
135
- - lib/multi_git/config/default_schema.rb
136
- - lib/multi_git/config/schema.rb
137
142
  - lib/multi_git/rugged_backend.rb
138
- - lib/multi_git/utils.rb
139
- - lib/multi_git/tree_entry.rb
140
- - lib/multi_git/backend_set.rb
141
- - lib/multi_git/rugged_backend/commit.rb
142
143
  - lib/multi_git/rugged_backend/blob.rb
143
- - lib/multi_git/rugged_backend/object.rb
144
- - lib/multi_git/rugged_backend/tree.rb
144
+ - lib/multi_git/rugged_backend/commit.rb
145
145
  - lib/multi_git/rugged_backend/config.rb
146
+ - lib/multi_git/rugged_backend/object.rb
146
147
  - lib/multi_git/rugged_backend/ref.rb
147
148
  - lib/multi_git/rugged_backend/remote.rb
148
149
  - lib/multi_git/rugged_backend/repository.rb
149
- - lib/multi_git/jgit_backend/commit.rb
150
- - lib/multi_git/jgit_backend/blob.rb
151
- - lib/multi_git/jgit_backend/object.rb
152
- - lib/multi_git/jgit_backend/tree.rb
153
- - lib/multi_git/jgit_backend/config.rb
154
- - lib/multi_git/jgit_backend/ref.rb
155
- - lib/multi_git/jgit_backend/remote.rb
156
- - lib/multi_git/jgit_backend/repository.rb
157
- - lib/multi_git/jgit_backend/rewindeable_io.rb
158
- - lib/multi_git.rb
150
+ - lib/multi_git/rugged_backend/tree.rb
151
+ - lib/multi_git/submodule.rb
152
+ - lib/multi_git/symlink.rb
153
+ - lib/multi_git/tree.rb
154
+ - lib/multi_git/tree/builder.rb
155
+ - lib/multi_git/tree_entry.rb
156
+ - lib/multi_git/utils.rb
157
+ - lib/multi_git/version.rb
158
+ - lib/multi_git/walkable.rb
159
159
  homepage: https://github.com/hannesg/multi_git
160
160
  licenses:
161
161
  - GPL-3
@@ -171,13 +171,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
171
171
  version: '0'
172
172
  required_rubygems_version: !ruby/object:Gem::Requirement
173
173
  requirements:
174
- - - '>'
174
+ - - '>='
175
175
  - !ruby/object:Gem::Version
176
- version: 1.3.1
176
+ version: '0'
177
177
  requirements:
178
178
  - jar 'org.eclipse.jgit:org.eclipse.jgit'
179
179
  rubyforge_project:
180
- rubygems_version: 2.1.4
180
+ rubygems_version: 2.2.0
181
181
  signing_key:
182
182
  specification_version: 4
183
183
  summary: Use all the git