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
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
@!endgroup
 @!group Writing methods
 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.

 @overload update( lock = :optimistic )
   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 {MultiGit::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.

   @param lock [:reckless, :optimistic, :pessimistic]
   @yield [current_target] Yields the current target and expects the block to return the new target
   @yieldparam current_target [MultiGit::Ref, MultiGit::Object, nil] current target
   @yieldreturn [MultiGit::Ref, MultiGit::Object, MultiGit::Builder, nil] new target
   @return [MultiGit::Ref] The altered ref

 @overload update( value )

   @param value [MultiGit::Commit, MultiGit::Ref, MultiGit::Builder, nil] new target for this ref
   @return [MultiGit::Ref] The altered ref

 @example
  # 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}`