Class: Git::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/git/base.rb

Overview

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: open, init, clone, or bare.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Git::Base

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

Options Hash (options):

  • :working_dir (Pathname)

    the path to the root of the working directory. Should be nil if executing commands on a bare repository.

  • :repository (Pathname)

    used to specify a non-standard path to the repository directory. The default is "#{working_dir}/.git".

  • :index (Pathname)

    used to specify a non-standard path to an index file. The default is "#{working_dir}/.git/index"

  • :log (Logger)

    A logger to use for Git operations. Git commands are logged at the :info level. Additional logging is done at the :debug level.

  • :git_ssh (String, nil)

    Path to a custom SSH executable or script. Controls how SSH is configured for this Git::Base instance:

    • If this option is not provided, the global Git::Base.config.git_ssh setting is used.
    • If this option is explicitly set to nil, SSH is disabled for this instance.
    • If this option is a non-empty String, that value is used as the SSH command for this instance, overriding the global Git::Base.config.git_ssh setting.


163
164
165
166
167
168
# File 'lib/git/base.rb', line 163

def initialize(options = {})
  options = default_paths(options)
  setup_logger(options[:log])
  @git_ssh = options.key?(:git_ssh) ? options[:git_ssh] : :use_global_config
  initialize_components(options)
end

Instance Attribute Details

#git_sshString, ... (readonly)

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Returns the per-instance git_ssh configuration value.

This may be:

  • a [String] path when an explicit git_ssh command has been configured
  • the Symbol :use_global_config when this instance is using the global config
  • nil when SSH has been explicitly disabled for this instance


350
351
352
# File 'lib/git/base.rb', line 350

def git_ssh
  @git_ssh
end

#index (readonly)

returns reference to the git index file



244
245
246
# File 'lib/git/base.rb', line 244

def index
  @index
end

Class Method Details

.bare(git_dir, options = {}) ⇒ Git::Base

Open a bare repository

Opens a bare repository located in the git_dir directory. Since there is no working copy, you can not checkout or commit but you can do most read operations.

Examples:

Open a bare repository and retrieve the first commit SHA

repository = Git.bare('ruby-git.git')
puts repository.log[0].sha #=> "64c6fa011d3287bab9158049c85f3e85718854a0"

Options Hash (options):

  • :git_ssh (String, nil)

    An optional custom SSH command

    • If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
    • If nil, disables SSH for this instance.
    • If a non-empty string, uses that value for this instance.
  • :log (Logger)

    A logger to use for Git operations. Git commands are logged at the :info level. Additional logging is done at the :debug level.

See Also:



17
18
19
20
# 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)



43
44
45
46
47
48
49
# File 'lib/git/base.rb', line 43

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 = {}) ⇒ Git::Base

Clone a repository into an empty or newly created directory

Examples:

Clone into the default directory ruby-git

git = Git.clone('https://github.com/ruby-git/ruby-git.git')

Clone and then checkout the development branch

git = Git.clone('https://github.com/ruby-git/ruby-git.git', branch: 'development')

Clone into a different directory my-ruby-git

git = Git.clone('https://github.com/ruby-git/ruby-git.git', 'my-ruby-git')
# or:
git = Git.clone('https://github.com/ruby-git/ruby-git.git', path: 'my-ruby-git')

Create a bare repository in the directory ruby-git.git

git = Git.clone('https://github.com/ruby-git/ruby-git.git', bare: true)

Clone a repository and set a single config option

git = Git.clone(
  'https://github.com/ruby-git/ruby-git.git',
  config: 'submodule.recurse=true'
)

Clone a repository and set multiple config options

git = Git.clone(
  'https://github.com/ruby-git/ruby-git.git',
  config: ['user.name=John Doe', '[email protected]']
)

Clone using a specific SSH key

git = Git.clone(
  '[email protected]:ruby-git/ruby-git.git',
  'local-dir',
  git_ssh: 'ssh -i /path/to/private_key'
)

