Class: Git::Lib Private

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

Overview

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

Internal git operations

Defined Under Namespace

Classes: HeadState

Constant Summary collapse

CAT_FILE_HEADER_LINE =

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

/\A(?<key>\w+) (?<value>.*)\z/
LS_TREE_ALLOWED_OPTS =

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

Allowed option keys for #ls_tree

%i[recursive path].freeze
GREP_ALLOWED_OPTS =

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

%i[ignore_case i invert_match v extended_regexp E object path_limiter].freeze
FULL_LOG_ALLOWED_OPTS =

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

Allowed option keys for #full_log_commits

%i[count all cherry since until grep author between object path_limiter skip merges].freeze
DIFF_FULL_ALLOWED_OPTS =

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

Allowed option keys for #diff_full

%i[path_limiter].freeze
DIFF_STATS_ALLOWED_OPTS =

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

Allowed option keys for #diff_stats

%i[path_limiter].freeze
DIFF_PATH_STATUS_ALLOWED_OPTS =

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

Allowed option keys for #diff_path_status

%i[path_limiter path].freeze
CONFIG_SET_ALLOWED_OPTS =

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

WRITE COMMANDS ##

%i[file].freeze
REVERT_ALLOWED_OPTS =

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

%i[no_edit].freeze
PUSH_ALLOWED_OPTS =

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

%i[mirror delete force f push_option all tags].freeze
PULL_ALLOWED_OPTS =

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

%i[allow_unrelated_histories].freeze
READ_TREE_ALLOWED_OPTS =

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

rubocop:enable Style/ArgumentsForwarding

%i[prefix].freeze
COMMIT_TREE_ALLOWED_OPTS =

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

%i[p parent parents m message].freeze
ARCHIVE_ALLOWED_OPTS =

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

%i[prefix remote path format add_gzip].freeze
COMMAND_CAPTURING_ARG_DEFAULTS =

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

{
  in: nil,
  out: nil,
  err: nil,
  normalize: true,
  chomp: true,
  merge: false,
  chdir: nil,
  timeout: nil, # Don't set to Git.config.timeout here since it is mutable
  env: {},
  raise_on_failure: true
}.freeze
STATIC_GLOBAL_OPTS =

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

%w[
  -c core.quotePath=true
  -c core.editor=false
  -c color.ui=false
  -c color.advice=false
  -c color.diff=false
  -c color.grep=false
  -c color.push=false
  -c color.remote=false
  -c color.showBranch=false
  -c color.status=false
  -c color.transport=false
].freeze
COMMAND_STREAMING_ARG_DEFAULTS =

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

{
  in: nil,
  out: nil,
  err: nil,
  chdir: nil,
  timeout: nil,
  env: {},
  raise_on_failure: true
}.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(base, logger) ⇒ Lib #initialize(base, logger) ⇒ Lib

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.

Create a new Git::Lib object

Overloads:

  • #initialize(base, logger) ⇒ Lib

    Parameters:

    • base (Hash)

      the hash containing paths to the Git working copy, the Git repository directory, and the Git index file.

    • logger (Logger)

    Options Hash (base):

    • :working_directory (Pathname)
    • :repository (Pathname)
    • :index (Pathname)
  • #initialize(base, logger) ⇒ Lib

    Parameters:

    • base (#dir, #repo, #index)

      an object with methods to get the Git worktree (#dir), the Git repository directory (#repo), and the Git index file (#index).

    • logger (Logger)


76
77
78
79
80
81
82
83
84
85
86
# File 'lib/git/lib.rb', line 76

def initialize(base = nil, logger = nil)
  @logger = logger || Logger.new(nil)
  @git_ssh = :use_global_config

  case base
  when Git::Base
    initialize_from_base(base)
  when Hash
    initialize_from_hash(base)
  end
end

Instance Attribute Details

#git_dirPathname (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.

The path to the Git repository directory. The default is "#{git_work_dir}/.git".

Returns:

  • (Pathname)

    the Git repository directory.

See Also:

  • repository](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefrepositoryarepository)


45
46
47
# File 'lib/git/lib.rb', line 45

def git_dir
  @git_dir
end

#git_index_filePathname (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.

The Git index file used to stage changes (using git add) before they are committed.

Returns:

  • (Pathname)

    the Git index file

See Also:

  • index file](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefindexaindex)


54
55
56
# File 'lib/git/lib.rb', line 54

def git_index_file
  @git_index_file
end

#git_work_dirPathname (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.

The path to the Git working copy. The default is '"./.git"'.

Returns:

  • (Pathname)

    the path to the Git working copy.

See Also:

  • working tree](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefworkingtreeaworkingtree)


36
37
38
# File 'lib/git/lib.rb', line 36

def git_work_dir
  @git_work_dir
end

Class Method Details

.cached_git_version(binary_path, &block)

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.

Class-level cache for git versions, keyed by binary path

Thread-safe for JRuby/TruffleRuby where true parallelism exists.



1902
1903
1904
1905
1906
# File 'lib/git/lib.rb', line 1902

def self.cached_git_version(binary_path, &block)
  @git_version_cache_mutex.synchronize do
    @git_version_cache[binary_path] ||= block.call
  end
end

.clear_git_version_cache

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.

Clear the git version cache (primarily for testing)



1912
1913
1914
1915
1916
# File 'lib/git/lib.rb', line 1912

def self.clear_git_version_cache
  @git_version_cache_mutex.synchronize do
    @git_version_cache.clear
  end
end

.warn_if_old_command(_lib)

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.

Deprecated.

Version validation is now handled automatically by Commands::Base#validate_version!, which raises VersionError on failure. Callers wanting the old warn-and-continue behavior must implement it themselves using: Git.git_version >= Git::MINIMUM_GIT_VERSION.



1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
# File 'lib/git/lib.rb', line 1985

def self.warn_if_old_command(_lib) # rubocop:disable Metrics/MethodLength, Naming/PredicateMethod
  Git::Deprecation.warn(
    'Git::Lib.warn_if_old_command is deprecated and will be removed in 6.0. ' \
    'Version validation is now handled automatically by Git::Commands::Base#validate_version!, ' \
    'which RAISES Git::VersionError on failure (the old method only printed a warning ' \
    'once per process and continued). Callers wanting the old warn-and-continue behavior ' \
    'must implement it themselves using: Git.git_version >= Git::MINIMUM_GIT_VERSION.'
  )

  return true if @version_checked

  @version_checked = true
  git_version = Git.git_version
  unless git_version >= Git::MINIMUM_GIT_VERSION
    warn "The git gem requires git #{Git::MINIMUM_GIT_VERSION} or later, " \
         "but only found #{git_version}. You should probably upgrade."
  end
  true
end

Instance Method Details

#add(paths = '.', options = {}) ⇒ String

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.

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)

Parameters:

  • paths (String, Array<String>) (defaults to: '.')

    files to be added to the repository (relative to the worktree root)

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

Options Hash (options):

  • :all (Boolean, nil) — default: nil

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

  • :force (Boolean, nil) — default: nil

    allow adding otherwise ignored files

Returns:

  • (String)

    the command output (typically empty on success)



1172
1173
1174
# File 'lib/git/lib.rb', line 1172

def add(paths = '.', options = {})
  Git::Commands::Add.new(self).call(*Array(paths), **options).stdout
end

#apply(patch_file)

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.



1248
1249
1250
# File 'lib/git/lib.rb', line 1248

def apply(patch_file)
  Git::Commands::Apply.new(self).call(*[patch_file].compact, chdir: @git_work_dir).stdout
end

#apply_mail(patch_file)

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.



1252
1253
1254
# File 'lib/git/lib.rb', line 1252

def apply_mail(patch_file)
  Git::Commands::Am::Apply.new(self).call(*[patch_file].compact, chdir: @git_work_dir).stdout
end

#archive(sha, file = nil, opts = {}) ⇒ String

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.

Creates an archive of the given tree-ish and writes it to a file

Delegates to Commands::Archive for CLI execution. Format coercion (tgztar + gzip), temp file management, and gzip post-processing remain in this adapter.

Parameters:

  • sha (String)

    tree-ish to archive (commit, tag, branch, or tree SHA)

  • file (String, nil) (defaults to: nil)

    destination file path; a unique temp file is created and returned if nil

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

    archive options

Options Hash (opts):

  • :prefix (String)

    prefix to prepend to each filename in the archive

  • :remote (String)

    URL of a remote repository to archive from

  • :path (String)

    limit the archive to a path within the tree

  • :format (String)

    archive format — 'tar', 'tgz', or 'zip' (default: 'zip')

  • :add_gzip (Boolean, nil) — default: nil

    wrap the archive in gzip compression

Returns:

  • (String)

    the path to the written archive file

Raises:

See Also:



1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
# File 'lib/git/lib.rb', line 1858

def archive(sha, file = nil, opts = {})
  assert_valid_opts(opts, ARCHIVE_ALLOWED_OPTS)
  file ||= temp_file_name
  format, gzip = parse_archive_format_options(opts)

  command_opts = opts.slice(:prefix, :remote).merge(format: format)
  path_args = opts[:path] ? [opts[:path]] : []

  File.open(file, 'wb') do |f|
    Git::Commands::Archive.new(self).call(sha, *path_args, **command_opts, out: f)
  end
  apply_gzip(file) if gzip

  file
end

#assert_args_are_not_options(arg_name, *args)

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.

This method returns an undefined value.

Validate that the given arguments cannot be mistaken for a command-line option

Parameters:

  • arg_name (String)

    the name of the arguments to mention in the error message

  • args (Array<String, nil>)

    the arguments to validate

Raises:

  • (ArgumentError)

    if any of the parameters are a string starting with a hyphen



827
828
829
830
831
832
# File 'lib/git/lib.rb', line 827

def assert_args_are_not_options(arg_name, *args)
  invalid_args = args.select { |arg| arg&.start_with?('-') }
  return unless invalid_args.any?

  raise ArgumentError, "Invalid #{arg_name}: '#{invalid_args.join("', '")}'"
end

#assert_valid_opts(opts, allowed)

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.

