class Git::Base

The main public interface for interacting with Git commands

Instead of creating a Git::Base directly, obtain a Git::Base instance by calling one of the follow {Git} class methods: {Git.open}, {Git.init}, {Git.clone}, or {Git.bare}.

@api public

Attributes

index[R]

returns reference to the git index file

Public Class Methods

bare(git_dir, options = {}) click to toggle source

(see Git.bare)

# File lib/git/base.rb, line 17
def self.bare(git_dir, options = {})
  normalize_paths(options, default_repository: git_dir, bare: true)
  new(options)
end
binary_version(binary_path) click to toggle source
# File lib/git/base.rb, line 41
def self.binary_version(binary_path)
  result, status = execute_git_version(binary_path)

  raise "Failed to get git version: #{status}\n#{result}" unless status.success?

  parse_version_string(result)
end
clone(repository_url, directory, options = {}) click to toggle source

(see Git.clone)

# File lib/git/base.rb, line 23
def self.clone(repository_url, directory, options = {})
  new_options = Git::Lib.new(nil, options[:log]).clone(repository_url, directory, options)
  normalize_paths(new_options, bare: options[:bare] || options[:mirror])
  new(new_options)
end
config() click to toggle source

Returns (and initialize if needed) a Git::Config instance

@return [Git::Config] the current config instance.

# File lib/git/base.rb, line 37
def self.config
  @config ||= Config.new
end
init(directory = '.', options = {}) click to toggle source

(see Git.init)

# File lib/git/base.rb, line 69
def self.init(directory = '.', options = {})
  normalize_paths(options, default_working_directory: directory, default_repository: directory,
                           bare: options[:bare])

  init_options = {
    bare: options[:bare],
    initial_branch: options[:initial_branch]
  }

  directory = options[:bare] ? options[:repository] : options[:working_directory]
  FileUtils.mkdir_p(directory)

  # TODO: this dance seems awkward: this creates a Git::Lib so we can call
  #   init so we can create a new Git::Base which in turn (ultimately)
  #   creates another/different Git::Lib.
  #
  # TODO: maybe refactor so this Git::Bare.init does this:
  #   self.new(opts).init(init_opts) and move all/some of this code into
  #   Git::Bare#init. This way the init method can be called on any
  #   repository you have a Git::Base instance for.  This would not
  #   change the existing interface (other than adding to it).
  #
  Git::Lib.new(options).init(init_options)

  new(options)
end
new(options = {}) click to toggle source

Create an object that executes Git commands in the context of a working copy or a bare repository.

@param [Hash] options The options for this command (see list of valid

options below)

@option options [Pathname] :working_dir the path to the root of the working

directory.  Should be `nil` if executing commands on a bare repository.

@option options [Pathname] :repository used to specify a non-standard path to

the repository directory.  The default is `"#{working_dir}/.git"`.

@option options [Pathname] :index used to specify a non-standard path to an

index file.  The default is `"#{working_dir}/.git/index"`

@option options [Logger] :log A logger to use for Git operations. Git

commands are logged at the `:info` level.  Additional logging is done
at the `:debug` level.

@return [Git::Base] an object that can execute git commands in the context

of the opened working copy or bare repository
# File lib/git/base.rb, line 154
def initialize(options = {})
  options = default_paths(options)
  setup_logger(options[:log])
  initialize_components(options)
end
open(working_dir, options = {}) click to toggle source

(see Git.open)

# File lib/git/base.rb, line 122
def self.open(working_dir, options = {})
  raise ArgumentError, "'#{working_dir}' is not a directory" unless Dir.exist?(working_dir)

  working_dir = root_of_worktree(working_dir) unless options[:repository]

  normalize_paths(options, default_working_directory: working_dir)

  new(options)
end
repository_default_branch(repository, options = {}) click to toggle source

(see Git.default_branch)

# File lib/git/base.rb, line 30
def self.repository_default_branch(repository, options = {})
  Git::Lib.new(nil, options[:log]).repository_default_branch(repository)
end
root_of_worktree(working_dir) click to toggle source
# File lib/git/base.rb, line 96
def self.root_of_worktree(working_dir)
  raise ArgumentError, "'#{working_dir}' does not exist" unless Dir.exist?(working_dir)

  result, status = execute_rev_parse_toplevel(working_dir)
  process_rev_parse_result(result, status, working_dir)
end

Private Class Methods