Options Hash (options):

  • :bare (Boolean)

    Make a bare Git repository. See what is a bare repository?.

  • :branch (String)

    The name of a branch or tag to checkout instead of the default branch.

  • :config (Array, String)

    A list of configuration options to set on the newly created repository.

  • :depth (Integer)

    Create a shallow clone with a history truncated to the specified number of commits.

  • :filter (String)

    Request that the server send a partial clone according to the given filter

  • :single_branch (Boolean, nil)

    Control whether the clone limits fetch refspecs to a single branch.

    • If nil (default), no flag is passed and the Git default is used.
    • If true, --single-branch is passed to limit the refspec to the checkout branch.
    • If false, --no-single-branch is passed to broaden the refspec (useful for shallow clones that should include all branches).
  • :git_ssh (String, nil)

    An optional custom SSH command

    • If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
    • If nil, disables SSH for this instance.
    • If a non-empty string, uses that value for this instance.
  • :log (Logger)

    A logger to use for Git operations. Git commands are logged at the :info level. Additional logging is done at the :debug level.

  • :mirror (Boolean)

    Set up a mirror of the source repository.

  • :origin (String)

    Use the value instead origin to track the upstream repository.

  • :path (Pathname)

    The directory to clone into. May be used as an alternative to the directory parameter. If specified, the path option is used instead of the directory parameter.

  • :recursive (Boolean)

    After the clone is created, initialize all submodules within, using their default settings.

See Also:



23
24
25
26
27
28
29
# File 'lib/git/base.rb', line 23

def self.clone(repository_url, directory, options = {})
  lib_options = {}
  lib_options[:git_ssh] = options[:git_ssh] if options.key?(:git_ssh)
  new_options = Git::Lib.new(lib_options, options[:log]).clone(repository_url, directory, options)
  normalize_paths(new_options, bare: options[:bare] || options[:mirror])
  new(new_options)
end

.configGit::Config

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



39
40
41
# File 'lib/git/base.rb', line 39

def self.config
  @config ||= Config.new
end

.init(directory = '.', options = {}) ⇒ Git::Base

Create an empty Git repository or reinitialize an existing Git repository

Examples:

Initialize a repository in the current directory

git = Git.init

Initialize a repository in some other directory

git = Git.init '~/code/ruby-git'

Initialize a bare repository

git = Git.init '~/code/ruby-git.git', bare: true

Initialize a repository in a non-default location (outside of the working copy)

git = Git.init '~/code/ruby-git', repository: '~/code/ruby-git.git'

Options Hash (options):

  • :bare (Boolean)

    Instead of creating a repository at "#{directory}/.git", create a bare repository at "#{directory}". See what is a bare repository?.

  • :initial_branch (String)

    Use the specified name for the initial branch in the newly created repository.

  • :repository (Pathname)

    the path to put the newly initialized Git repository. The default for non-bare repository is "#{directory}/.git".

    A relative path is referenced from the current working directory of the process and converted to an absolute path using File.expand_path.

  • :git_ssh (String, nil)

    An optional custom SSH command

    • If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
    • If nil, disables SSH for this instance.
    • If a non-empty string, uses that value for this instance.
  • :log (Logger)

    A logger to use for Git operations. Git commands are logged at the :info level. Additional logging is done at the :debug level.

See Also:



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/git/base.rb', line 71

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

.open(working_dir, options = {}) ⇒ Git::Base

Open a an existing Git working directory

Git.open will most likely be the most common way to create a git reference, referring to an existing working directory.

If not provided in the options, the library will assume the repository and index are in the default places (.git/, .git/index).

Examples:

Open the Git working directory in the current directory

git = Git.open

Open a Git working directory in some other directory

git = Git.open('~/Projects/ruby-git')

Use a logger to see what is going on

logger = Logger.new(STDOUT)
git = Git.open('~/Projects/ruby-git', log: logger)

Open a working copy whose repository is in a non-standard directory

git = Git.open('~/Projects/ruby-git', repository: '~/Project/ruby-git.git')