Validate that opts contains only allowed keys

Parameters:

  • opts (Hash)

    options hash to validate

  • allowed (Array<Symbol>)

    allowed option keys

Raises:

  • (ArgumentError)

    if unknown keys are present



906
907
908
909
# File 'lib/git/lib.rb', line 906

def assert_valid_opts(opts, allowed)
  unknown = opts.keys - allowed
  raise ArgumentError, "Unknown options: #{unknown.join(', ')}" if unknown.any?
end

#branch_contains(commit, branch_name = '')

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.



792
793
794
795
796
# File 'lib/git/lib.rb', line 792

def branch_contains(commit, branch_name = '')
  branch_name = branch_name.to_s
  pattern = branch_name.empty? ? nil : branch_name
  Git::Commands::Branch::List.new(self).call(*[pattern].compact, contains: commit, no_color: true).stdout
end

#branch_current

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.



786
787
788
789
790
# File 'lib/git/lib.rb', line 786

def branch_current
  result = Git::Commands::Branch::ShowCurrent.new(self).call
  name = result.stdout.strip
  name.empty? ? 'HEAD' : name
end

#branch_delete(*branches, **options) ⇒ String

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.

Delete one or more branches

Parameters:

Options Hash (**options):

  • :force (Boolean, nil) — default: nil

    allow deleting unmerged branches (defaults to true when not given)

  • :remotes (Boolean, nil) — default: nil

    delete remote-tracking branches

Returns:

  • (String)

    newline-separated list of "Deleted branch (was )." messages

Raises:



1376
1377
1378
1379
1380
1381
1382
1383
# File 'lib/git/lib.rb', line 1376

def branch_delete(*branches, **options)
  options = { force: true }.merge(options)
  result = Git::Commands::Branch::Delete.new(self).call(*branches, **options)

  raise Git::Error, result.stderr.strip unless result.status.success?

  result.stdout.strip
end

#branch_new(branch, start_point = nil, options = {}) ⇒ nil

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.

Create a new branch