execute_git_version(binary_path) click to toggle source
# File lib/git/base.rb, line 49
                     def self.execute_git_version(binary_path)
  Open3.capture2e(
    binary_path,
    '-c', 'core.quotePath=true',
    '-c', 'color.ui=false',
    'version'
  )
rescue Errno::ENOENT
  raise "Failed to get git version: #{binary_path} not found"
end
execute_rev_parse_toplevel(working_dir) click to toggle source
# File lib/git/base.rb, line 103
                     def self.execute_rev_parse_toplevel(working_dir)
  Open3.capture2e(
    Git::Base.config.binary_path,
    '-c', 'core.quotePath=true',
    '-c', 'color.ui=false',
    'rev-parse', '--show-toplevel',
    chdir: File.expand_path(working_dir)
  )
rescue Errno::ENOENT
  raise ArgumentError, 'Failed to find the root of the worktree: git binary not found'
end
initial_repository_path(options, default:, bare:) click to toggle source

Determines the initial, potential path to the repository directory

This path is considered ‘initial’ because it is not guaranteed to be the final repository location. For features like submodules or worktrees, this path may point to a text file containing a ‘gitdir:` pointer to the actual repository directory elsewhere. This initial path must be subsequently resolved.

@api private

@param options [Hash] The options hash, checked for ‘[:repository]`.

@param default [String] A fallback path if ‘options` is not set.

@param bare [Boolean] Whether the repository is bare, which changes path resolution.

@return [String] The initial, absolute path to the ‘.git` directory or file.

# File lib/git/base.rb, line 943
                     def self.initial_repository_path(options, default:, bare:)
  if bare
    File.expand_path(options[:repository] || default || Dir.pwd)
  else
    File.expand_path(options[:repository] || '.git', options[:working_directory])
  end
end
normalize_index(options) click to toggle source

Normalize options

If options is a relative directory, convert it to an absolute directory relative to the repository directory

# File lib/git/base.rb, line 979
                     def self.normalize_index(options)
  index = File.expand_path(options[:index] || 'index', options[:repository])
  options[:index] = index
end
normalize_paths( options, default_working_directory: nil, default_repository: nil, bare: false ) click to toggle source

Normalize options before they are sent to Git::Base.new

Updates the options parameter by setting appropriate values for the following keys:

* options[:working_directory]
* options[:repository]
* options[:index]

All three values will be set to absolute paths. An exception is that :working_directory will be set to nil if bare is true.

# File lib/git/base.rb, line 867
                     def self.normalize_paths(
  options, default_working_directory: nil, default_repository: nil, bare: false
)
  normalize_working_directory(options, default: default_working_directory, bare: bare)
  normalize_repository(options, default: default_repository, bare: bare)
  normalize_index(options)
end
normalize_repository(options, default:, bare: false) click to toggle source

Normalize options

If working with a bare repository, set to the first non-nil value out of:

1. `options[:repository]`
2. the `default` parameter
3. the current working directory

Otherwise, set to the first non-nil value of:

1. `options[:repository]`
2. `.git`

Next, if options refers to a file and not a directory, set options to the contents of that file. This is the case when working with a submodule or a secondary working tree (created with git worktree add). In these cases the repository is actually contained/nested within the parent’s repository directory.

Finally, if options is a relative path, convert it to an absolute path relative to:

1. the current directory if working with a bare repository or
2. the working directory if NOT working with a bare repository
# File lib/git/base.rb, line 919
                     def self.normalize_repository(options, default:, bare: false)
  initial_path = initial_repository_path(options, default: default, bare: bare)
  final_path = resolve_gitdir_if_present(initial_path, options[:working_directory])
  options[:repository] = final_path
end
normalize_working_directory(options, default:, bare: false) click to toggle source

Normalize options

If working with a bare repository, set to ‘nil`. Otherwise, set to the first non-nil value of:

1. `options[:working_directory]`,
2. the `default` parameter, or
3. the current working directory

Finally, if options is a relative path, convert it to an absoluite path relative to the current directory.

# File lib/git/base.rb, line 886
                     def self.normalize_working_directory(options, default:, bare: false)
  working_directory =
    if bare
      nil
    else
      File.expand_path(options[:working_directory] || default || Dir.pwd)
    end

  options[:working_directory] = working_directory
end
parse_version_string(raw_string) click to toggle source
# File lib/git/base.rb, line 60
                     def self.parse_version_string(raw_string)
  version_match = raw_string.match(/\d+(\.\d+)+/)
  return [0, 0, 0] unless version_match

  version_parts = version_match[0].split('.').map(&:to_i)
  version_parts.fill(0, version_parts.length...3)
end
process_rev_parse_result(result, status, working_dir) click to toggle source
# File lib/git/base.rb, line 115
                     def self.process_rev_parse_result(result, status, working_dir)
  raise ArgumentError, "'#{working_dir}' is not in a git working tree" unless status.success?

  result.chomp
end
resolve_gitdir_if_present(path, working_dir) click to toggle source

Resolves the path to the actual repository if it’s a ‘gitdir:` pointer file.