Options Hash (options):

  • :repository (Pathname)

    used to specify a non-standard path to the repository directory. The default is "#{working_dir}/.git".

  • :index (Pathname)

    used to specify a non-standard path to an index file. The default is "#{working_dir}/.git/index"

  • :git_ssh (String, nil)

    An optional custom SSH command

    • If not specified, uses the global config (Git.configure { |c| c.git_ssh = ... }).
    • If nil, disables SSH for this instance.
    • If a non-empty string, uses that value for this instance.
  • :log (Logger)

    A logger to use for Git operations. Git commands are logged at the :info level. Additional logging is done at the :debug level.

Raises:

  • (ArgumentError)


124
125
126
127
128
129
130
131
132
# File 'lib/git/base.rb', line 124

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 = {}) ⇒ String

Returns the name of the default branch of the given repository

Examples:

with a URI string

Git.default_branch('https://github.com/ruby-git/ruby-git') # => 'master'
Git.default_branch('https://github.com/rspec/rspec-core') # => 'main'

with a URI object

repository_uri = URI('https://github.com/ruby-git/ruby-git')
Git.default_branch(repository_uri) # => 'master'

with a local repository

Git.default_branch('.') # => 'master'

with a local repository Pathname

repository_path = Pathname('.')
Git.default_branch(repository_path) # => 'master'

with the logging option