Parameters:

  • branch (String)

    the name of the branch to create

  • start_point (String, nil) (defaults to: nil)

    the commit, branch, or tag to start the new branch from

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

    command options (see Commands::Branch::Create#call)

Returns:

  • (nil)


1360
1361
1362
1363
# File 'lib/git/lib.rb', line 1360

def branch_new(branch, start_point = nil, options = {})
  Git::Commands::Branch::Create.new(self).call(branch, start_point, **options)
  nil
end

#branches_all

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.



704
705
706
707
# File 'lib/git/lib.rb', line 704

def branches_all
  result = Git::Commands::Branch::List.new(self).call(all: true, format: Git::Parsers::Branch::FORMAT_STRING)
  Git::Parsers::Branch.parse_list(result.stdout)
end

#cat_file_commit(object) ⇒ Hash Also known as: commit_data

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.

Return a hash of commit data

The returned commit data has the following keys:

  • tree [String]
  • parent [Array]
  • author [String] the author name, email, and commit timestamp
  • committer [String] the committer name, email, and merge timestamp
  • message [String] the commit message
  • gpgsig [String] the public signing key of the commit (if signed)

Parameters:

  • object (String)

    the object to get the type

Returns:

  • (Hash)

    commit data

Raises:

  • (ArgumentError)

    if object is a string starting with a hyphen

See Also:



453
454
455
456
457
458
# File 'lib/git/lib.rb', line 453

def cat_file_commit(object)
  assert_args_are_not_options('object', object)

  cdata = Git::Commands::CatFile::Raw.new(self).call('commit', object).stdout.split("\n")
  process_commit_data(cdata, object)
end

#cat_file_contents(object) ⇒ String #cat_file_contents(object) {|file| ... } ⇒ Object Also known as: object_contents

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 raw content of a git object, or streams it into a tempfile

Without a block, the full content is buffered in memory and returned as a String. With a block, git output is streamed directly to disk without memory buffering — safe for large blobs.

Overloads:

  • #cat_file_contents(object) ⇒ String

    Returns the object's raw content as a string.

    Examples:

    Get the contents of a blob

    lib.cat_file_contents('HEAD:README.md') # => "This is a README file\n"

    Parameters:

    • object (String)

      the object name (SHA, ref, HEAD, treeish path, etc.)

    Returns:

    • (String)

      the raw content of the object

    Raises:

    • (ArgumentError)

      if object starts with a hyphen

    • (Git::FailedError)

      if the object does not exist or the command fails

  • #cat_file_contents(object) {|file| ... } ⇒ Object

    Streams the object's raw content to a temporary file and yields it.

    Git output is written directly to a file on disk without being buffered in memory first, then the file is rewound and yielded to the block. The return value is whatever the block returns.

    Examples:

    Read a large blob without buffering it in memory

    lib.cat_file_contents('HEAD:large_file.bin') { |f| process(f) }

    Parameters:

    • object (String)

      the object name (SHA, ref, HEAD, treeish path, etc.)

    Yields:

    • (file)

      the temporary file containing the streamed content, positioned at the start

    Yield Parameters:

    • file (File)

      readable IO object positioned at the beginning of the content

    Yield Returns:

    • (Object)

      the value to return from this method

    Returns:

    • (Object)

      the value returned by the block

    Raises:

    • (ArgumentError)

      if object starts with a hyphen

    • (Git::FailedError)

      if the object does not exist or the command fails

See Also:



382
383
384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/git/lib.rb', line 382

def cat_file_contents(object)
  assert_args_are_not_options('object', object)

  return Git::Commands::CatFile::Raw.new(self).call(object, p: true).stdout unless block_given?

  # Stream git output directly to a tempfile to avoid buffering large
  # object content in memory when a block is given.
  Tempfile.create do |file|
    file.binmode
    Git::Commands::CatFile::Raw.new(self).call(object, p: true, out: file)
    file.rewind
    yield file
  end
end

#cat_file_object_meta(object)

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.



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

def cat_file_object_meta(object)
  stdout = Git::Commands::CatFile::Batch.new(self).call(object, batch_check: true).stdout
  parse_cat_file_meta(stdout, object)
end

#cat_file_size(object) ⇒ Integer Also known as: object_size

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.

Get the size for the given object

Parameters:

  • object (String)

    the object to get the size of

Returns:

  • (Integer)

    the object size in bytes

Raises:

  • (ArgumentError)

    if object is a string starting with a hyphen

See Also:



427
428
429
430
431
# File 'lib/git/lib.rb', line 427

def cat_file_size(object)
  assert_args_are_not_options('object', object)

  cat_file_object_meta(object)[:size]
end

#cat_file_tag(object) ⇒ Hash Also known as: tag_data

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.

Return a hash of annotated tag data

Does not work with lightweight tags. List all annotated tags in your repository with the following command:

git for-each-ref --format='%(refname:strip=2)' refs/tags | \
  while read tag; do git cat-file tag $tag >/dev/null 2>&1 && echo $tag; done

The returned commit data has the following keys:

  • object [String] the sha of the tag object
  • type [String]
  • tag [String] tag name
  • tagger [String] the name and email of the user who created the tag and the timestamp of when the tag was created
  • message [String] the tag message

Parameters:

  • object (String)

    the tag to retrieve

Returns:

  • (Hash)

    tag data

    Example tag data returned:

    {
      "name" => "annotated_tag",
      "object" => "46abbf07e3c564c723c7c039a43ab3a39e5d02dd",
      "type" => "commit",
      "tag" => "annotated_tag",
      "tagger" => "Scott Chacon <schacon@gmail.com> 1724799270 -0700",
      "message" => "Creating an annotated tag\n"
    }
    

Raises:

  • (ArgumentError)

    if object is a string starting with a hyphen

See Also:



542
543
544
545
546
547
# File 'lib/git/lib.rb', line 542

def cat_file_tag(object)
  assert_args_are_not_options('object', object)

  tdata = Git::Commands::CatFile::Raw.new(self).call('tag', object).stdout.split("\n")
  process_tag_data(tdata, object)
end

#cat_file_type(object) ⇒ String Also known as: object_type

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.

Get the type for the given object

Parameters:

  • object (String)

    the object to get the type

Returns:

  • (String)

    the object type

Raises:

  • (ArgumentError)

    if object is a string starting with a hyphen

See Also:



409
410
411
412
413
# File 'lib/git/lib.rb', line 409

def cat_file_type(object)
  assert_args_are_not_options('object', object)

  cat_file_object_meta(object)[:type]
end

#change_head_branch(branch_name)

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.



700
701
702
# File 'lib/git/lib.rb', line 700

def change_head_branch(branch_name)
  Git::Commands::SymbolicRef::Update.new(self).call('HEAD', "refs/heads/#{branch_name}")
end

#checkout(branch = nil, opts = {}) ⇒ String

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.

Runs checkout command to checkout or create branch

accepts options: :new_branch / :b - create a new branch with the given name (true = legacy, string = new) :force / :f - proceed even with uncommitted changes :start_point - start the new branch at this commit (used with :new_branch in legacy mode)

Parameters:

  • branch (String) (defaults to: nil)

    the branch to checkout, or nil

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

    options for the checkout command

Returns:

  • (String)

    the command output



1396
1397
1398
1399
1400
1401
1402
1403
1404
# File 'lib/git/lib.rb', line 1396

def checkout(branch = nil, opts = {})
  if branch.is_a?(Hash) && opts.empty?
    opts = branch
    branch = nil
  end

  target, translated_opts = translate_checkout_opts(branch, opts)
  Git::Commands::Checkout::Branch.new(self).call(target, **translated_opts).stdout
end

#checkout_file(version, file) ⇒ String

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.

Checkout a specific version of a file

Parameters:

  • version (String)

    the tree-ish (commit, branch, tag) to restore from

  • file (String)

    the file path to restore

Returns:

  • (String)

    the command output



1426
1427
1428
# File 'lib/git/lib.rb', line 1426

def checkout_file(version, file)
  Git::Commands::Checkout::Files.new(self).call(version, pathspec: [file]).stdout
end

#checkout_index(opts = {})

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.



1820
1821
1822
1823
1824
# File 'lib/git/lib.rb', line 1820

def checkout_index(opts = {})
  paths = normalize_pathspecs(opts[:path_limiter], 'path_limiter')
  keyword_opts = opts.except(:path_limiter)
  Git::Commands::CheckoutIndex.new(self).call(*paths.to_a, **keyword_opts)
end

#clean(opts = {}) ⇒ String

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 command output.

Returns:

  • (String)

    the command output



1235
1236
1237
1238
# File 'lib/git/lib.rb', line 1235

def clean(opts = {})
  opts = migrate_clean_legacy_options(opts)
  Git::Commands::Clean.new(self).call(**opts).stdout
end

#clone(repository_url, directory = nil, opts = {}) ⇒ Hash

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.

TODO:

make this work with SSH password or auth_key

Clones a repository into a newly created directory

Parameters:

  • repository_url (String)

    the URL of the repository to clone

  • directory (String, nil) (defaults to: nil)

    the directory to clone into

    If nil, the repository is cloned into a directory with the same name as the repository.

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

    the options for this command

Options Hash (opts):

  • :bare (Boolean, nil) — default: nil

    if true, clone as a bare repository

  • :branch (String, nil) — default: nil

    the branch to checkout

  • :config (String, Array<String>, nil) — default: nil

    one or more configuration options to set

  • :depth (Integer, nil) — default: nil

    the number of commits back to pull

  • :filter (String, nil) — default: nil

    specify partial clone

  • :git_ssh (String, nil) — default: nil

    SSH command or binary to use for git over SSH

  • :log (Logger, nil) — default: nil

    Logger instance to use for git operations

  • :mirror (Boolean, nil) — default: nil

    set up a mirror of the source repository

  • :origin (String, nil) — default: nil

    the name of the remote

  • :chdir (String, nil) — default: nil

    run git clone from this directory

    When given, directory (or the repository basename when directory is nil) is resolved relative to :chdir, just as if you had cd'd into it before running git clone. The returned path is the join of :chdir and the cloned directory path.

  • :path (String)

    deprecated: use :chdir instead.

  • :remote (String)

    deprecated: use :origin instead.

  • :recurse_submodules (Boolean, String, Array<String>, nil) — default: nil

    initialize submodules after cloning; pass true for all submodules, or a pathspec string/array for a subset

  • :recursive (Boolean, String, Array<String>, nil) — default: nil

    deprecated: use :recurse_submodules instead

  • :timeout (Numeric, nil) — default: nil

    the number of seconds to wait for the command to complete

    See #command for more information about :timeout

Returns:

  • (Hash)

    the options to pass to Base.new



167
168
169
170
171
172
173
174
175
176
177
# File 'lib/git/lib.rb', line 167

def clone(repository_url, directory = nil, opts = {})
  opts = opts.dup
  deprecate_clone_options!(opts)
  chdir = opts.delete(:chdir)
  execution_opts = extract_clone_execution_context_opts(opts)
  opts[:chdir] = chdir if chdir
  command_line_result = Git::Commands::Clone.new(self).call(repository_url, directory, **opts)
  result = build_clone_result(command_line_result, execution_opts)
  prefix_clone_result_paths!(result, chdir)
  result
end

#command_capturing(*args, **options_hash) ⇒ Git::CommandLineResult

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.

Note:

Individual command classes (under Commands) can selectively expose :timeout and :env to their callers by declaring them as execution options in their Arguments DSL definition and forwarding them to this method. See Commands::Clone#call for an example of a command that exposes :timeout.

Runs a git command and returns the result

By default, raises FailedError if the command exits with a non-zero status. Pass raise_on_failure: false to suppress this behavior.

Runs a git command and returns the result

Args should exclude the 'git' command itself and global options. Remember to splat the arguments if given as an array.

Examples:

Run git log

result = command_capturing('log', '--pretty=oneline')
result.stdout #=> "abc123 First commit\ndef456 Second commit\n"

Using an array of arguments

args = ['log', '--pretty=oneline']
result = command_capturing(*args)

Suppress raising on failure

result = command_capturing('show', 'nonexistent', raise_on_failure: false)
result.status.success? #=> false

Parameters:

  • args (Array<String>)

    the command and its arguments

  • options_hash (Hash)

    the options to pass to the command

Parameters:

  • options_hash (Hash)

    a customizable set of options

Options Hash (**options_hash):

  • :in (IO, nil)

    the IO object to use as stdin for the command, or nil to inherit the parent process stdin. Must be a real IO object with a file descriptor.

  • :out (IO, String, #write, nil)

    the destination for captured stdout

  • :err (IO, String, #write, nil)

    the destination for captured stderr

  • :normalize (Boolean, nil) — default: true

    normalize the output encoding to UTF-8

  • :chomp (Boolean, nil) — default: true

    remove trailing newlines from the output

  • :merge (Boolean, nil) — default: false

    merge stdout and stderr into a single output

  • :chdir (String, nil)

    the directory to run the command in

  • :env (Hash)

    additional environment variable overrides for this command

  • :raise_on_failure (Boolean, nil) — default: true

    whether to raise on non-zero exit

  • :timeout (Numeric, nil)

    the maximum seconds to wait for the command to complete

    If timeout is nil, the global timeout from Config is used.

    If timeout is zero, the timeout will not be enforced.

    If the command times out, it is killed via a SIGKILL signal and Git::TimeoutError is raised.

    If the command does not respond to SIGKILL, it will hang this method.

Returns:

Raises:

  • (ArgumentError)

    if an unknown option is passed

  • (Git::FailedError)

    if the command failed (when raise_on_failure is true)

  • (Git::SignaledError)

    if the command was signaled

  • (Git::TimeoutError)

    if the command times out

  • (Git::ProcessIOError)

    if an exception was raised while collecting subprocess output

    The exception's result attribute is a CommandLineResult which will contain the result of the command including the exit status, stdout, and stderr.

See Also:



2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
# File 'lib/git/lib.rb', line 2114

def command_capturing(*, **options_hash)
  options_hash = COMMAND_CAPTURING_ARG_DEFAULTS.merge(options_hash)
  options_hash[:timeout] ||= Git.config.timeout

  extra_options = options_hash.keys - COMMAND_CAPTURING_ARG_DEFAULTS.keys
  raise ArgumentError, "Unknown options: #{extra_options.join(', ')}" if extra_options.any?

  env_overrides = options_hash.delete(:env)
  raise_on_failure = options_hash.delete(:raise_on_failure)
  command_line_capturing.run(*, raise_on_failure: raise_on_failure, env: env_overrides, **options_hash)
end

#command_streaming(*args, **options_hash) ⇒ Git::CommandLineResult

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.

Runs a git command using the streaming (non-capturing) execution path

Unlike #command_capturing, stdout is NOT buffered in memory. It is written only to the IO object provided via the out: option. Stderr is captured internally via a StringIO for error diagnostics.

Use this entry point when you want to stream large output (e.g. blob content from cat-file) without creating memory pressure.

Parameters:

  • args (Array<String>)

    the git command and its arguments

  • options_hash (Hash)

    the options to pass to the command

Parameters:

  • options_hash (Hash)

    a customizable set of options

Options Hash (**options_hash):

  • :in (IO, nil)

    stdin IO object

  • :out (#write, nil)

    destination for streamed stdout

  • :err (#write, nil)

    an optional additional destination to receive stderr output in real time. Stderr is always captured internally; when err: is supplied, writes are teed to both the internal buffer and this destination. result.stderr always reflects the internal capture.

  • :chdir (String, nil)

    the directory to run the command in

  • :env (Hash)

    additional environment variable overrides for this command

  • :raise_on_failure (Boolean, nil) — default: true

    whether to raise on non-zero exit

  • :timeout (Numeric, nil)

    the maximum seconds to wait for the command

    If nil, the global timeout from Config is used.

Returns:

  • (Git::CommandLineResult)

    the result of the command

    result.stdout will always be '' — stdout was streamed to out:. result.stderr contains any stderr output captured for diagnostics.

Raises:

See Also:



2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
# File 'lib/git/lib.rb', line 2188

def command_streaming(*, **options_hash)
  options_hash = COMMAND_STREAMING_ARG_DEFAULTS.merge(options_hash)
  options_hash[:timeout] ||= Git.config.timeout

  extra_options = options_hash.keys - COMMAND_STREAMING_ARG_DEFAULTS.keys
  raise ArgumentError, "Unknown options: #{extra_options.join(', ')}" if extra_options.any?

  env_overrides = options_hash.delete(:env)
  raise_on_failure = options_hash.delete(:raise_on_failure)
  command_line_streaming.run(*, raise_on_failure: raise_on_failure, env: env_overrides, **options_hash)
end

#commit(message, opts = {})

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.

Takes the commit message with the options and executes the commit command

accepts options: :amend :all :allow_empty :author :date :no_verify :allow_empty_message :gpg_sign (accepts true or a gpg key ID as a String) :no_gpg_sign (conflicts with :gpg_sign)

Parameters:

  • message (String)

    the commit message to be used

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

    the commit options to be used



1221
1222
1223
1224
1225
# File 'lib/git/lib.rb', line 1221

def commit(message, opts = {})
  opts = opts.merge(message: message) if message
  deprecate_commit_add_all_option!(opts)
  Git::Commands::Commit.new(self).call(no_edit: true, **opts).stdout
end

#commit_tree(tree, opts = {})

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.



1810
1811
1812
1813
1814
# File 'lib/git/lib.rb', line 1810

def commit_tree(tree, opts = {})
  assert_valid_opts(opts, COMMIT_TREE_ALLOWED_OPTS)
  actual_opts = normalize_commit_tree_opts(opts, tree)
  Git::Commands::CommitTree.new(self).call(tree, **actual_opts).stdout
end

#compare_version_to(*other_version) ⇒ Integer

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.

Deprecated.

Use Git.git_version with Version comparison operators instead, e.g. Git.git_version <=> Git::Version.new(2, 41, 0)

Returns current_command_version <=> other_version

Examples:

lib.compare_version_to(2, 41, 0) #=> 1
lib.compare_version_to(2, 42, 0) #=> 0
lib.compare_version_to(2, 43, 0) #=> -1

Parameters:

  • other_version (Array<Integer>)

    the other version to compare to

Returns:

  • (Integer)

    -1 if this version is less than other_version, 0 if equal, or 1 if greater than



1945
1946
1947
1948
1949
1950
1951
1952
# File 'lib/git/lib.rb', line 1945

def compare_version_to(*other_version)
  Git::Deprecation.warn(
    'Git::Lib#compare_version_to is deprecated and will be removed in 6.0. ' \
    'Use Git.git_version with Git::Version comparison operators instead, ' \
    'e.g. Git.git_version <=> Git::Version.new(2, 41, 0)'
  )
  git_version.to_a <=> other_version
end

#config_get(name)

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.

Raises:



1099
1100
1101
1102
1103
1104
# File 'lib/git/lib.rb', line 1099

def config_get(name)
  result = Git::Commands::ConfigOptionSyntax::Get.new(self).call(name)
  raise Git::FailedError, result if result.status.exitstatus != 0

  result.stdout
end

#config_list

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.



1113
1114
1115
# File 'lib/git/lib.rb', line 1113

def config_list
  parse_config_list Git::Commands::ConfigOptionSyntax::List.new(self).call.stdout.split("\n")
end

#config_remote(name)

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.



1091
1092
1093
1094
1095
1096
1097
# File 'lib/git/lib.rb', line 1091

def config_remote(name)
  hsh = {}
  config_list.each do |key, value|
    hsh[key.gsub("remote.#{name}.", '')] = value if /remote.#{name}/.match(key)
  end
  hsh
end

#config_set(name, value, options = {})

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.



1148
1149
1150
1151
# File 'lib/git/lib.rb', line 1148

def config_set(name, value, options = {})
  assert_valid_opts(options, CONFIG_SET_ALLOWED_OPTS)
  Git::Commands::ConfigOptionSyntax::Set.new(self).call(name, value, **options.slice(*CONFIG_SET_ALLOWED_OPTS))
end

#conflicts

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.

:yields: file, your, their



1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
# File 'lib/git/lib.rb', line 1500

def conflicts # :yields: file, your, their
  unmerged.each do |file_path|
    Tempfile.create(['YOUR-', File.basename(file_path)]) do |your_file|
      write_staged_content(file_path, 2, your_file).flush

      Tempfile.create(['THEIR-', File.basename(file_path)]) do |their_file|
        write_staged_content(file_path, 3, their_file).flush
        yield(file_path, your_file.path, their_file.path)
      end
    end
  end
end

#current_branch_stateHeadState

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.

The current branch state which is the state of HEAD

Returns:

  • (HeadState)

    the state and name of the current branch



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

def current_branch_state
  branch_name = Git::Commands::Branch::ShowCurrent.new(self).call.stdout
  return HeadState.new(:detached, 'HEAD') if branch_name.empty?

  state = get_branch_state(branch_name)
  HeadState.new(state, branch_name)
end

#current_command_version

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.

Deprecated.

Use Git.git_version instead, which returns a Version (not an Array). For the legacy array shape, call: Git.git_version.to_a

Returns the current version of git, as an Array



1923
1924
1925
1926
1927
1928
1929
1930
# File 'lib/git/lib.rb', line 1923

def current_command_version
  Git::Deprecation.warn(
    'Git::Lib#current_command_version is deprecated and will be removed in 6.0. ' \
    'Use Git.git_version instead, which returns a Git::Version (not an Array). ' \
    'For the legacy array shape, call: Git.git_version.to_a'
  )
  git_version.to_a
end

#describe(commit_ish = nil, opts = {}) ⇒ String

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.

Finds most recent tag that is reachable from a commit

Parameters:

  • commit_ish (String, nil) (defaults to: nil)

    target commit sha or object name

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

    the given options

Options Hash (opts):

  • :all (Boolean, nil) — default: nil

    use refs from all branches, tags, and remotes

  • :tags (Boolean, nil) — default: nil

    consider any tag, not just annotated ones

  • :contains (Boolean, nil) — default: nil

    find the tag that comes after the commit

  • :debug (Boolean, nil) — default: nil

    enable verbose searching strategy output

  • :long (Boolean, nil) — default: nil

    always output the long format

  • :always (Boolean, nil) — default: nil

    show uniquely abbreviated commit as a fallback

  • :exact_match (Boolean, nil) — default: nil

    only output exact tag matches

  • :dirty (true, String)
  • :abbrev (String)
  • :candidates (String)
  • :match (String)

Returns:

  • (String)

    the tag name

Raises:

  • (ArgumentError)

    if the commit_ish is a string starting with a hyphen

See Also:



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

def describe(commit_ish = nil, opts = {})
  assert_args_are_not_options('commit-ish object', commit_ish)

  # Translate legacy :"exact-match" (hyphenated) key to :exact_match (underscored)
  opts = opts.dup
  opts[:exact_match] ||= opts.delete(:'exact-match') if opts.key?(:'exact-match')

  commit_ishes = Array(commit_ish).compact
  Git::Commands::Describe.new(self).call(*commit_ishes, **opts).stdout
end

#diff_files

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.

compares the index and the working directory



1014
1015
1016
1017
# File 'lib/git/lib.rb', line 1014

def diff_files
  Git::Commands::Status.new(self).call
  parse_raw_diff_output(Git::Commands::DiffFiles.new(self).call.stdout)
end

#diff_full(obj1 = 'HEAD', obj2 = nil, opts = {}) ⇒ String

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.

Show full diff patch output between commits or the working tree

Delegates to Commands::Diff.

Parameters:

  • obj1 (String) (defaults to: 'HEAD')

    first commit reference (default: 'HEAD')

  • obj2 (String, nil) (defaults to: nil)

    second commit reference (default: nil)

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

    options

Options Hash (opts):

  • :path_limiter (String, Pathname, Array<String, Pathname>) — default: nil

    pathspecs to limit the diff

Returns:

  • (String)

    the unified diff patch output

Raises:

See Also:



930
931
932
933
934
935
936
937
938
939
940
# File 'lib/git/lib.rb', line 930

def diff_full(obj1 = 'HEAD', obj2 = nil, opts = {})
  assert_valid_opts(opts, DIFF_FULL_ALLOWED_OPTS)
  pathspecs = normalize_pathspecs(opts[:path_limiter], 'path limiter')
  result = Git::Commands::Diff.new(self).call(
    *[obj1, obj2].compact,
    patch: true, numstat: true, shortstat: true,
    src_prefix: 'a/', dst_prefix: 'b/',
    path: pathspecs
  )
  extract_patch_text(result.stdout)
end

#diff_index(treeish)

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.

compares the index and the repository



1020
1021
1022
1023
# File 'lib/git/lib.rb', line 1020

def diff_index(treeish)
  Git::Commands::Status.new(self).call
  parse_raw_diff_output(Git::Commands::DiffIndex.new(self).call(treeish).stdout)
end

#diff_path_status(reference1 = nil, reference2 = nil, opts = {}) ⇒ Hash

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.

Show path status (name-status) for diff between commits or the working tree

Delegates to Commands::Diff and extracts status letters and paths from the raw output lines.

Parameters:

  • reference1 (String, nil) (defaults to: nil)

    first commit reference (default: nil)

  • reference2 (String, nil) (defaults to: nil)

    second commit reference (default: nil)

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

    options

Options Hash (opts):

  • :path_limiter (String, Pathname, Array<String, Pathname>) — default: nil

    pathspecs to limit the diff

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

    deprecated; use :path_limiter instead

Returns:

  • (Hash)

    mapping of file paths to status letters (e.g. { "lib/foo.rb" => "M", "README.md" => "A" })

Raises:

See Also:



999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
# File 'lib/git/lib.rb', line 999

def diff_path_status(reference1 = nil, reference2 = nil, opts = {})
  assert_valid_opts(opts, DIFF_PATH_STATUS_ALLOWED_OPTS)

  path_limiter = handle_deprecated_path_option(opts)
  pathspecs = normalize_pathspecs(path_limiter, 'path limiter')
  result = Git::Commands::Diff.new(self).call(
    *[reference1, reference2].compact,
    raw: true, numstat: true, shortstat: true,
    src_prefix: 'a/', dst_prefix: 'b/',
    path: pathspecs
  )
  extract_name_status_from_raw(result.stdout)
end

#diff_stats(obj1 = 'HEAD', obj2 = nil, opts = {}) ⇒ Hash

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.

Show numstat diff output between commits or the working tree

Delegates to Commands::Diff.

Parameters:

  • obj1 (String) (defaults to: 'HEAD')

    first commit reference (default: 'HEAD')

  • obj2 (String, nil) (defaults to: nil)

    second commit reference (default: nil)

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

    options

Options Hash (opts):

  • :path_limiter (String, Pathname, Array<String, Pathname>) — default: nil

    pathspecs to limit the diff

Returns:

  • (Hash)

    diff statistics with the shape: { total: { insertions:, deletions:, lines:, files: }, files: { ... } }

Raises:

See Also:



962
963
964
965
966
967
968
969
970
971
972
973
# File 'lib/git/lib.rb', line 962

def diff_stats(obj1 = 'HEAD', obj2 = nil, opts = {})
  assert_valid_opts(opts, DIFF_STATS_ALLOWED_OPTS)
  pathspecs = normalize_pathspecs(opts[:path_limiter], 'path limiter')
  result = Git::Commands::Diff.new(self).call(
    *[obj1, obj2].compact,
    numstat: true, shortstat: true,
    src_prefix: 'a/', dst_prefix: 'b/',
    path: pathspecs
  )
  output_lines = extract_numstat_lines(result.stdout)
  parse_diff_stats_output(output_lines)
end

#each_cat_file_header(data) {|key, value| ... }

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.

This method returns an undefined value.

Yields parsed header key/value pairs from git cat-file output lines

Consumes header lines from the front of data until a non-header line is encountered. Continuation lines that begin with a space are folded into the previous header value using newline separators.

Parameters:

  • data (Array<String>)

    mutable output lines from a cat-file response

Yields:

  • (key, value)

    each parsed header pair

Yield Parameters:

  • key (String)

    header field name

  • value (String)

    unfolded header value text

Yield Returns:

  • (void)

Raises:

  • (NoMethodError)

    if data contains non-string entries



493
494
495
496
497
498
499
500
501
502
# File 'lib/git/lib.rb', line 493

def each_cat_file_header(data)
  while (match = CAT_FILE_HEADER_LINE.match(data.shift))
    key = match[:key]
    value_lines = [match[:value]]

    value_lines << data.shift.lstrip while data.first.start_with?(' ')

    yield key, value_lines.join("\n")
  end
end

#empty?Boolean

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 true if the repository is empty (meaning it has no commits)

Returns:

  • (Boolean)


1195
1196
1197
1198
1199
1200
1201
1202
1203
# File 'lib/git/lib.rb', line 1195

def empty?
  Git::Commands::RevParse.new(self).call('HEAD', verify: true)
  false
rescue Git::FailedError => e
  raise unless e.result.status.exitstatus == 128 &&
               e.result.stderr == 'fatal: Needed a single revision'

  true
end

#fetch(remote, opts)

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.



1639
1640
1641
1642
1643
1644
# File 'lib/git/lib.rb', line 1639

def fetch(remote, opts)
  opts = opts.dup
  refspecs = Array(opts.delete(:ref)).compact
  positionals = [*([remote] if remote), *refspecs]
  Git::Commands::Fetch.new(self).call(*positionals, **opts, merge: true).stdout
end

#fsck(*objects, **opts) ⇒ Git::FsckResult

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.

Execute git fsck to verify repository integrity

rubocop:disable Style/ArgumentsForwarding

Parameters:

  • objects (Array<String>)

    optional object identifiers to check

  • opts (Hash)

    command options (see Commands::Fsck#call)

Returns:



1790
1791
1792
1793
# File 'lib/git/lib.rb', line 1790

def fsck(*objects, **opts)
  result = Git::Commands::Fsck.new(self).call(*objects, no_progress: true, **opts)
  Git::Parsers::Fsck.parse(result.stdout)
end

#full_log_commits(opts = {}) ⇒ Array<Hash>

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.

Return the commits that are within the given revision range

Parameters:

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

    the given options

Options Hash (opts):

  • :count (Integer)

    the maximum number of commits to return (maps to max-count)

  • :all (Boolean, nil) — default: nil

    include commits reachable from any ref

  • :cherry (Boolean, nil) — default: nil

    omit commits equivalent to cherry-picked commits

  • :since (String)
  • :until (String)
  • :grep (String)
  • :author (String)
  • :between (Array<String>)

    an array of two commit-ish strings to specify a revision range

    Only :between or :object options can be used, not both.

  • :object (String)

    the revision range for the git log command

    Only :between or :object options can be used, not both.

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

    only include commits that impact files from the specified paths

  • :skip (Integer)

Returns:

  • (Array<Hash>)

    the log output parsed into an array of hashs for each commit

    Each hash contains the following keys:

    • 'sha' [String] the commit sha
    • 'author' [String] the author of the commit
    • 'message' [String] the commit message
    • 'parent' [Array] the commit shas of the parent commits
    • 'tree' [String] the tree sha
    • 'author' [String] the author of the commit and timestamp of when the changes were created
    • 'committer' [String] the committer of the commit and timestamp of when the commit was applied
    • 'merges' [Boolean] if truthy, only include merge commits (aka commits with 2 or more parents)

Raises:

  • (ArgumentError)

    if the revision range (specified with :between or :object) is a string starting with a hyphen

See Also:



288
289
290
291
292
293
294
# File 'lib/git/lib.rb', line 288

def full_log_commits(opts = {})
  assert_valid_opts(opts, FULL_LOG_ALLOWED_OPTS)
  validate_log_count_option!(opts)

  call_opts = log_base_call_options(opts, skip: opts[:skip], merges: opts[:merges])
  run_log_command(log_revision_range_args(opts), call_opts)
end

#full_tree(sha)

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.



692
693
694
# File 'lib/git/lib.rb', line 692

def full_tree(sha)
  Git::Commands::LsTree.new(self).call(sha, r: true).stdout.split("\n")
end

#gc

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.



1778
1779
1780
# File 'lib/git/lib.rb', line 1778

def gc
  Git::Commands::Gc.new(self).call(prune: true, aggressive: true, auto: true)
end

#git_versionGit::Version

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 git version as a Git::Version

Parses the output of git version, strips platform suffixes (like .windows.1 or .vfs.0), and pads two-segment versions to three segments.

Results are cached globally (keyed by binary path). It is assumed that the git version doesn't change during runtime for a given binary.

Examples:

lib.git_version #=> Git::Version.new(2, 42, 1)

Returns:

Raises:



1889
1890
1891
1892
1893
1894
# File 'lib/git/lib.rb', line 1889

def git_version
  self.class.cached_git_version(Git::Base.config.binary_path) do
    output = Git::Commands::Version.new(self).call.stdout
    Git::Version.parse(output)
  end
end

#global_config_get(name)

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.

Raises:



1106
1107
1108
1109
1110
1111
# File 'lib/git/lib.rb', line 1106

def global_config_get(name)
  result = Git::Commands::ConfigOptionSyntax::Get.new(self).call(name, global: true)
  raise Git::FailedError, result if result.status.exitstatus != 0

  result.stdout
end

#global_config_list

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.



1117
1118
1119
# File 'lib/git/lib.rb', line 1117

def global_config_list
  parse_config_list Git::Commands::ConfigOptionSyntax::List.new(self).call(global: true).stdout.split("\n")
end

#global_config_set(name, value)

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.



1153
1154
1155
# File 'lib/git/lib.rb', line 1153

def global_config_set(name, value)
  Git::Commands::ConfigOptionSyntax::Set.new(self).call(name, value, global: true)
end

#grep(pattern, opts = {})

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.

Raises:



800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
# File 'lib/git/lib.rb', line 800

def grep(pattern, opts = {})
  assert_valid_opts(opts, GREP_ALLOWED_OPTS)

  opts = normalize_grep_opts(opts)
  object = opts.delete(:object) || 'HEAD'
  result = Git::Commands::Grep.new(self).call(
    object, pattern:, **opts, no_color: true, line_number: true, null: true
  )
  exitstatus = result.status.exitstatus

  # Exit status 1 with empty stderr means no lines matched (not an error)
  return {} if exitstatus == 1 && result.stderr.empty?

  # Exit status 1 with non-empty stderr is a real error (e.g. bad object reference)
  raise Git::FailedError, result if exitstatus == 1

  parse_grep_output(result.stdout)
end

#handle_deprecated_path_option(opts) ⇒ String, ...

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.

Handle deprecated :path option in favor of :path_limiter

Parameters:

  • opts (Hash)

    options hash that may contain :path or :path_limiter

Returns:

  • (String, Pathname, Array<String, Pathname>, nil)

    the resolved path limiter



887
888
889
890
891
892
893
894
895
896
# File 'lib/git/lib.rb', line 887

def handle_deprecated_path_option(opts)
  if opts.key?(:path_limiter)
    opts[:path_limiter]
  elsif opts.key?(:path)
    Git::Deprecation.warn(
      'Git::Lib#diff_path_status :path option is deprecated. Use :path_limiter instead.'
    )
    opts[:path]
  end
end

#ignored_files

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.



1079
1080
1081
1082
1083
# File 'lib/git/lib.rb', line 1079

def ignored_files
  Git::Commands::LsFiles.new(self).call(
    others: true, ignored: true, exclude_standard: true
  ).stdout.split("\n").map { |f| unescape_quoted_path(f) }
end

#init(opts = {}) ⇒ String

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.

Creates or reinitializes the repository in the current directory

This is a low-level method that just runs git init with the given options. For full repository initialization including directory creation and path resolution, use Git.init instead.

Parameters:

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

    command options

Options Hash (opts):

  • :bare (Boolean, nil) — default: nil

    create a bare repository

  • :initial_branch (String, nil) — default: nil

    use the specified name for the initial branch

  • :separate_git_dir (String, nil) — default: nil

    path to put the .git directory (--separate-git-dir)

  • :repository (String, nil) — default: nil

    deprecated — use :separate_git_dir instead

Returns:

  • (String)

    the command output



106
107
108
109
110
# File 'lib/git/lib.rb', line 106

def init(opts = {})
  opts = opts.dup
  opts[:separate_git_dir] ||= opts.delete(:repository)
  Git::Commands::Init.new(self).call(**opts).stdout
end

#list_files(ref_dir)

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.



745
746
747
748
# File 'lib/git/lib.rb', line 745

def list_files(ref_dir)
  dir = File.join(@git_dir, 'refs', ref_dir)
  Dir.glob('**/*', base: dir).select { |f| File.file?(File.join(dir, f)) }
end

#ls_files(location = nil) ⇒ Hash<String, Hash>

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.

List all files that are in the index

Parameters:

  • location (String) (defaults to: nil)

    the location to list the files from

Returns:

  • (Hash<String, Hash>)

    a hash of files in the index

    • key: file [String] the file path
    • value: file_info [Hash] the file information containing the following keys:
      • :path [String] the file path
      • :mode_index [String] the file mode
      • :sha_index [String] the file sha
      • :stage [String] the file stage


1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
# File 'lib/git/lib.rb', line 1037

def ls_files(location = nil)
  location ||= '.'
  {}.tap do |files|
    Git::Commands::LsFiles.new(self).call(location, stage: true).stdout.split("\n").each do |line|
      (info, file) = split_status_line(line)
      (mode, sha, stage) = info.split
      files[file] = {
        path: file, mode_index: mode, sha_index: sha, stage: stage
      }
    end
  end
end

#ls_remote(location = nil, opts = {})

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.



1073
1074
1075
1076
1077
# File 'lib/git/lib.rb', line 1073

def ls_remote(location = nil, opts = {})
  repository = location || '.'
  output_lines = Git::Commands::LsRemote.new(self).call(repository, **opts).stdout.split("\n")
  parse_ls_remote_output(output_lines)
end

#ls_tree(sha, opts = {}) ⇒ Hash<String, Hash<String, Hash>>

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.

Lists the objects in a git tree

Parameters:

  • sha (String)

    the tree-ish object to list

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

    additional options

Returns:

  • (Hash<String, Hash<String, Hash>>)

    parsed ls-tree output



665
666
667
668
669
670
671
672
673
# File 'lib/git/lib.rb', line 665

def ls_tree(sha, opts = {})
  assert_valid_opts(opts, LS_TREE_ALLOWED_OPTS)
  r_value = opts[:recursive]
  paths = Array(opts[:path]).compact
  safe_options = {}
  safe_options[:r] = r_value unless r_value.nil?
  result = Git::Commands::LsTree.new(self).call(sha, *paths, **safe_options)
  parse_ls_tree_output(result.stdout)
end

#meets_required_version?Boolean

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.

Deprecated.

For a boolean check, use Git.git_version >= Git::MINIMUM_GIT_VERSION. For enforcement, no action is needed: Commands::Base#call automatically invokes validate_version!, which raises VersionError on failure.

Returns:

  • (Boolean)


1970
1971
1972
1973
1974
1975
1976
1977
1978
# File 'lib/git/lib.rb', line 1970

def meets_required_version?
  Git::Deprecation.warn(
    'Git::Lib#meets_required_version? is deprecated and will be removed in 6.0. ' \
    'For a boolean check, use: Git.git_version >= Git::MINIMUM_GIT_VERSION. ' \
    'For enforcement, no action is needed: Git::Commands::Base#call automatically ' \
    'invokes validate_version!, which raises Git::VersionError on failure.'
  )
  git_version >= Git::MINIMUM_GIT_VERSION
end

#merge(branch, message = nil, opts = {}) ⇒ String

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.

Merge one or more branches into the current branch

Parameters:

  • branch (String, Array<String>)

    branch name(s) to merge

  • message (String, nil) (defaults to: nil)

    commit message for merge commit

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

    merge options

Options Hash (opts):

  • :no_commit (Boolean, nil) — default: nil

    stop before creating merge commit (deprecated: use no_commit: true instead)

  • :no_ff (Boolean, nil) — default: nil

    create merge commit even for fast-forward (deprecated: use no_ff: true instead)

  • :m (String) — default: nil

    commit message (deprecated: use message: option)

  • :commit (Boolean, nil) — default: nil

    true for --commit (--commit)

  • :ff (Boolean, nil) — default: nil

    true for --ff (--ff)

  • :ff_only (Boolean, nil) — default: nil

    only merge if fast-forward possible

  • :squash (Boolean, nil) — default: nil

    squash commits into single commit

  • :message (String) — default: nil

    commit message

  • :strategy (String) — default: nil

    merge strategy (e.g., 'ort', 'ours')

  • :strategy_option (String, Array<String>) — default: nil

    strategy-specific options

  • :allow_unrelated_histories (Boolean, nil) — default: nil

    allow merging unrelated histories

Returns:

  • (String)

    the command output



1452
1453
1454
1455
1456
1457
1458
1459
1460
# File 'lib/git/lib.rb', line 1452

def merge(branch, message = nil, opts = {})
  # Handle legacy positional message argument
  opts = opts.merge(message: message) if message

  # Map legacy option names to new interface
  opts = translate_merge_options(opts)

  Git::Commands::Merge::Start.new(self).call(*Array(branch), no_edit: true, **opts).stdout
end

#merge_base(*commits, options = {}) ⇒ Array<String>

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.

Find common ancestor commit(s) for merge

Parameters:

  • commits (Array<String>)

    commits to find common ancestor(s) of

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

    merge-base options

Options Hash (options):

  • :octopus (Boolean, nil) — default: nil

    compute best ancestor for n-way merge

  • :independent (Boolean, nil) — default: nil

    list commits not reachable from others

  • :fork_point (Boolean, nil) — default: nil

    find fork point

  • :all (Boolean, nil) — default: nil

    output all merge bases

Returns:

  • (Array<String>)

    array of commit SHAs



1477
1478
1479
1480
1481
# File 'lib/git/lib.rb', line 1477

def merge_base(*args)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  result = Git::Commands::MergeBase.new(self).call(*args, **opts)
  result.stdout.lines.map(&:strip).reject(&:empty?)
end

#mv(source, destination, options = {}) ⇒ String

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 command output.

Returns:

  • (String)

    the command output



688
689
690
# File 'lib/git/lib.rb', line 688

def mv(source, destination, options = {})
  Git::Commands::Mv.new(self).call(*Array(source), destination, verbose: true, **options).stdout
end

#name_rev(commit_ish) ⇒ String? Also known as: namerev

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.

Find the first symbolic name for given commit_ish

Parameters:

  • commit_ish (String)

    the commit_ish to find the symbolic name of

Returns:

  • (String, nil)

    the first symbolic name or nil if the commit_ish isn't found

Raises:

  • (ArgumentError)

    if the commit_ish is a string starting with a hyphen



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

def name_rev(commit_ish)
  assert_args_are_not_options('commit_ish', commit_ish)

  Git::Commands::NameRev.new(self).call(commit_ish).stdout.split[1]
end

#normalize_pathspecs(pathspecs, arg_name) ⇒ Array<String>?

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.

Normalizes path specifications for Git commands

Converts a single path or array of paths into a consistent array format suitable for appending to Git command arguments after '--'. Empty strings are filtered out after conversion.

Parameters:

  • pathspecs (String, Pathname, Array<String, Pathname>, nil)

    path(s) to normalize

  • arg_name (String)

    name of the argument for error messages

Returns:

  • (Array<String>, nil)

    normalized array of path strings, or nil if empty/nil input

Raises:

  • (ArgumentError)

    if any path is not a String or Pathname



845
846
847
848
849
850
851
852
853
854
855
# File 'lib/git/lib.rb', line 845

def normalize_pathspecs(pathspecs, arg_name)
  return nil unless pathspecs

  normalized = Array(pathspecs)
  validate_pathspec_types(normalized, arg_name)

  normalized = normalized.map(&:to_s).reject(&:empty?)
  return nil if normalized.empty?

  normalized
end

#parse_cat_file_meta(output, object)

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.



556
557
558
559
560
561
562
563
564
565
566
567
568
# File 'lib/git/lib.rb', line 556

def parse_cat_file_meta(output, object)
  line = output.to_s.lines.first.to_s.chomp

  request_object_to_raise_error!(object) if line == "#{object} missing"

  match = /\A\S+ (?<type>\S+) (?<size>\d+)\z/.match(line)
  raise Git::UnexpectedResultError, "unexpected git cat-file metadata output: #{line.inspect}" if match.nil?

  {
    type: match[:type],
    size: match[:size].to_i
  }
end

#parse_config(file)

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.



1130
1131
1132
# File 'lib/git/lib.rb', line 1130

def parse_config(file)
  parse_config_list Git::Commands::ConfigOptionSyntax::List.new(self).call(file: file).stdout.split("\n")
end

#parse_config_list(lines)

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.



1121
1122
1123
1124
1125
1126
1127
1128
# File 'lib/git/lib.rb', line 1121

def parse_config_list(lines)
  hsh = {}
  lines.each do |line|
    (key, *values) = line.split('=')
    hsh[key] = values.join('=')
  end
  hsh
end

#process_commit_data(data, sha)

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.



462
463
464
465
466
467
468
469
# File 'lib/git/lib.rb', line 462

def process_commit_data(data, sha)
  # process_commit_headers consumes the header lines from the `data` array,
  # leaving only the message lines behind.
  headers = process_commit_headers(data)
  message = "#{data.join("\n")}\n"

  { 'sha' => sha, 'message' => message }.merge(headers)
end

#process_commit_log_data(data)

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.



590
591
592
# File 'lib/git/lib.rb', line 590

def process_commit_log_data(data)
  RawLogParser.new(data).parse
end

#process_tag_data(data, name)

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.



578
579
580
581
582
583
584
585
586
587
588
# File 'lib/git/lib.rb', line 578

def process_tag_data(data, name)
  hsh = { 'name' => name }

  each_cat_file_header(data) do |key, value|
    hsh[key] = value
  end

  hsh['message'] = "#{data.join("\n")}\n"

  hsh
end

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

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.

Raises:

  • (ArgumentError)


1748
1749
1750
1751
1752
1753
1754
1755
# File 'lib/git/lib.rb', line 1748

def pull(remote = nil, branch = nil, opts = {})
  raise ArgumentError, 'You must specify a remote if a branch is specified' if remote.nil? && !branch.nil?

  assert_valid_opts(opts, PULL_ALLOWED_OPTS)
  allowed_opts = opts.slice(*PULL_ALLOWED_OPTS)
  positional_args = [remote, branch].compact
  Git::Commands::Pull.new(self).call(*positional_args, no_edit: true, no_progress: true, **allowed_opts).stdout
end

#push(options = {}) ⇒ String #push(remote, options = {}) ⇒ String #push(remote, branch, options = {}) ⇒ String #push(remote, branch, tags) ⇒ String

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.

Push refs to a remote repository

Overloads:

  • #push(options = {}) ⇒ String

    Push using the current branch's default remote and push configuration

    Parameters:

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

      push options

    Options Hash (options):

    • :all (Boolean, nil) — default: nil

      push all branches

    • :mirror (Boolean, nil) — default: nil

      push all refs

    • :tags (Boolean, nil) — default: nil

      push all tags

    • :force (Boolean, nil) — default: nil

      force updates

    • :delete (Boolean, nil) — default: nil

      delete the named remote ref

    • :push_option (String, Array<String>) — default: nil

      server-side push option values

    Returns:

    • (String)

      the stdout from the final git push invocation

    Raises:

  • #push(remote, options = {}) ⇒ String

    Push to the given remote using the current branch's default push configuration

    Parameters:

    • remote (String)

      the remote name or URL to push to

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

      push options

    Options Hash (options):

    • :all (Boolean, nil) — default: nil

      push all branches

    • :mirror (Boolean, nil) — default: nil

      push all refs

    • :tags (Boolean, nil) — default: nil

      push all tags

    • :force (Boolean, nil) — default: nil

      force updates

    • :delete (Boolean, nil) — default: nil

      delete the named remote ref

    • :push_option (String, Array<String>) — default: nil

      server-side push option values

    Returns:

    • (String)

      the stdout from the final git push invocation

    Raises:

  • #push(remote, branch, options = {}) ⇒ String

    Push a branch or refspec to the given remote

    Parameters:

    • remote (String)

      the remote name or URL to push to

    • branch (String)

      the branch name or refspec to push

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

      push options

    Options Hash (options):

    • :all (Boolean, nil) — default: nil

      push all branches

    • :mirror (Boolean, nil) — default: nil

      push all refs

    • :tags (Boolean, nil) — default: nil

      push all tags

    • :force (Boolean, nil) — default: nil

      force updates

    • :delete (Boolean, nil) — default: nil

      delete the named remote ref

    • :push_option (String, Array<String>) — default: nil

      server-side push option values

    Returns:

    • (String)

      the stdout from the final git push invocation

    Raises:

    • (Git::FailedError)

      if git exits with a non-zero exit status

    • (ArgumentError)

      if remote is nil

  • #push(remote, branch, tags) ⇒ String

    Backward-compatible shorthand for push(remote, branch, tags: tags)

    Parameters:

    • remote (String)

      the remote name or URL to push to

    • branch (String)

      the branch name or refspec to push

    • tags (Boolean)

      whether to push all tags

    Returns:

    • (String)

      the stdout from the final git push invocation

    Raises:

    • (Git::FailedError)

      if git exits with a non-zero exit status

    • (ArgumentError)

      if remote is nil



1736
1737
1738
1739
1740
1741
1742
1743
1744
# File 'lib/git/lib.rb', line 1736

def push(remote = nil, branch = nil, opts = nil)
  remote, branch, opts = normalize_push_args(remote, branch, opts)
  validate_push_args!(remote, branch, opts)

  first_result = push_refs(remote, branch, opts)
  return first_result.stdout unless push_tags_separately?(opts)

  push_tags(remote, opts).stdout
end

#read_tree(treeish, opts = {})

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.



1798
1799
1800
1801
1802
# File 'lib/git/lib.rb', line 1798

def read_tree(treeish, opts = {})
  assert_valid_opts(opts, READ_TREE_ALLOWED_OPTS)
  allowed_opts = opts.slice(*READ_TREE_ALLOWED_OPTS)
  Git::Commands::ReadTree.new(self).call(treeish, **allowed_opts)
end

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

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.



1513
1514
1515
1516
1517
1518
# File 'lib/git/lib.rb', line 1513

def remote_add(name, url, opts = {})
  translated_opts = opts.dup
  translated_opts[:fetch] = translated_opts.delete(:with_fetch) if translated_opts.key?(:with_fetch)

  Git::Commands::Remote::Add.new(self).call(name, url, **translated_opts)
end

#remote_remove(name)

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.



1528
1529
1530
# File 'lib/git/lib.rb', line 1528

def remote_remove(name)
  Git::Commands::Remote::Remove.new(self).call(name)
end

#remote_set_branches(name, branches, opts = {})

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.



1520
1521
1522
# File 'lib/git/lib.rb', line 1520

def remote_set_branches(name, branches, opts = {})
  Git::Commands::Remote::SetBranches.new(self).call(name, *Array(branches).flatten, **opts)
end

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

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.



1524
1525
1526
# File 'lib/git/lib.rb', line 1524

def remote_set_url(name, url, opts = {})
  Git::Commands::Remote::SetUrl.new(self).call(name, url, **opts)
end

#remotes

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.



1532
1533
1534
# File 'lib/git/lib.rb', line 1532

def remotes
  Git::Commands::Remote::List.new(self).call.stdout.split("\n")
end

#repack

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.



1774
1775
1776
# File 'lib/git/lib.rb', line 1774

def repack
  Git::Commands::Repack.new(self).call(a: true, d: true)
end

#repository_default_branch(repository) ⇒ String

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 name of the default branch of the given repository

Parameters:

  • repository (URI, Pathname, String)

    The (possibly remote) repository to clone from

Returns:

  • (String)

    the name of the default branch

Raises:



185
186
187
188
189
190
191
192
193
194
195
# File 'lib/git/lib.rb', line 185

def repository_default_branch(repository)
  output = Git::Commands::LsRemote.new(self).call(repository, 'HEAD', symref: true).stdout

  match_data = output.match(%r{^ref: refs/remotes/origin/(?<default_branch>[^\t]+)\trefs/remotes/origin/HEAD$})
  return match_data[:default_branch] if match_data

  match_data = output.match(%r{^ref: refs/heads/(?<default_branch>[^\t]+)\tHEAD$})
  return match_data[:default_branch] if match_data

  raise Git::UnexpectedResultError, 'Unable to determine the default branch'
end

#request_object_to_raise_error!(object)

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.

Re-request the missing object via non-batch cat-file so git produces a real non-zero exit and a FailedError with an accurate stderr message.



572
573
574
575
576
# File 'lib/git/lib.rb', line 572

def request_object_to_raise_error!(object)
  Git::Commands::CatFile::Raw.new(self).call(object, p: true)
  raise Git::UnexpectedResultError,
        "expected git cat-file to raise Git::FailedError for missing object #{object.inspect}"
end

#required_command_version

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.

Deprecated.

Use MINIMUM_GIT_VERSION constant instead, which returns a Version (not an Array). For the legacy array shape, call: Git::MINIMUM_GIT_VERSION.to_a.first(2)



1957
1958
1959
1960
1961
1962
1963
1964
# File 'lib/git/lib.rb', line 1957

def required_command_version
  Git::Deprecation.warn(
    'Git::Lib#required_command_version is deprecated and will be removed in 6.0. ' \
    'Use the Git::MINIMUM_GIT_VERSION constant instead, which returns a Git::Version ' \
    '(not an Array). For the legacy array shape, call: Git::MINIMUM_GIT_VERSION.to_a.first(2)'
  )
  Git::MINIMUM_GIT_VERSION.to_a.first(2)
end

#reset(commit = nil, opts = {}) ⇒ String

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 command output.

Returns:

  • (String)

    the command output



1229
1230
1231
# File 'lib/git/lib.rb', line 1229

def reset(commit = nil, opts = {})
  Git::Commands::Reset.new(self).call(commit, **opts).stdout
end

#rev_parse(revision) ⇒ String Also known as: revparse

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.

Verify and resolve a Git revision to its full SHA

Examples:

lib.rev_parse('HEAD') # => '9b9b31e704c0b85ffdd8d2af2ded85170a5af87d'
lib.rev_parse('9b9b31e') # => '9b9b31e704c0b85ffdd8d2af2ded85170a5af87d'

Parameters:

  • revision (String)

    the revision to resolve

Returns:

  • (String)

    the full commit hash

Raises:

See Also:



313
314
315
# File 'lib/git/lib.rb', line 313

def rev_parse(revision)
  Git::Commands::RevParse.new(self).call(revision, '--', revs_only: true).stdout
end

#revert(commitish, opts = {})

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.



1242
1243
1244
1245
1246
# File 'lib/git/lib.rb', line 1242

def revert(commitish, opts = {})
  assert_valid_opts(opts, REVERT_ALLOWED_OPTS)
  opts = { no_edit: true }.merge(opts)
  Git::Commands::Revert::Start.new(self).call(commitish, **opts).stdout
end

#rm(path = '.', opts = {}) ⇒ String

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.

Remove files from the working tree and from the index

Parameters:

  • path (String, Array<String>) (defaults to: '.')

    files or directories to remove

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

    command options

Options Hash (opts):

  • :force (Boolean, nil) — default: nil

    force removal, bypassing the up-to-date check; alias: :f

  • :recursive (Boolean, nil) — default: nil

    remove directories and their contents recursively

  • :cached (Boolean, nil) — default: nil

    only remove from the index, keeping working tree files

Returns:

  • (String)

    the command output



1187
1188
1189
# File 'lib/git/lib.rb', line 1187

def rm(path = '.', opts = {})
  Git::Commands::Rm.new(self).call(*Array(path), **opts).stdout
end

#show(objectish = nil, path = nil) ⇒ String

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.

Shows objects

Parameters:

  • objectish (String|NilClass) (defaults to: nil)

    the target object reference (nil == HEAD)

  • path (String|NilClass) (defaults to: nil)

    the path of the file to be shown

Returns:

  • (String)

    the object information



1139
1140
1141
1142
# File 'lib/git/lib.rb', line 1139

def show(objectish = nil, path = nil)
  object = path ? "#{objectish}:#{path}" : objectish
  Git::Commands::Show.new(self).call(*[object].compact).stdout
end

#stash_apply(id = nil) ⇒ String

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.

Apply a stash to the working directory

This method preserves v4.0.0 backward compatibility by returning the command output.

Examples:

Apply the latest stash

lib.stash_apply

Apply a specific stash

lib.stash_apply('stash@{1}')

Parameters:

  • id (String, Integer, nil) (defaults to: nil)

    the stash identifier (e.g., 'stash@{0}', 0) or nil for latest

Returns:

  • (String)

    the output from the git stash apply command

See Also:



1312
1313
1314
1315
# File 'lib/git/lib.rb', line 1312

def stash_apply(id = nil)
  result = Git::Commands::Stash::Apply.new(self).call(id)
  result.stdout
end

#stash_clearString

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.

Remove all stash entries

This method preserves v4.0.0 backward compatibility by returning the command output.

Examples:

Clear all stashes

lib.stash_clear

Returns:

  • (String)

    the output from the git stash clear command

See Also:



1328
1329
1330
1331
# File 'lib/git/lib.rb', line 1328

def stash_clear
  result = Git::Commands::Stash::Clear.new(self).call
  result.stdout
end

#stash_listString

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.

List all stash entries in standard git stash list format

This method preserves v4.0.0 backward compatibility by returning a formatted string matching the output of git stash list.

Examples:

List all stashes

lib.stash_list # => "stash@\\{0}: On main: WIP\nstash@\\{1}: On feature: test"

Returns:

  • (String)

    newline-separated list of stash entries in the format "stash@{n}: ", or an empty string if no stashes exist

See Also:



1346
1347
1348
1349
1350
# File 'lib/git/lib.rb', line 1346

def stash_list
  result = Git::Commands::Stash::List.new(self).call
  stashes = Git::Parsers::Stash.parse_list(result.stdout)
  stashes.map { |info| "#{info.name}: #{info.message}" }.join("\n")
end

#stash_save(message) ⇒ Boolean

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.

Save the current working directory and index state to a new stash

This method preserves v4.0.0 backward compatibility by returning a truthy/falsy value indicating whether a stash was created.

Examples:

Save current changes

lib.stash_save('WIP: feature work')

Parameters:

  • message (String)

    the stash message

Returns:

  • (Boolean)

    true if changes were stashed, false if there were no local changes to save

See Also:



1291
1292
1293
1294
# File 'lib/git/lib.rb', line 1291

def stash_save(message) # rubocop:disable Naming/PredicateMethod
  result = Git::Commands::Stash::Push.new(self).call(message: message)
  !result.stdout.include?('No local changes to save')
end

#stashes_allArray<Array(Integer, String)>

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 all stash entries as an array of index and message pairs

List all stash entries in the repository ordered from oldest to newest

The index is a sequential number starting from 0 for the oldest stash, and the message is the description of the stash entry.

Examples:

List all stashes (oldest first)

lib.stashes_all # => [[0, "Fix bug"], [1, "Add feature"]]

Returns:

  • (Array<Array(Integer, String)>)

    array of [index, message] pairs where index is the sequential position (0 is oldest) and message is the stash description

See Also:



1271
1272
1273
1274
1275
# File 'lib/git/lib.rb', line 1271

def stashes_all
  result = Git::Commands::Stash::List.new(self).call
  stashes = Git::Parsers::Stash.parse_list(result.stdout)
  stashes.reverse.each_with_index.map { |info, i| stash_info_to_legacy(info, i) }
end

#tag(name, target, opts = {}) ⇒ String #tag(name, opts = {}) ⇒ String #tag(name, opts = {}) ⇒ String

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.

Create or delete a tag

When the :d or :delete option is set, deletes the named tag. Otherwise, creates a new tag pointing at HEAD or the specified target.

Overloads:

  • #tag(name, target, opts = {}) ⇒ String

    Create a tag on the specified target

    Parameters:

    • name (String)

      the tag name to create

    • target (String)

      the commit or object to tag

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

      options for creating the tag

    Options Hash (opts):

    • :annotate (Boolean, nil) — default: nil

      create an unsigned, annotated tag object. Requires :message or :file.

      Alias: :a

    • :sign (Boolean, nil) — default: nil

      create a GPG-signed tag. Requires :message or :file.

      Alias: :s

    • :force (Boolean, nil) — default: nil

      replace an existing tag with the given name.

      Alias: :f

    • :message (String) — default: nil

      use the given string as the tag message. Implies annotated tag if none of :annotate, :sign, or :local_user is given.

      Alias: :m

  • #tag(name, opts = {}) ⇒ String

    Create a lightweight tag on HEAD

    Parameters:

    • name (String)

      the tag name to create

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

      options for creating the tag

    Options Hash (opts):

    • :annotate (Boolean, nil) — default: nil

      create an unsigned, annotated tag object. Requires :message or :file.

      Alias: :a

    • :sign (Boolean, nil) — default: nil

      create a GPG-signed tag. Requires :message or :file.

      Alias: :s

    • :force (Boolean, nil) — default: nil

      replace an existing tag with the given name.

      Alias: :f

    • :message (String) — default: nil

      use the given string as the tag message. Implies annotated tag if none of :annotate, :sign, or :local_user is given.

      Alias: :m

  • #tag(name, opts = {}) ⇒ String

    Delete the named tag

    Parameters:

    • name (String)

      the tag name to delete

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

      options

    Options Hash (opts):

    • :delete (Boolean, nil) — default: nil

      delete the named tag.

      Alias: :d

Returns:

  • (String)

    command output

Raises:

  • (ArgumentError)

    if creating an annotated or signed tag without a message

  • (Git::FailedError)

    if the tag already exists (without :force) or if the tag to delete does not exist

See Also:



1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
# File 'lib/git/lib.rb', line 1627

def tag(name, *args)
  opts = args.last.is_a?(Hash) ? args.pop : {}
  target = args.first

  if opts[:d] || opts[:delete]
    delete_tag(name)
  else
    validate_tag_options!(opts)
    create_tag(name, target, opts)
  end
end

#tag_sha(tag_name) ⇒ String

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.

Return the SHA of a tag reference

Looks up the tag first in the local refs directory, then falls back to git show-ref. Returns an empty string if the tag does not exist.

Parameters:

  • tag_name (String)

    the tag name to look up

Returns:

  • (String)

    the SHA of the tag, or an empty string if not found



1766
1767
1768
1769
1770
1771
1772
# File 'lib/git/lib.rb', line 1766

def tag_sha(tag_name)
  head = File.join(@git_dir, 'refs', 'tags', tag_name)
  return File.read(head).chomp if File.exist?(head)

  result = Git::Commands::ShowRef::List.new(self).call(tag_name, tags: true, hash: true)
  result.stdout
end

#tagsArray<String>

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.

List all tags in the repository

Returns:

  • (Array<String>)

    tag names

See Also:



1542
1543
1544
1545
# File 'lib/git/lib.rb', line 1542

def tags
  result = Git::Commands::Tag::List.new(self).call(format: Git::Parsers::Tag::FORMAT_STRING)
  Git::Parsers::Tag.parse_list(result.stdout).map(&:name)
end

#tree_depth(sha)

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.



696
697
698
# File 'lib/git/lib.rb', line 696

def tree_depth(sha)
  full_tree(sha).size
end

#unescape_quoted_path(path) ⇒ String

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.

Unescape a path if it is quoted

Git commands that output paths (e.g. ls-files, diff), will escape unusual characters.

Examples:

lib.unescape_if_quoted('"quoted_file_\\342\\230\\240"') # => 'quoted_file_☠'
lib.unescape_if_quoted('unquoted_file')   # => 'unquoted_file'

Parameters:

  • path (String)

    the path to unescape if quoted

Returns:

  • (String)

    the unescaped path if quoted otherwise the original path



1065
1066
1067
1068
1069
1070
1071
# File 'lib/git/lib.rb', line 1065

def unescape_quoted_path(path)
  if path.start_with?('"') && path.end_with?('"')
    Git::EscapedPath.new(path[1..-2]).unescape
  else
    path
  end
end

#unmergedArray<String>

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.

List paths that remain unmerged after a failed or partial merge

Delegates to Commands::Diff.

Returns:

  • (Array<String>)

    paths of files with unresolved merge conflicts

Raises:

See Also:



1493
1494
1495
1496
1497
1498
# File 'lib/git/lib.rb', line 1493

def unmerged
  result = Git::Commands::Diff.new(self).call(cached: true)
  result.stdout.split("\n").filter_map do |line|
    ::Regexp.last_match(1) if line =~ /^\* Unmerged path (.*)/
  end
end

#untracked_files

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.



1085
1086
1087
1088
1089
# File 'lib/git/lib.rb', line 1085

def untracked_files
  Git::Commands::LsFiles.new(self).call(
    others: true, exclude_standard: true, chdir: @git_work_dir
  ).stdout.split("\n").map { |f| unescape_quoted_path(f) }
end

#update_ref(ref, commit)

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.



1816
1817
1818
# File 'lib/git/lib.rb', line 1816

def update_ref(ref, commit)
  Git::Commands::UpdateRef::Update.new(self).call(ref, commit)
end

#validate_pathspec_types(pathspecs, arg_name)

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.

Validates that all pathspecs are String or Pathname objects

Parameters:

  • pathspecs (Array)

    the pathspecs to validate

  • arg_name (String)

    name of the argument for error messages

Raises:

  • (ArgumentError)

    if any path is not a String or Pathname



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

def validate_pathspec_types(pathspecs, arg_name)
  return if pathspecs.all? { |path| path.is_a?(String) || path.is_a?(Pathname) }

  raise ArgumentError, "Invalid #{arg_name}: must be a String, Pathname, or Array of Strings/Pathnames"
end

#worktree_add(dir, commitish = nil)

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.



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

def worktree_add(dir, commitish = nil)
  if commitish.nil?
    Git::Commands::Worktree::Add.new(self).call(dir).stdout
  else
    Git::Commands::Worktree::Add.new(self).call(dir, commitish).stdout
  end
end

#worktree_prune

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.



741
742
743
# File 'lib/git/lib.rb', line 741

def worktree_prune
  Git::Commands::Worktree::Prune.new(self).call.stdout
end

#worktree_remove(dir)

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.



737
738
739
# File 'lib/git/lib.rb', line 737

def worktree_remove(dir)
  Git::Commands::Worktree::Remove.new(self).call(dir).stdout
end

#worktrees_all

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.



709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
# File 'lib/git/lib.rb', line 709

def worktrees_all
  arr = []
  directory = ''
  # Output example for `worktree list --porcelain`:
  # worktree /code/public/ruby-git
  # HEAD 4bef5abbba073c77b4d0ccc1ffcd0ed7d48be5d4
  # branch refs/heads/master
  #
  # worktree /tmp/worktree-1
  # HEAD b8c63206f8d10f57892060375a86ae911fad356e
  # detached
  #
  Git::Commands::Worktree::List.new(self).call(porcelain: true).stdout.split("\n").each do |w|
    s = w.split
    directory = s[1] if s[0] == 'worktree'
    arr << [directory, s[1]] if s[0] == 'HEAD'
  end
  arr
end

#write_tree

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.



1804
1805
1806
# File 'lib/git/lib.rb', line 1804

def write_tree
  Git::Commands::WriteTree.new(self).call.stdout
end