Module: MultiGit::Ref Abstract

Extended by:
Utils::AbstractMethods
Included in:
GitBackend::Ref, JGitBackend::Ref, MultiGit::RuggedBackend::Ref
Defined in:
lib/multi_git/ref.rb

Overview

This module is abstract.

A reference is something that points eihter to another reference or to an Object. So the most noteable method of this class is #target.

Instances of this classe are immuteable and reuseable. All writing methods return new instances.

Defined Under Namespace

Modules: Locking, OptimisticUpdater, PessimisticUpdater Classes: FileUpdater, OptimisticFileUpdater, PessimisticFileUpdater, RecklessUpdater, Updater

Instance Attribute Summary collapse

Treeish methods collapse

Utility methods collapse

Writing methods collapse

Instance Method Summary collapse

Methods included from Utils::AbstractMethods

abstract

Instance Attribute Details

#nameString (readonly)

The full name of this ref e.g. refs/heads/master for the master branch.

Returns:

  • (String)


251
252
253
# File 'lib/multi_git/ref.rb', line 251

def name
  @name
end

#repositoryMultiGit::Repository (readonly)



260
261
262
# File 'lib/multi_git/ref.rb', line 260

def repository
  @repository
end

#targetMultiGit::Ref, ... (readonly)

This method is abstract.

The target of this ref.

Returns:



257
# File 'lib/multi_git/ref.rb', line 257

abstract :target

Instance Method Details

#[](name) ⇒ Object Also known as: /



290
291
292
293
294
295
# File 'lib/multi_git/ref.rb', line 290

def [](name)
  t = resolve.target
  if t
    return t[name]
  end
end

#commit(options = {}) { ... } ⇒ Ref

Shorthand method to directly create a commit and update the given ref.

Examples:

# setup:
dir = `mktemp -d`
repository = MultiGit.open(dir, init: true)
# insert a commit:
repository.head.commit do
  tree['a_file'] = 'some_content'
end
# check result:
repository.head['a_file'].content #=> eql 'some_content'
# teardown:
`rm -rf #{dir}`

Parameters:

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :lock (:optimistic, :pessimistic)

    How to lock during the commit.

Yields:

Returns:



404
405
406
407
408
409
# File 'lib/multi_git/ref.rb', line 404

def commit(options = {}, &block)
  resolve.update(options.fetch(:lock, :optimistic)) do |current|
    Commit::Builder.new(current, &block)
  end
  return reload
end

#deleteRef

Shorthand for deleting this ref.

Returns:



382
383
384
# File 'lib/multi_git/ref.rb', line 382

def delete
  update( nil )
end

#detached?Boolean

Returns:

  • (Boolean)


311
312
313
# File 'lib/multi_git/ref.rb', line 311

def detached?
  symbolic? && !target.kind_of?(Ref)
end

#direct?Boolean

Returns:

  • (Boolean)


303
304
305
# File 'lib/multi_git/ref.rb', line 303

def direct?
  name.include?('/')
end

#exists?Boolean

Returns:

  • (Boolean)


315
316
317
# File 'lib/multi_git/ref.rb', line 315

def exists?
  !target.nil?
end

#reloadMultiGit::Ref

Rereads this reference from the repository.

Returns:



271
272
273
# File 'lib/multi_git/ref.rb', line 271

def reload
  repository.ref(name)
end

#resolveMultGit::Ref

Resolves symbolic references and returns the final reference.

Returns:

  • (MultGit::Ref)


278
279
280
281
282
283
284
285
286
# File 'lib/multi_git/ref.rb', line 278

def resolve
  @leaf ||= begin
    ref = self
    loop do
      break ref unless ref.target.kind_of? MultiGit::Ref
      ref = ref.target
    end
  end
end

#symbolic?Boolean

Returns:

  • (Boolean)


307
308
309
# File 'lib/multi_git/ref.rb', line 307

def symbolic?
  !direct?
end

#update(lock = :optimistic) {|current_target| ... } ⇒ MultiGit::Ref #update(value) ⇒ MultiGit::Ref

Updates the target of this reference.

The new target of this reference is the result of the passed block. If you return nil, the ref will be deleted.

Examples:

# setup:
dir = `mktemp -d`
repository = MultiGit.open(dir, init: true)
# insert a commit:
builder = MultiGit::Commit::Builder.new
builder.tree['a_file'] = 'some_content'
commit = repository.write(builder)
# update the ref:
ref = repository.ref('refs/heads/master') #=> be_a MultiGit::Ref
ref.update do |current_target|
  current_target #=> be_nil
  commit
end
# check result:
repository.ref('refs/heads/master').target #=> eql commit
# teardown:
`rm -rf #{dir}`

Overloads:

  • #update(lock = :optimistic) {|current_target| ... } ⇒ MultiGit::Ref

    By using the lock param you can control the isolation:

    :reckless

    Updates the reference the hard way. Only locks enough to ensure the integrity of the repository and simply overwrites concurrent changes.

    :optimistic

    If the target is altered during the execution of the block, a Error::ConcurrentRefUpdate is raised. This is the default as it holds hard locks only as long as necessary while providing pointfull isolation.

    :pessimistic

    A lock is acquired and held during the execution of the block. Concurrent updates will wait or fail. This is good if the block is not retry-able or very small.

    Parameters:

    • lock (:reckless, :optimistic, :pessimistic) (defaults to: :optimistic)

    Yields:

    • (current_target)

      Yields the current target and expects the block to return the new target

    Yield Parameters:

    Yield Returns:

    Returns:

  • #update(value) ⇒ MultiGit::Ref

    Returns The altered ref.

    Parameters:

    Returns:



372
373
374
375
376
377
378
# File 'lib/multi_git/ref.rb', line 372

def update( value_or_lock = :optimistic )
  updater = updater_class(block_given?, value_or_lock).new(self)
  updater.update( block_given? ? yield(updater.target) : value_or_lock )
  return reload
ensure
  updater.destroy! if updater
end