logger = Logger.new(STDOUT, level: Logger::INFO)
Git.default_branch('.', log: logger) # => 'master'
I, [2022-04-13T16:01:33.221596 #18415]  INFO -- : git '-c' 'core.quotePath=true'
  '-c' 'color.ui=false' ls-remote '--symref' '--' '.' 'HEAD'  2>&1

Options Hash (options):

  • :log (Logger)

    A logger to use for Git operations. Git commands are logged at the :info level. Additional logging is done at the :debug level.



32
33
34
# File 'lib/git/base.rb', line 32

def self.repository_default_branch(repository, options = {})
  Git::Lib.new(nil, options[:log]).repository_default_branch(repository)
end

.root_of_worktree(working_dir)

Raises:

  • (ArgumentError)


98
99
100
101
102
103
# File 'lib/git/base.rb', line 98

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

Instance Method Details

#add(paths = '.', **options)

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

Examples:

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

Options Hash (**options):

  • :all (Boolean)

    Add, modify, and remove index entries to match the worktree

  • :force (Boolean)

    Allow adding otherwise ignored files



183
184
185
# File 'lib/git/base.rb', line 183

def add(paths = '.', **options)
  lib.add(paths, options)
end

#add_remote(name, url, opts = {})

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 =>



197
198
199
200
201
# File 'lib/git/base.rb', line 197

def add_remote(name, url, opts = {})
  url = url.repo.to_s if url.is_a?(Git::Base)
  lib.remote_add(name, url, opts)
  Git::Remote.new(self, name)
end

#add_tag(name, *options)

Create a new git tag

Examples:

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

Options Hash (*options):

  • :annotate (boolean)

    Make an unsigned, annotated tag object

  • :a (boolean)

    An alias for the :annotate option

  • :d (boolean)

    Delete existing tag with the given names.

  • :f (boolean)

    Replace an existing tag with the given name (instead of failing)

  • :message (String)

    Use the given tag message

  • :m (String)

    An alias for the :message option

  • :s (boolean)

    Make a GPG-signed tag.



633
634
635
636
# File 'lib/git/base.rb', line 633

def add_tag(name, *options)
  lib.tag(name, *options)
  tag(name)
end

#apply(file)

rubocop:enable Style/ArgumentsForwarding



708
709
710
711
712
# File 'lib/git/base.rb', line 708

def apply(file)
  return unless File.exist?(file)

  lib.apply(file)
end

#apply_mail(file)



714
715
716
# File 'lib/git/base.rb', line 714

def apply_mail(file)
  lib.apply_mail(file) if File.exist?(file)
end

#archive(treeish, file = nil, opts = {})

creates an archive file of the given tree-ish



644
645
646
# File 'lib/git/base.rb', line 644

def archive(treeish, file = nil, opts = {})
  object(treeish).archive(file, opts)
end

#branch(branch_name = current_branch) ⇒ Git::Branch

Returns an object for branch_name.



843
844
845
# File 'lib/git/base.rb', line 843

def branch(branch_name = current_branch)
  Git::Branch.new(self, branch_name)
end

#branch?(branch) ⇒ Boolean

returns +true+ if the branch exists



321
322
323
324
# File 'lib/git/base.rb', line 321

def branch?(branch)
  branch_names = branches.map(&:name)
  branch_names.include?(branch)
end

#branchesGit::Branches

Returns a collection of all the branches in the repository. Each branch is represented as a Git::Branch.



849
850
851
# File 'lib/git/base.rb', line 849

def branches
  Git::Branches.new(self)
end

#cat_file(objectish) ⇒ String

Returns the contents of a git object

Uses git cat-file -p to pretty-print the contents of the given object.

See Also:



826
827
828
# File 'lib/git/base.rb', line 826

def cat_file(objectish)
  lib.cat_file_contents(objectish)
end

#chdir

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

example @git.chdir do # write files @git.add @git.commit('message') end



212
213
214
215
216
# File 'lib/git/base.rb', line 212

def chdir # :yields: the Git::Path
  Dir.chdir(dir.to_s) do
    yield dir.to_s
  end
end

#checkout

checks out a branch as the new git working directory



474
475
476
# File 'lib/git/base.rb', line 474

def checkout(*, **)
  lib.checkout(*, **)
end

#checkout_file(version, file)

checks out an old version of a file



479
480
481
# File 'lib/git/base.rb', line 479

def checkout_file(version, file)
  lib.checkout_file(version, file)
end

#checkout_index(opts = {})



752
753
754
# File 'lib/git/base.rb', line 752

def checkout_index(opts = {})
  lib.checkout_index(opts)
end

#clean(opts = {})

cleans the working directory

options: :force :d :ff



420
421
422
# File 'lib/git/base.rb', line 420

def clean(opts = {})
  lib.clean(opts)
end

#commit(message, opts = {})

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

options: :all :allow_empty :amend :author



461
462
463
# File 'lib/git/base.rb', line 461

def commit(message, opts = {})
  lib.commit(message, opts)
end

#commit_all(message, opts = {})

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.



468
469
470
471
# File 'lib/git/base.rb', line 468

def commit_all(message, opts = {})
  opts = { add_all: true }.merge(opts)
  lib.commit(message, opts)
end

#commit_tree(tree = nil, opts = {}) ⇒ Git::Object::Commit

Returns a commit object.



865
866
867
# File 'lib/git/base.rb', line 865

def commit_tree(tree = nil, opts = {})
  Git::Object::Commit.new(self, lib.commit_tree(tree, opts))
end

#config(name = nil, value = nil, options = {})

g.config('user.name', 'Scott Chacon') # sets value g.config('user.email', '[email protected]') # sets value g.config('user.email', '[email protected]', file: 'path/to/custom/config) # sets value in file g.config('user.name') # returns 'Scott Chacon' g.config # returns whole config hash



223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/git/base.rb', line 223

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_branchString

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


838
839
840
# File 'lib/git/base.rb', line 838

def current_branch
  lib.branch_current
end

#delete_tag(name)

deletes a tag



639
640
641
# File 'lib/git/base.rb', line 639

def delete_tag(name)
  lib.tag(name, { d: true })
end

#describe(committish = nil, opts = {})

returns the most recent tag that is reachable from a commit

options: :all :tags :contains :debug :exact_match :dirty :abbrev :candidates :long :always :match



439
440
441
# File 'lib/git/base.rb', line 439

def describe(committish = nil, opts = {})
  lib.describe(committish, opts)
end

#diff(objectish = 'HEAD', obj2 = nil) ⇒ Git::Diff

Returns a Git::Diff object.



870
871
872
# File 'lib/git/base.rb', line 870

def diff(objectish = 'HEAD', obj2 = nil)
  Git::Diff.new(self, objectish, obj2)
end

#diff_path_status(objectish = 'HEAD', obj2 = nil, opts = {}) ⇒ Git::DiffPathStatus Also known as: diff_name_status

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

Options Hash (opts):

  • :path_limiter (String, Pathname, Array<String, Pathname>)

    Limit status to specified path(s).

  • :path (String, Pathname, Array<String, Pathname>) — default: deprecated

    Legacy alias for :path_limiter.



951
952
953
954
955
956
957
958
959
960
961
962
# File 'lib/git/base.rb', line 951

def diff_path_status(objectish = 'HEAD', obj2 = nil, opts = {})
  path_limiter = if opts.key?(:path_limiter)
                   opts[:path_limiter]
                 elsif opts.key?(:path)
                   Git::Deprecation.warn(
                     'Git::Base#diff_path_status :path option is deprecated. Use :path_limiter instead.'
                   )
                   opts[:path]
                 end

  Git::DiffPathStatus.new(self, objectish, obj2, path_limiter)
end

#diff_stats(objectish = 'HEAD', obj2 = nil, opts = {}) ⇒ Git::DiffStats

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

Options Hash (opts):

  • :path_limiter (String, Pathname, Array<String, Pathname>)

    Limit stats to specified path(s).



939
940
941
# File 'lib/git/base.rb', line 939

def diff_stats(objectish = 'HEAD', obj2 = nil, opts = {})
  Git::DiffStats.new(self, objectish, obj2, opts[:path_limiter])
end

#dir

returns a reference to the working directory @git.dir.path @git.dir.writeable?



239
240
241
# File 'lib/git/base.rb', line 239

def dir
  @working_directory
end

#each_conflict

iterates over the files which are unmerged



523
524
525
# File 'lib/git/base.rb', line 523

def each_conflict(&) # :yields: file, your_version, their_version
  lib.conflicts(&)
end

#fetch(remote = 'origin', opts = {})

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



485
486
487
488
489
490
491
# File 'lib/git/base.rb', line 485

def fetch(remote = 'origin', opts = {})
  if remote.is_a?(Hash)
    opts = remote
    remote = nil
  end
  lib.fetch(remote, opts)
end

#fsck(objects = [], options = {}) ⇒ Git::FsckResult

Verifies the connectivity and validity of objects in the database

Runs git fsck to check repository integrity and identify dangling, missing, or unreachable objects.

rubocop:disable Style/ArgumentsForwarding

Returns categorized objects flagged by fsck.

Examples:

Check repository integrity

result = git.fsck
result.dangling.each { |obj| puts "#{obj.type}: #{obj.sha}" }

Check with strict mode and suppress dangling output

result = git.fsck(strict: true, dangling: false)

Check if repository has any issues

result = git.fsck
puts "Repository is clean" if result.empty?

List root commits

result = git.fsck(root: true)
result.root.each { |obj| puts obj.sha }

Check specific objects

result = git.fsck('abc1234', 'def5678')

Options Hash (options):

  • :unreachable (Boolean)

    print unreachable objects

  • :strict (Boolean)

    enable strict checking

  • :connectivity_only (Boolean)

    check only connectivity (faster)

  • :root (Boolean)

    report root nodes

  • :tags (Boolean)

    report tags

  • :cache (Boolean)

    consider objects in the index

  • :no_reflogs (Boolean)

    do not consider reflogs

  • :lost_found (Boolean)

    write dangling objects to .git/lost-found (note: this modifies the repository by creating files)

  • :dangling (Boolean, nil)

    print dangling objects (true/false/nil for default)

  • :full (Boolean, nil)

    check objects in alternate pools (true/false/nil for default)

  • :name_objects (Boolean, nil)

    name objects by refs (true/false/nil for default)

  • :references (Boolean, nil)

    check refs database consistency (true/false/nil for default)



703
704
705
# File 'lib/git/base.rb', line 703

def fsck(*objects, **opts)
  lib.fsck(*objects, **opts)
end

#gblob(objectish) ⇒ Git::Object

Returns a Git object.



875
876
877
# File 'lib/git/base.rb', line 875

def gblob(objectish)
  Git::Object.new(self, objectish, 'blob')
end

#gc



653
654
655
# File 'lib/git/base.rb', line 653

def gc
  lib.gc
end

#gcommit(objectish) ⇒ Git::Object

Returns a Git object.



880
881
882
# File 'lib/git/base.rb', line 880

def gcommit(objectish)
  Git::Object.new(self, objectish, 'commit')
end

#grep(string, path_limiter = nil, opts = {}) ⇒ Hash<String, Array>

Run a grep for 'string' on the HEAD of the git repository

Examples:

Limit grep's scope by calling grep() from a specific object:

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

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

Options Hash (opts):

  • :ignore_case (Boolean) — default: false

    ignore case when matching

  • :invert_match (Boolean) — default: false

    select non-matching lines

  • :extended_regexp (Boolean) — default: false

    use extended regular expressions

  • :object (String) — default: HEAD

    the object to search from



384
385
386
# File 'lib/git/base.rb', line 384

def grep(string, path_limiter = nil, opts = {})
  object('HEAD').grep(string, path_limiter, opts)
end

#gtree(objectish) ⇒ Git::Object

Returns a Git object.



885
886
887
# File 'lib/git/base.rb', line 885

def gtree(objectish)
  Git::Object.new(self, objectish, 'tree')
end

#ignored_filesArray<String>

List the files in the worktree that are ignored by git



391
392
393
# File 'lib/git/base.rb', line 391

def ignored_files
  lib.ignored_files
end

#is_branch?(branch) ⇒ Boolean

rubocop:disable Naming/PredicatePrefix



326
327
328
329
330
331
332
# File 'lib/git/base.rb', line 326

def is_branch?(branch) # rubocop:disable Naming/PredicatePrefix
  Git::Deprecation.warn(
    'Git::Base#is_branch? is deprecated and will be removed in a future version. ' \
    'Use Git::Base#branch? instead.'
  )
  branch?(branch)
end

#is_local_branch?(branch) ⇒ Boolean

rubocop:disable Naming/PredicatePrefix



298
299
300
301
302
303
304
# File 'lib/git/base.rb', line 298

def is_local_branch?(branch) # rubocop:disable Naming/PredicatePrefix
  Git::Deprecation.warn(
    'Git::Base#is_local_branch? is deprecated and will be removed in a future version. ' \
    'Use Git::Base#local_branch? instead.'
  )
  local_branch?(branch)
end

#is_remote_branch?(branch) ⇒ Boolean

rubocop:disable Naming/PredicatePrefix



312
313
314
315
316
317
318
# File 'lib/git/base.rb', line 312

def is_remote_branch?(branch) # rubocop:disable Naming/PredicatePrefix
  Git::Deprecation.warn(
    'Git::Base#is_remote_branch? is deprecated and will be removed in a future version. ' \
    'Use Git::Base#remote_branch? instead.'
  )
  remote_branch?(branch)
end

#lib

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



337
338
339
# File 'lib/git/base.rb', line 337

def lib
  @lib ||= Git::Lib.new(self, @logger)
end

#local_branch?(branch) ⇒ Boolean

returns +true+ if the branch exists locally



293
294
295
296
# File 'lib/git/base.rb', line 293

def local_branch?(branch)
  branch_names = branches.local.map(&:name)
  branch_names.include?(branch)
end

#log(count = 30) ⇒ Git::Log

Returns a log with the specified number of commits.



890
891
892
# File 'lib/git/base.rb', line 890

def log(count = 30)
  Git::Log.new(self, count)
end

#ls_files(location = nil)



773
774
775
# File 'lib/git/base.rb', line 773

def ls_files(location = nil)
  lib.ls_files(location)
end

#ls_tree(objectish, opts = {})



811
812
813
# File 'lib/git/base.rb', line 811

def ls_tree(objectish, opts = {})
  lib.ls_tree(objectish, opts)
end

#merge(branch, message = 'merge', opts = {})

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



518
519
520
# File 'lib/git/base.rb', line 518

def merge(branch, message = 'merge', opts = {})
  lib.merge(branch, message, opts)
end

#merge_baseArray<Git::Object::Commit>

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



927
928
929
930
# File 'lib/git/base.rb', line 927

def merge_base(*)
  shas = lib.merge_base(*)
  shas.map { |sha| gcommit(sha) }
end

#object(objectish) ⇒ Git::Object

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



904
905
906
# File 'lib/git/base.rb', line 904

def object(objectish)
  Git::Object.new(self, objectish)
end

#pull(remote = nil, branch = nil, opts = {}) ⇒ Void

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

Examples:

pulls from origin/master

@git.pull

pulls from upstream/master

@git.pull('upstream')

pulls from upstream/develop

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

Options Hash (opts):

  • :allow_unrelated_histories (Boolean) — default: false

    Merges histories of two projects that started their lives independently

Raises:

  • (Git::FailedError)

    if the pull fails

  • (ArgumentError)

    if a branch is given without a remote



546
547
548
# File 'lib/git/base.rb', line 546

def pull(remote = nil, branch = nil, opts = {})
  lib.pull(remote, branch, opts)
end

#push(remote = nil, branch = nil, options = {}) ⇒ Void

Push changes to a remote repository

Raises:

  • (Git::FailedError)

    if the push fails

  • (ArgumentError)

    if a branch is given without a remote



511
512
513
# File 'lib/git/base.rb', line 511

def push(*, **)
  lib.push(*, **)
end

#read_tree(treeish, opts = {})



756
757
758
# File 'lib/git/base.rb', line 756

def read_tree(treeish, opts = {})
  lib.read_tree(treeish, opts)
end

#remote(remote_name = 'origin') ⇒ Git::Remote

Returns a remote of the specified name.



909
910
911
# File 'lib/git/base.rb', line 909

def remote(remote_name = 'origin')
  Git::Remote.new(self, remote_name)
end

#remote_branch?(branch) ⇒ Boolean

returns +true+ if the branch exists remotely



307
308
309
310
# File 'lib/git/base.rb', line 307

def remote_branch?(branch)
  branch_names = branches.remote.map(&:name)
  branch_names.include?(branch)
end

#remote_set_branches(name, *branches, add: false) ⇒ nil

Configures which branches are fetched for a remote

Uses git remote set-branches to set or append fetch refspecs. When the add: option is not given, the --add option is not passed to the git command

the underlying git command fails

Examples:

Replace fetched branches with a single glob pattern

git = Git.open('/path/to/repo')
# Only fetch branches matching "feature/*" from origin
git.remote_set_branches('origin', 'feature/*')

Append a glob pattern to existing fetched branches

git = Git.open('/path/to/repo')
# Keep existing fetch refspecs and add all release branches
git.remote_set_branches('origin', 'release/*', add: true)

Configure multiple explicit branches

git = Git.open('/path/to/repo')
git.remote_set_branches('origin', 'main', 'development', 'hotfix')

Raises:

  • (ArgumentError)

    if no branches are provided @raise [Git::FailedError] if



594
595
596
597
598
599
600
601
# File 'lib/git/base.rb', line 594

def remote_set_branches(name, *branches, add: false)
  branch_list = branches.flatten
  raise ArgumentError, 'branches are required' if branch_list.empty?

  lib.remote_set_branches(name, branch_list, add: add)

  nil
end

#remotes

returns an array of Git:Remote objects



551
552
553
# File 'lib/git/base.rb', line 551

def remotes
  lib.remotes.map { |r| Git::Remote.new(self, r) }
end

#remove_remote(name)

removes a remote from this repository

@git.remove_remote('scott_git')



606
607
608
# File 'lib/git/base.rb', line 606

def remove_remote(name)
  lib.remote_remove(name)
end

#repack

repacks the repository



649
650
651
# File 'lib/git/base.rb', line 649

def repack
  lib.repack
end

#repo

returns reference to the git repository directory @git.dir.path



248
249
250
# File 'lib/git/base.rb', line 248

def repo
  @repository
end

#repo_size

returns the repository size in bytes



253
254
255
256
257
258
259
260
# File 'lib/git/base.rb', line 253

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 = {})