If ‘path` points to a file (common in submodules and worktrees), this method reads the `gitdir:` path from it and returns the real repository path. Otherwise, it returns the original path.

@api private

@param path [String] The initial path to the repository, which may be a pointer file.

@param working_dir [String] The working directory, used as a base to resolve the path.

@return [String] The final, resolved absolute path to the repository directory.

# File lib/git/base.rb, line 965
                     def self.resolve_gitdir_if_present(path, working_dir)
  return path unless File.file?(path)

  # The file contains `gitdir: <path>`, so we read the file,
  # extract the path part, and expand it.
  gitdir_pointer = File.read(path).sub(/\Agitdir: /, '').strip
  File.expand_path(gitdir_pointer, working_dir)
end

Public Instance Methods

add(paths = '.', **options) click to toggle source

Update the index from the current worktree to prepare the for the next commit

@example

lib.add('path/to/file')
lib.add(['path/to/file1','path/to/file2'])
lib.add(all: true)

@param [String, Array<String>] paths a file or files to be added to the repository (relative to the worktree root) @param [Hash] options

@option options [Boolean] :all Add, modify, and remove index entries to match the worktree @option options [Boolean] :force Allow adding otherwise ignored files

# File lib/git/base.rb, line 173
def add(paths = '.', **options)
  lib.add(paths, options)
end
add_remote(name, url, opts = {}) click to toggle source

adds a new remote to this repository url can be a git url or a Git::Base object if it’s a local reference

@git.add_remote('scotts_git', 'git://repo.or.cz/rubygit.git')
@git.fetch('scotts_git')
@git.merge('scotts_git/master')

Options:

:fetch => true
:track => <branch_name>
# File lib/git/base.rb, line 187
def add_remote(name, url, opts = {})
  url = url.repo.path if url.is_a?(Git::Base)
  lib.remote_add(name, url, opts)
  Git::Remote.new(self, name)
end
add_tag(name, *options) click to toggle source

Create a new git tag

@example

repo.add_tag('tag_name', object_reference)
repo.add_tag('tag_name', object_reference, {:options => 'here'})
repo.add_tag('tag_name', {:options => 'here'})

@param [String] name The name of the tag to add @param [Hash] options Opstions to pass to ‘git tag`.

