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