resets the working directory to the provided commitish



403
404
405
# File 'lib/git/base.rb', line 403

def reset(commitish = nil, opts = {})
  lib.reset(commitish, opts)
end

#reset_hard(commitish = nil, opts = {})

resets the working directory to the commitish with '--hard'



408
409
410
411
# File 'lib/git/base.rb', line 408

def reset_hard(commitish = nil, opts = {})
  opts = { hard: true }.merge(opts)
  lib.reset(commitish, opts)
end

#rev_parse(objectish) Also known as: revparse

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

Examples:

git.rev_parse("HEAD^^")
git.rev_parse('v2.4^{tree}')
git.rev_parse('v2.4:/doc/index.html')


804
805
806
# File 'lib/git/base.rb', line 804

def rev_parse(objectish)
  lib.rev_parse(objectish)
end

#revert(commitish = nil, opts = {})

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

options: :no_edit



449
450
451
# File 'lib/git/base.rb', line 449

def revert(commitish = nil, opts = {})
  lib.revert(commitish, opts)
end

#rm(path = '.', opts = {}) Also known as: remove

removes file(s) from the git repository



396
397
398
# File 'lib/git/base.rb', line 396

def rm(path = '.', opts = {})
  lib.rm(path, opts)
end

#set_index(index_file, check = nil, must_exist: nil)