See [git-tag](https://git-scm.com/docs/git-tag) for more details.

@option options [boolean] :annotate Make an unsigned, annotated tag object @option options [boolean] :a An alias for the ‘:annotate` option @option options [boolean] :d Delete existing tag with the given names. @option options [boolean] :f Replace an existing tag with the given name (instead of failing) @option options [String] :message Use the given tag message @option options [String] :m An alias for the `:message` option @option options [boolean] :s Make a GPG-signed tag.

# File lib/git/base.rb, line 565
def add_tag(name, *options)
  lib.tag(name, *options)
  tag(name)
end
apply(file) click to toggle source
# File lib/git/base.rb, line 589
def apply(file)
  return unless File.exist?(file)

  lib.apply(file)
end
apply_mail(file) click to toggle source
# File lib/git/base.rb, line 595
def apply_mail(file)
  lib.apply_mail(file) if File.exist?(file)
end
archive(treeish, file = nil, opts = {}) click to toggle source

creates an archive file of the given tree-ish

# File lib/git/base.rb, line 576
def archive(treeish, file = nil, opts = {})
  object(treeish).archive(file, opts)
end
branch(branch_name = current_branch) click to toggle source

@return [Git::Branch] an object for branch_name

# File lib/git/base.rb, line 713
def branch(branch_name = current_branch)
  Git::Branch.new(self, branch_name)
end
branch?(branch) click to toggle source

returns true if the branch exists

# File lib/git/base.rb, line 305
def branch?(branch)
  branch_names = branches.map(&:name)
  branch_names.include?(branch)
end
branches() click to toggle source

@return [Git::Branches] a collection of all the branches in the repository.

Each branch is represented as a {Git::Branch}.
# File lib/git/base.rb, line 719
def branches
  Git::Branches.new(self)
end
cat_file(objectish) click to toggle source
# File lib/git/base.rb, line 696
def cat_file(objectish)
  lib.cat_file(objectish)
end
chdir() { |the Path| ... } click to toggle source

changes current working directory for a block to the git working directory

example

@git.chdir do
  # write files
  @git.add
  @git.commit('message')
end
# File lib/git/base.rb, line 202
def chdir # :yields: the Git::Path
  Dir.chdir(dir.path) do
    yield dir.path
  end
end
checkout(*, **) click to toggle source

checks out a branch as the new git working directory

# File lib/git/base.rb, line 443
def checkout(*, **)
  lib.checkout(*, **)
end
checkout_file(version, file) click to toggle source

checks out an old version of a file

# File lib/git/base.rb, line 448
def checkout_file(version, file)
  lib.checkout_file(version, file)
end
checkout_index(opts = {}) click to toggle source
# File lib/git/base.rb, line 633
def checkout_index(opts = {})
  lib.checkout_index(opts)
end
clean(opts = {}) click to toggle source

cleans the working directory

options:

:force
:d
:ff
# File lib/git/base.rb, line 389
def clean(opts = {})
  lib.clean(opts)
end
commit(message, opts = {}) click to toggle source

commits all pending changes in the index file to the git repository

options:

:all
:allow_empty
:amend
:author
# File lib/git/base.rb, line 430
def commit(message, opts = {})
  lib.commit(message, opts)
end
commit_all(message, opts = {}) click to toggle source

commits all pending changes in the index file to the git repository, but automatically adds all modified files without having to explicitly calling @git.add() on them.

# File lib/git/base.rb, line 437
def commit_all(message, opts = {})
  opts = { add_all: true }.merge(opts)
  lib.commit(message, opts)
end
commit_tree(tree = nil, opts = {}) click to toggle source

@return [Git::Object::Commit] a commit object

# File lib/git/base.rb, line 735
def commit_tree(tree = nil, opts = {})
  Git::Object::Commit.new(self, lib.commit_tree(tree, opts))
end
config(name = nil, value = nil, options = {}) click to toggle source

g.config(‘user.name’, ‘Scott Chacon’) # sets value g.config(‘user.email’, ‘email@email.com’) # sets value g.config(‘user.email’, ‘email@email.com’, file: ‘path/to/custom/config) # sets value in file g.config(’user.name’) # returns ‘Scott Chacon’ g.config # returns whole config hash

# File lib/git/base.rb, line 213
def config(name = nil, value = nil, options = {})
  if name && value
    # set value
    lib.config_set(name, value, options)
  elsif name
    # return value
    lib.config_get(name)
  else
    # return hash
    lib.config_list
  end
end
current_branch() click to toggle source

The name of the branch HEAD refers to or ‘HEAD’ if detached

Returns one of the following:

* The branch name that HEAD refers to (even if it is an unborn branch)
* 'HEAD' if in a detached HEAD state

@return [String] the name of the branch HEAD refers to or ‘HEAD’ if detached

# File lib/git/base.rb, line 708
def current_branch
  lib.branch_current
end
delete_tag(name) click to toggle source

deletes a tag

# File lib/git/base.rb, line 571
def delete_tag(name)
  lib.tag(name, { d: true })
end
describe(committish = nil, opts = {}) click to toggle source
returns the most recent tag that is reachable from a commit

options:

:all
:tags
:contains
:debug
:exact_match
:dirty
:abbrev
:candidates
:long
:always
:match
# File lib/git/base.rb, line 408
def describe(committish = nil, opts = {})
  lib.describe(committish, opts)
end
diff(objectish = 'HEAD', obj2 = nil) click to toggle source

@return [Git::Diff] a Git::Diff object

# File lib/git/base.rb, line 740
def diff(objectish = 'HEAD', obj2 = nil)
  Git::Diff.new(self, objectish, obj2)
end
diff_name_status(objectish = 'HEAD', obj2 = nil)

Provided for backwards compatibility

Alias for: diff_path_status
diff_path_status(objectish = 'HEAD', obj2 = nil) click to toggle source

Returns a Git::Diff::PathStatus object for accessing the name-status report.

@param objectish [String] The first commit or object to compare. Defaults to ‘HEAD’. @param obj2 [String, nil] The second commit or object to compare. @return [Git::Diff::PathStatus]

# File lib/git/base.rb, line 816
def diff_path_status(objectish = 'HEAD', obj2 = nil)
  Git::DiffPathStatus.new(self, objectish, obj2)
end
Also aliased as: diff_name_status
diff_stats(objectish = 'HEAD', obj2 = nil) click to toggle source

Returns a Git::Diff::Stats object for accessing diff statistics.

@param objectish [String] The first commit or object to compare. Defaults to ‘HEAD’. @param obj2 [String, nil] The second commit or object to compare. @return [Git::Diff::Stats]

# File lib/git/base.rb, line 807
def diff_stats(objectish = 'HEAD', obj2 = nil)
  Git::DiffStats.new(self, objectish, obj2)
end
dir() click to toggle source

returns a reference to the working directory

@git.dir.path
@git.dir.writeable?
# File lib/git/base.rb, line 229
def dir
  @working_directory
end
each_conflict(&) { |file, your_version, their_version| ... } click to toggle source

iterates over the files which are unmerged

# File lib/git/base.rb, line 492
def each_conflict(&) # :yields: file, your_version, their_version
  lib.conflicts(&)
end
fetch(remote = 'origin', opts = {}) click to toggle source

fetches changes from a remote branch - this does not modify the working directory, it just gets the changes from the remote if there are any

# File lib/git/base.rb, line 454
def fetch(remote = 'origin', opts = {})
  if remote.is_a?(Hash)
    opts = remote
    remote = nil
  end
  lib.fetch(remote, opts)
end
gblob(objectish) click to toggle source

@return [Git::Object] a Git object

# File lib/git/base.rb, line 745
def gblob(objectish)
  Git::Object.new(self, objectish, 'blob')
end
gc() click to toggle source
# File lib/git/base.rb, line 585
def gc
  lib.gc
end
gcommit(objectish) click to toggle source

@return [Git::Object] a Git object

# File lib/git/base.rb, line 750
def gcommit(objectish)
  Git::Object.new(self, objectish, 'commit')
end
grep(string, path_limiter = nil, opts = {}) click to toggle source

Run a grep for ‘string’ on the HEAD of the git repository

@example Limit grep’s scope by calling grep() from a specific object:

git.object("v2.3").grep('TODO')

@example Using grep results:

git.grep("TODO").each do |sha, arr|
  puts "in blob #{sha}:"
  arr.each do |line_no, match_string|
    puts "\t line #{line_no}: '#{match_string}'"
  end
end

@param string [String] the string to search for @param path_limiter [String, Array] a path or array of paths to limit the search to or nil for no limit @param opts [Hash] options to pass to the underlying ‘git grep` command

@option opts [Boolean] :ignore_case (false) ignore case when matching @option opts [Boolean] :invert_match (false) select non-matching lines @option opts [Boolean] :extended_regexp (false) use extended regular expressions @option opts [String] :object (HEAD) the object to search from

@return [Hash<String, Array>] a hash of arrays

```Ruby
{
   'tree-ish1' => [[line_no1, match_string1], ...],
   'tree-ish2' => [[line_no1, match_string1], ...],
   ...
}
```
# File lib/git/base.rb, line 353
def grep(string, path_limiter = nil, opts = {})
  object('HEAD').grep(string, path_limiter, opts)
end
gtree(objectish) click to toggle source

@return [Git::Object] a Git object

# File lib/git/base.rb, line 755
def gtree(objectish)
  Git::Object.new(self, objectish, 'tree')
end
ignored_files() click to toggle source

List the files in the worktree that are ignored by git @return [Array<String>] the list of ignored files relative to teh root of the worktree

# File lib/git/base.rb, line 360
def ignored_files
  lib.ignored_files
end
is_branch?(branch) click to toggle source
# File lib/git/base.rb, line 310
def is_branch?(branch) # rubocop:disable Naming/PredicatePrefix
  Git.deprecated('Git::Base#is_branch? is deprecated. Use Git::Base#branch? instead.')
  branch?(branch)
end
is_local_branch?(branch) click to toggle source
# File lib/git/base.rb, line 288
def is_local_branch?(branch) # rubocop:disable Naming/PredicatePrefix
  Git.deprecation('Git::Base#is_local_branch? is deprecated. Use Git::Base#local_branch? instead.')
  local_branch?(branch)
end
is_remote_branch?(branch) click to toggle source
# File lib/git/base.rb, line 299
def is_remote_branch?(branch) # rubocop:disable Naming/PredicatePrefix
  Git.deprecated('Git::Base#is_remote_branch? is deprecated. Use Git::Base#remote_branch? instead.')
  remote_branch?(branch)
end
lib() click to toggle source

this is a convenience method for accessing the class that wraps all the actual ‘git’ forked system calls. At some point I hope to replace the Git::Lib class with one that uses native methods or libgit C bindings

# File lib/git/base.rb, line 318
def lib
  @lib ||= Git::Lib.new(self, @logger)
end
local_branch?(branch) click to toggle source

returns true if the branch exists locally

# File lib/git/base.rb, line 283
def local_branch?(branch)
  branch_names = branches.local.map(&:name)
  branch_names.include?(branch)
end
log(count = 30) click to toggle source

@return [Git::Log] a log with the specified number of commits

# File lib/git/base.rb, line 760
def log(count = 30)
  Git::Log.new(self, count)
end
ls_files(location = nil) click to toggle source
# File lib/git/base.rb, line 654
def ls_files(location = nil)
  lib.ls_files(location)
end
ls_tree(objectish, opts = {}) click to toggle source
# File lib/git/base.rb, line 692
def ls_tree(objectish, opts = {})
  lib.ls_tree(objectish, opts)
end
merge(branch, message = 'merge', opts = {}) click to toggle source

merges one or more branches into the current working branch

you can specify more than one branch to merge by passing an array of branches

# File lib/git/base.rb, line 487
def merge(branch, message = 'merge', opts = {})
  lib.merge(branch, message, opts)
end
merge_base(*) click to toggle source

Find as good common ancestors as possible for a merge example: g.merge_base(‘master’, ‘some_branch’, ‘some_sha’, octopus: true)

@return [Array<Git::Object::Commit>] a collection of common ancestors

# File lib/git/base.rb, line 797
def merge_base(*)
  shas = lib.merge_base(*)
  shas.map { |sha| gcommit(sha) }
end
object(objectish) click to toggle source

returns a Git::Object of the appropriate type you can also call @git.gtree(‘tree’), but that’s just for readability. If you call @git.gtree(‘HEAD’) it will still return a Git::Object::Commit object.

object calls a method that will run a rev-parse on the objectish and determine the type of the object and return an appropriate object for that type

@return [Git::Object] an instance of the appropriate type of Git::Object

# File lib/git/base.rb, line 774
def object(objectish)
  Git::Object.new(self, objectish)
end
pull(remote = nil, branch = nil, opts = {}) click to toggle source

Pulls the given branch from the given remote into the current branch

@param remote [String] the remote repository to pull from @param branch [String] the branch to pull from @param opts [Hash] options to pass to the pull command

@option opts [Boolean] :allow_unrelated_histories (false) Merges histories of two projects that started their

lives independently

@example pulls from origin/master

@git.pull

@example pulls from upstream/master

@git.pull('upstream')

@example pulls from upstream/develop

@git.pull('upstream', 'develop')

@return [Void]

@raise [Git::FailedError] if the pull fails @raise [ArgumentError] if a branch is given without a remote

# File lib/git/base.rb, line 515
def pull(remote = nil, branch = nil, opts = {})
  lib.pull(remote, branch, opts)
end
push(*, **) click to toggle source

Push changes to a remote repository

@overload push(remote = nil, branch = nil, options = {})

@param remote [String] the remote repository to push to
@param branch [String] the branch to push
@param options [Hash] options to pass to the push command

@option opts [Boolean] :mirror (false) Push all refs under refs/heads/, refs/tags/ and refs/remotes/
@option opts [Boolean] :delete (false) Delete refs that don't exist on the remote
@option opts [Boolean] :force (false) Force updates
@option opts [Boolean] :tags (false) Push all refs under refs/tags/
@option opts [Array, String] :push_options (nil) Push options to transmit

@return [Void]

@raise [Git::FailedError] if the push fails
@raise [ArgumentError] if a branch is given without a remote
# File lib/git/base.rb, line 480
def push(*, **)
  lib.push(*, **)
end
read_tree(treeish, opts = {}) click to toggle source
# File lib/git/base.rb, line 637
def read_tree(treeish, opts = {})
  lib.read_tree(treeish, opts)
end
remote(remote_name = 'origin') click to toggle source

@return [Git::Remote] a remote of the specified name

# File lib/git/base.rb, line 779
def remote(remote_name = 'origin')
  Git::Remote.new(self, remote_name)
end
remote_branch?(branch) click to toggle source

returns true if the branch exists remotely

# File lib/git/base.rb, line 294
def remote_branch?(branch)
  branch_names = branches.remote.map(&:name)
  branch_names.include?(branch)
end
remotes() click to toggle source

returns an array of Git:Remote objects

# File lib/git/base.rb, line 520
def remotes
  lib.remotes.map { |r| Git::Remote.new(self, r) }
end
remove(path = '.', opts = {})
Alias for: rm
remove_remote(name) click to toggle source

removes a remote from this repository

@git.remove_remote(‘scott_git’)

# File lib/git/base.rb, line 538
def remove_remote(name)
  lib.remote_remove(name)
end
repack() click to toggle source

repacks the repository

# File lib/git/base.rb, line 581
def repack
  lib.repack
end
repo() click to toggle source

returns reference to the git repository directory

@git.dir.path
# File lib/git/base.rb, line 238
def repo
  @repository
end
repo_size() click to toggle source

returns the repository size in bytes

# File lib/git/base.rb, line 243
def repo_size
  all_files = Dir.glob(File.join(repo.path, '**', '*'), File::FNM_DOTMATCH)

  all_files.reject { |file| file.include?('..') }
           .map { |file| File.expand_path(file) }
           .uniq
           .sum { |file| File.stat(file).size.to_i }
end
reset(commitish = nil, opts = {}) click to toggle source

resets the working directory to the provided commitish

# File lib/git/base.rb, line 372
def reset(commitish = nil, opts = {})
  lib.reset(commitish, opts)
end
reset_hard(commitish = nil, opts = {}) click to toggle source

resets the working directory to the commitish with ‘–hard’

# File lib/git/base.rb, line 377
def reset_hard(commitish = nil, opts = {})
  opts = { hard: true }.merge(opts)
  lib.reset(commitish, opts)
end
rev_parse(objectish) click to toggle source

runs git rev-parse to convert the objectish to a full sha

@example

git.rev_parse("HEAD^^")
git.rev_parse('v2.4^{tree}')
git.rev_parse('v2.4:/doc/index.html')
# File lib/git/base.rb, line 685
def rev_parse(objectish)
  lib.rev_parse(objectish)
end
Also aliased as: revparse
revert(commitish = nil, opts = {}) click to toggle source

reverts the working directory to the provided commitish. Accepts a range, such as comittish..HEAD

options:

:no_edit
# File lib/git/base.rb, line 418
def revert(commitish = nil, opts = {})
  lib.revert(commitish, opts)
end
revparse(objectish)

For backwards compatibility

Alias for: rev_parse
rm(path = '.', opts = {}) click to toggle source

removes file(s) from the git repository

# File lib/git/base.rb, line 365
def rm(path = '.', opts = {})
  lib.rm(path, opts)
end
Also aliased as: remove
set_index(index_file, check = nil, must_exist: nil) click to toggle source
# File lib/git/base.rb, line 252
def set_index(index_file, check = nil, must_exist: nil)
  unless check.nil?
    Git::Deprecation.warn(
      'The "check" argument is deprecated and will be removed in a future version. ' \
      'Use "must_exist:" instead.'
    )
  end

  # default is true
  must_exist = must_exist.nil? && check.nil? ? true : must_exist | check

  @lib = nil
  @index = Git::Index.new(index_file.to_s, must_exist:)
end
set_remote_url(name, url) click to toggle source

sets the url for a remote url can be a git url or a Git::Base object if it’s a local reference

@git.set_remote_url('scotts_git', 'git://repo.or.cz/rubygit.git')
# File lib/git/base.rb, line 529
def set_remote_url(name, url)
  url = url.repo.path if url.is_a?(Git::Base)
  lib.remote_set_url(name, url)
  Git::Remote.new(self, name)
end
set_working(work_dir, check = nil, must_exist: nil) click to toggle source
# File lib/git/base.rb, line 267
def set_working(work_dir, check = nil, must_exist: nil)
  unless check.nil?
    Git::Deprecation.warn(
      'The "check" argument is deprecated and will be removed in a future version. ' \
      'Use "must_exist:" instead.'
    )
  end

  # default is true
  must_exist = must_exist.nil? && check.nil? ? true : must_exist | check

  @lib = nil
  @working_directory = Git::WorkingDirectory.new(work_dir.to_s, must_exist:)
end
show(objectish = nil, path = nil) click to toggle source

Shows objects

@param [String|NilClass] objectish the target object reference (nil == HEAD) @param [String|NilClass] path the path of the file to be shown @return [String] the object information

# File lib/git/base.rb, line 604
def show(objectish = nil, path = nil)
  lib.show(objectish, path)
end
status() click to toggle source

@return [Git::Status] a status object

# File lib/git/base.rb, line 784
def status
  Git::Status.new(self)
end
tag(tag_name) click to toggle source

@return [Git::Object::Tag] a tag object

# File lib/git/base.rb, line 789
def tag(tag_name)
  Git::Object::Tag.new(self, tag_name)
end
tags() click to toggle source

returns an array of all Git::Tag objects for this repository

# File lib/git/base.rb, line 543
def tags
  lib.tags.map { |r| tag(r) }
end
update_ref(branch, commit) click to toggle source
# File lib/git/base.rb, line 650
def update_ref(branch, commit)
  branch(branch).update_ref(commit)
end
with_index(new_index) { |new_index| ... } click to toggle source

LOWER LEVEL INDEX OPERATIONS ##

# File lib/git/base.rb, line 610
def with_index(new_index) # :yields: new_index
  old_index = @index
  set_index(new_index, false)
  return_value = yield @index
  set_index(old_index)
  return_value
end
with_temp_index(&) click to toggle source
# File lib/git/base.rb, line 618
def with_temp_index(&)
  # Workaround for JRUBY, since they handle the TempFile path different.
  # MUST be improved to be safer and OS independent.
  if RUBY_PLATFORM == 'java'
    temp_path = "/tmp/temp-index-#{(0...15).map { ('a'..'z').to_a[rand(26)] }.join}"
  else
    tempfile = Tempfile.new('temp-index')
    temp_path = tempfile.path
    tempfile.close
    tempfile.unlink
  end

  with_index(temp_path, &)
end
with_temp_working(&) click to toggle source
# File lib/git/base.rb, line 669
def with_temp_working(&)
  tempfile = Tempfile.new('temp-workdir')
  temp_dir = tempfile.path
  tempfile.close
  tempfile.unlink
  Dir.mkdir(temp_dir, 0o700)
  with_working(temp_dir, &)
end
with_working(work_dir) { |the WorkingDirectory| ... } click to toggle source
# File lib/git/base.rb, line 658
def with_working(work_dir) # :yields: the Git::WorkingDirectory
  return_value = false
  old_working = @working_directory
  set_working(work_dir)
  Dir.chdir work_dir do
    return_value = yield @working_directory
  end
  set_working(old_working)
  return_value
end
worktree(dir, commitish = nil) click to toggle source

returns a Git::Worktree object for dir, commitish

# File lib/git/base.rb, line 724
def worktree(dir, commitish = nil)
  Git::Worktree.new(self, dir, commitish)
end
worktrees() click to toggle source

returns a Git::worktrees object of all the Git::Worktrees objects for this repo

# File lib/git/base.rb, line 730
def worktrees
  Git::Worktrees.new(self)
end
write_and_commit_tree(opts = {}) click to toggle source
# File lib/git/base.rb, line 645
def write_and_commit_tree(opts = {})
  tree = write_tree
  commit_tree(tree, opts)
end
write_tree() click to toggle source
# File lib/git/base.rb, line 641
def write_tree
  lib.write_tree
end

Private Instance Methods

default_paths(options) click to toggle source

Sets default paths in the options hash for direct ‘Git::Base.new` calls

Factory methods like ‘Git.open` pre-populate these options by calling `normalize_paths`, making this a fallback. It avoids mutating the original options hash by returning a new one.

@param options [Hash] the original options hash @return [Hash] a new options hash with defaults applied

# File lib/git/base.rb, line 833
def default_paths(options)
  return options unless (working_dir = options[:working_directory])

  options.dup.tap do |opts|
    opts[:repository] ||= File.join(working_dir, '.git')
    opts[:index] ||= File.join(opts[:repository], 'index')
  end
end
initialize_components(options) click to toggle source

Initializes the core git objects based on the provided options @param options [Hash] The processed options hash.

# File lib/git/base.rb, line 851
def initialize_components(options)
  @working_directory = Git::WorkingDirectory.new(options[:working_directory]) if options[:working_directory]
  @repository = Git::Repository.new(options[:repository]) if options[:repository]
  @index = Git::Index.new(options[:index], must_exist: false) if options[:index]
end
setup_logger(log_option) click to toggle source

Initializes the logger from the provided options @param log_option [Logger, nil] The logger instance from options.

# File lib/git/base.rb, line 844
def setup_logger(log_option)
  @logger = log_option || Logger.new(nil)
  @logger.info('Starting Git')
end