class Bundler::Source::Git

def base_name

def base_name
  File.basename(uri.sub(%r{^(\w+://)?([^/:]+:)},''), ".git")
end

def cache

def cache
  if cached?
    Bundler.ui.info "Updating #{uri}"
    in_cache { git %|fetch --force --quiet "#{uri}" refs/heads/*:refs/heads/*| }
  else
    Bundler.ui.info "Fetching #{uri}"
    FileUtils.mkdir_p(cache_path.dirname)
    git %|clone "#{uri}" "#{cache_path}" --bare --no-hardlinks|
  end
end

def cache_path

def cache_path
  @cache_path ||= Bundler.cache.join("git", "#{base_name}-#{uri_hash}")
end

def cached?

def cached?
  cache_path.exist?
end

def checkout

def checkout
  unless File.exist?(path.join(".git"))
    FileUtils.mkdir_p(path.dirname)
    git %|clone --no-checkout "#{cache_path}" "#{path}"|
  end
  Dir.chdir(path) do
    git "fetch --force --quiet"
    git "reset --hard #{revision}"
  end
end

def git(command)

def git(command)
  out = %x{git #{command}}
  if $? != 0
    raise GitError, "An error has occurred in git. Cannot complete bundling."
  end
  out
end

def in_cache(&blk)

def in_cache(&blk)
  cache unless cached?
  Dir.chdir(cache_path, &blk)
end

def initialize(options)

def initialize(options)
  super
  @uri    = options["uri"]
  @ref    = options["ref"] || options["branch"] || options["tag"] || 'master'
end

def install(spec)

def install(spec)
  Bundler.ui.debug "  * Using git #{uri}"
  if @installed
    Bundler.ui.debug "  * Already checked out revision: #{ref}"
  else
    Bundler.ui.debug "  * Checking out revision: #{ref}"
    checkout
    @installed = true
  end
  generate_bin(spec)
end

def load_spec_files

def load_spec_files
  super
rescue PathError
  raise PathError, "#{to_s} is not checked out. Please run `bundle install`"
end

def lock

def lock
  @ref = @options["ref"] = revision
  checkout
end

def path

def path
  Bundler.install_path.join("#{base_name}-#{uri_hash}-#{ref}")
end

def revision

def revision
  @revision ||= in_cache { git("rev-parse #{ref}").strip }
end

def specs

def specs
  # Start by making sure the git cache is up to date
  cache
  checkout
  local_specs
end

def to_s

def to_s
  ref = @options["ref"] ? @options["ref"][0..6] : @ref
  "#{@uri} (at #{ref})"
end

def uri_hash

def uri_hash
  if uri =~ %r{^\w+://(\w+@)?}
    # Downcase the domain component of the URI
    # and strip off a trailing slash, if one is present
    input = URI.parse(uri).normalize.to_s.sub(%r{/$},'')
  else
    # If there is no URI scheme, assume it is an ssh/git URI
    input = uri
  end
  Digest::SHA1.hexdigest(input)
end