262
263
264
265
266
267
268
269
270
271
272
273
274
275
# File 'lib/git/base.rb', line 262

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)

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')



560
561
562
563
564
# File 'lib/git/base.rb', line 560

def set_remote_url(name, url)
  url = url.repo.to_s 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)



277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/git/base.rb', line 277

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) ⇒ String

Shows objects



723
724
725
# File 'lib/git/base.rb', line 723

def show(objectish = nil, path = nil)
  lib.show(objectish, path)
end

#statusGit::Status

Returns a status object.



914
915
916
# File 'lib/git/base.rb', line 914

def status
  Git::Status.new(self)
end

#tag(tag_name) ⇒ Git::Object::Tag

Returns a tag object.



919
920
921
# File 'lib/git/base.rb', line 919

def tag(tag_name)
  Git::Object::Tag.new(self, tag_name)
end

#tags

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



611
612
613
# File 'lib/git/base.rb', line 611

def tags
  lib.tags.map { |r| tag(r) }
end

#update_ref(branch, commit)



769
770
771
# File 'lib/git/base.rb', line 769

def update_ref(branch, commit)
  branch(branch).update_ref(commit)
end

#with_index(new_index)

LOWER LEVEL INDEX OPERATIONS ##



729
730
731
732
733
734
735
# File 'lib/git/base.rb', line 729

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



737
738
739
740
741
742
743
744
745
746
747
748
749
750
# File 'lib/git/base.rb', line 737

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



788
789
790
791
792
793
794
795
# File 'lib/git/base.rb', line 788

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)

:yields: the Git::WorkingDirectory



777
778
779
780
781
782
783
784
785
786
# File 'lib/git/base.rb', line 777

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)

returns a Git::Worktree object for dir, commitish



854
855
856
# File 'lib/git/base.rb', line 854

def worktree(dir, commitish = nil)
  Git::Worktree.new(self, dir, commitish)
end

#worktrees

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



860
861
862
# File 'lib/git/base.rb', line 860

def worktrees
  Git::Worktrees.new(self)
end

#write_and_commit_tree(opts = {})



764
765
766
767
# File 'lib/git/base.rb', line 764

def write_and_commit_tree(opts = {})
  tree = write_tree
  commit_tree(tree, opts)
end

#write_tree



760
761
762
# File 'lib/git/base.rb', line 760

def write_tree
  lib.write_tree
end