Module: Git::Repository::ObjectOperations

Included in:
Git::Repository
Defined in:
lib/git/repository/object_operations.rb

Overview

Facade methods for raw git object store queries

Included by Git::Repository.

Instance Method Summary collapse

Instance Method Details

#add_tag(name, options = {}) ⇒ Git::Object::Tag #add_tag(name, target, options = {}) ⇒ Git::Object::Tag

Deprecated.

Use #tag_add instead.

Overloads:

  • #add_tag(name, options = {}) ⇒ Git::Object::Tag

    Returns the newly created tag.

    Parameters:

    • name (String)

      the name of the tag to create

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

      options for creating the tag

    Returns:

  • #add_tag(name, target, options = {}) ⇒ Git::Object::Tag

    Returns the newly created tag.

    Parameters:

    • name (String)

      the name of the tag to create

    • target (String)

      the object to tag (commit SHA, branch name, etc.)

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

      options for creating the tag

    Returns:

Raises:

  • (ArgumentError)

    if unsupported options are provided

  • (ArgumentError)

    if an annotated or signed tag is requested without a message

  • (Git::FailedError)

    if git exits with a non-zero exit status



915
916
917
918
919
920
921
# File 'lib/git/repository/object_operations.rb', line 915

def add_tag(name, *options)
  Git::Deprecation.warn(
    'Git::Repository#add_tag is deprecated and will be removed in v6.0.0. ' \
    'Use Git::Repository#tag_add instead.'
  )
  tag_add(name, *options)
end

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

Create an archive of the repository tree and write it to a file

Writes the archive content to a file and returns the file path. The default format is zip. Pass format: 'tar' for an uncompressed tar archive, or format: 'tgz' for a gzip-compressed tar archive (equivalent to format: 'tar' with add_gzip: true).

When no file path is given, a temporary file is created and its path is returned.

File replacement behavior when file is given:

The archive is first written to a staging file in the same directory as file. This means write permission is required on the parent directory of file, not just on file itself. Once the archive is fully written, the staging file atomically replaces file via rename.

If file already exists, only its numeric permission bits are applied to the new archive; ownership, ACLs, and extended attributes are not transferred. If file does not exist, the archive receives the standard file creation mode (0666 & ~umask). On Windows, File.chmod has no effect, so the archive always receives the default creation mode regardless of whether file already exists.

If file is a symlink that does not point to a directory, the symlink itself is replaced by the new archive file rather than writing through the link to its target. A symlink that points to a directory is treated as a directory and rejected with ArgumentError.

Examples:

Archive HEAD as a zip file

repo.archive('HEAD', '/tmp/release.zip') #=> "/tmp/release.zip"

Archive a tag as a tar file

repo.archive('v1.0', '/tmp/release.tar', format: 'tar') #=> "/tmp/release.tar"

Archive with a path prefix applied to every entry

repo.archive('HEAD', '/tmp/out.tar', format: 'tar', prefix: 'myproject/')
#=> "/tmp/out.tar"

Archive a subdirectory only

repo.archive('HEAD', '/tmp/src.tar', format: 'tar', path: 'src/')
#=> "/tmp/src.tar"

Parameters:

  • treeish (String)

    tree-ish to archive — commit SHA, tag, branch name, or tree SHA

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

    (nil) destination file path; when nil, a unique temporary file is created and its path is returned

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

    archive options

Options Hash (opts):

  • :format (String) — default: 'zip'

    archive format — 'tar', 'zip', or 'tgz'; 'tgz' is internally converted to 'tar' with gzip post-processing

  • :prefix (String) — default: nil

    prefix prepended to every filename in the archive; typically ends with /

  • :path (String) — default: nil

    path within the tree to include in the archive; when given, only files under that path are archived

  • :remote (String) — default: nil

    retrieve the archive from a remote repository rather than the local one

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

    apply gzip compression after writing the archive; set automatically when format: 'tgz' is given

Returns:

  • (String)

    path to the written archive file

Raises:

  • (ArgumentError)

    if unsupported options are provided

  • (ArgumentError)

    if file is an existing directory

  • (Git::FailedError)

    if git exits with a non-zero exit status

See Also:



605
606
607
608
609
610
611
612
613
614
615
616
617
# File 'lib/git/repository/object_operations.rb', line 605

def archive(treeish, file = nil, opts = {})
  SharedPrivate.assert_valid_opts!(ARCHIVE_ALLOWED_OPTS, **opts)
  raise ArgumentError, "#{file.inspect} is a directory" if file && File.directory?(file)

  tmp = Private.write_archive_tmp(@execution_context, treeish, opts, dest_dir: Private.staging_dir_for(file))
  return tmp unless file

  Private.atomic_replace(tmp, file)
  file
rescue StandardError
  FileUtils.rm_f(tmp) if tmp
  raise
end

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

Returns parsed commit data for the given git object

Examples:

Get commit data for HEAD

repo.cat_file_commit('HEAD')
# => {
#   'sha'       => 'HEAD',
#   'tree'      => 'def5678...',
#   'parent'    => ['ghi9012...'],
#   'author'    => 'A U Thor <author@example.com> 1234567890 +0000',
#   'committer' => 'A U Thor <author@example.com> 1234567890 +0000',
#   'message'   => "Initial commit\n"
# }

Parameters:

  • object (String)

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

Returns:

  • (Hash)

    commit data

    String-keyed hash with the following keys:

    • tree — the tree SHA
    • parent — Array of parent SHAs (empty for the root commit)
    • author — author identity string and timestamp
    • committer — committer identity string and timestamp
    • message — the commit message (includes trailing newline)
    • gpgsig — the cryptographic signature (signed commits only)
    • sha — the object argument as passed by the caller

Raises:

See Also:



198
199
200
201
# File 'lib/git/repository/object_operations.rb', line 198

def cat_file_commit(object)
  result = Git::Commands::CatFile::Raw.new(@execution_context).call('commit', object)
  Git::Parsers::CatFile.parse_commit(result.stdout.split("\n"), object)
end

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

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

    repo.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

  • #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

    repo.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 git exits with a non-zero exit status

See Also:



77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/git/repository/object_operations.rb', line 77

def cat_file_contents(object)
  raise ArgumentError, "Invalid object: '#{object}'" if object&.start_with?('-')

  return Git::Commands::CatFile::Raw.new(@execution_context).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(@execution_context).call(object, p: true, out: file)
    file.rewind
    yield file
  end
end

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

Returns the size of a git object in bytes

Examples:

Get the size of a commit object

repo.cat_file_size('HEAD') #=> 265

Get the size of a blob by treeish path

repo.cat_file_size('HEAD:README.md') #=> 14

Parameters:

  • object (String)

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

Returns:

  • (Integer)

    the object size in bytes

Raises:

  • (ArgumentError)

    if object starts with a hyphen

  • (Git::FailedError)

    if git exits with a non-zero exit status

See Also:



122
123
124
125
126
# File 'lib/git/repository/object_operations.rb', line 122

def cat_file_size(object)
  raise ArgumentError, "Invalid object: '#{object}'" if object&.start_with?('-')

  Git::Commands::CatFile::Raw.new(@execution_context).call(object, s: true).stdout.chomp.to_i
end

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

Returns parsed tag data for the given annotated tag object

Does not work with lightweight tags. To list all annotated tags in a repository:

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

Examples:

Get tag data for an annotated tag

repo.cat_file_tag('v1.0')
# => {
#   'name'    => 'v1.0',
#   'object'  => 'abc1234...',
#   'type'    => 'commit',
#   'tag'     => 'v1.0',
#   'tagger'  => 'A U Thor <author@example.com> 1234567890 +0000',
#   'message' => "Release v1.0\n"
# }

Parameters:

  • object (String)

    the annotated tag name or SHA

Returns:

  • (Hash)

    tag data

    String-keyed hash with the following keys:

    • name — the object argument as passed by the caller
    • object — the SHA of the tagged object
    • type — the type of the tagged object (usually "commit")
    • tag — the tag name
    • tagger — tagger identity string and timestamp
    • message — the tag message (includes trailing newline)

Raises:

  • (ArgumentError)

    if object starts with a hyphen

  • (Git::FailedError)

    if git exits with a non-zero exit status

See Also:



252
253
254
255
256
257
# File 'lib/git/repository/object_operations.rb', line 252

def cat_file_tag(object)
  raise ArgumentError, "Invalid object: '#{object}'" if object&.start_with?('-')

  tdata = Git::Commands::CatFile::Raw.new(@execution_context).call('tag', object).stdout.split("\n")
  Git::Parsers::CatFile.parse_tag(tdata, object)
end

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

Returns the type of a git object

Examples:

Get the type of a commit reference

repo.cat_file_type('HEAD') #=> "commit"

Get the type of a blob via treeish path

repo.cat_file_type('HEAD:README.md') #=> "blob"

Parameters:

  • object (String)

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

Returns:

  • (String)

    the object type — one of "blob", "commit", "tag", or "tree"

Raises:

  • (ArgumentError)

    if object starts with a hyphen

  • (Git::FailedError)

    if git exits with a non-zero exit status

See Also:



154
155
156
157
158
# File 'lib/git/repository/object_operations.rb', line 154

def cat_file_type(object)
  raise ArgumentError, "Invalid object: '#{object}'" if object&.start_with?('-')

  Git::Commands::CatFile::Raw.new(@execution_context).call(object, t: true).stdout.chomp
end

#delete_tag(name) ⇒ String

Deprecated.

Use #tag_delete instead.

Returns git's stdout from the delete.

Parameters:

  • name (String)

    the name of the tag to delete

Returns:

  • (String)

    git's stdout from the delete

Raises:



949
950
951
952
953
954
955
# File 'lib/git/repository/object_operations.rb', line 949

def delete_tag(name)
  Git::Deprecation.warn(
    'Git::Repository#delete_tag is deprecated and will be removed in v6.0.0. ' \
    'Use Git::Repository#tag_delete instead.'
  )
  tag_delete(name)
end

#full_tree(objectish) ⇒ Array<String>

Returns all recursive entries for a given tree object

Equivalent to running git ls-tree -r <objectish> and splitting the output on newlines. Each returned line describes a single entry in the tree in the format produced by git ls-tree: <mode> <type> <object>\t<file>.

Examples:

List all files in the tree rooted at HEAD

repo.full_tree('HEAD^{tree}')
# => [
#   "100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391\tex_dir/ex.txt",
#   "100644 blob abc1234...\tlib/git.rb"
# ]

Parameters:

  • objectish (String)

    the tree SHA or tree-ish specifier to recurse into

Returns:

  • (Array<String>)

    one entry per path, in the format <mode> <type> <object>\t<file>

    Returns an empty array for an empty tree.

Raises:

See Also:



348
349
350
# File 'lib/git/repository/object_operations.rb', line 348

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

#gblob(objectish) ⇒ Git::Object::Blob

Returns a blob object for the given object reference

The returned object is lazy: no git command is invoked until a property (e.g. Object::AbstractObject#sha, Object::AbstractObject#contents) is accessed on the result.

Examples:

Get a blob from a treeish path

repo.gblob('HEAD:README.md')
#=> #<Git::Object::Blob ...>

Parameters:

  • objectish (String)

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

Returns:

See Also:



635
636
637
# File 'lib/git/repository/object_operations.rb', line 635

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

#gcommit(objectish) ⇒ Git::Object::Commit

Returns a commit object for the given object reference

The returned object is lazy: no git command is invoked until a property (e.g. Object::AbstractObject#sha, Object::Commit#message) is accessed on the result.

Examples:

Get a commit by symbolic ref

repo.gcommit('HEAD')
#=> #<Git::Object::Commit ...>

Get a commit by abbreviated SHA

repo.gcommit('abc1234')
#=> #<Git::Object::Commit ...>

Parameters:

  • objectish (String)

    the object name (SHA, branch, tag, refspec, etc.)

Returns:

See Also:



659
660
661
# File 'lib/git/repository/object_operations.rb', line 659

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

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

Search tracked file contents in a git tree for a pattern

Runs git grep against the given tree-ish and returns every match as a filename-keyed hash of [line_number, text] pairs.

Examples:

Search HEAD for a pattern

repo.grep('TODO')
# => { "HEAD:src/foo.rb" => [[12, "# TODO: fix this"]], ... }

Limit the search to a path

repo.grep('TODO', 'src/')

Search a specific commit

repo.grep('TODO', nil, object: 'abc1234')

Case-insensitive search

repo.grep('todo', nil, ignore_case: true)

Parameters:

  • pattern (String)

    the pattern to search for

  • path_limiter (String, Pathname, Array<String, Pathname>, nil) (defaults to: nil)

    a path or array of paths to limit the search to, or nil for no limit

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

    additional options for the grep command

Options Hash (opts):

  • :object (String) — default: 'HEAD'

    the tree-ish to search

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

    ignore case distinctions in both the pattern and the file contents

    Alias: :i

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

    select non-matching lines

    Alias: :v

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

    use POSIX extended regular expressions for the pattern

    Alias: :E

Returns:

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

    a hash mapping each "treeish:filename" key to an array of [line_number, text] pairs; returns an empty hash when no lines match

Raises:

  • (ArgumentError)

    if unsupported options are provided

  • (Git::FailedError)

    if git exits with a non-zero status and stderr is non-empty (e.g. bad object reference)

See Also:



513
514
515
516
517
518
519
520
521
522
# File 'lib/git/repository/object_operations.rb', line 513

def grep(pattern, path_limiter = nil, opts = {})
  SharedPrivate.assert_valid_opts!(GREP_ALLOWED_OPTS, **opts)
  opts = opts.dup
  object = opts.delete(:object) || 'HEAD'
  opts[:pathspec] = Array(path_limiter).map(&:to_s) if path_limiter
  result = Git::Commands::Grep.new(@execution_context).call(
    object, pattern:, **opts, no_color: true, line_number: true, null: true
  )
  Private.parse_grep_result(result)
end

#gtree(objectish) ⇒ Git::Object::Tree

Returns a tree object for the given object reference

The returned object is lazy: no git command is invoked until a property (e.g. Object::AbstractObject#sha, Object::Tree#children) is accessed on the result.

Examples:

Get the root tree for the current HEAD

repo.gtree('HEAD^{tree}')
#=> #<Git::Object::Tree ...>

Parameters:

  • objectish (String)

    the object name (SHA, treeish specifier, etc.)

Returns:

See Also:



679
680
681
# File 'lib/git/repository/object_operations.rb', line 679

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

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

List the objects in a git tree

Runs git ls-tree against the given sha and returns a Hash of tree entries organised by object type.

Examples:

List the top-level tree

repo.ls_tree('HEAD')
# => { 'blob' => { 'README.md' => { mode: '100644', sha: 'abc...' } },
#      'tree' => { 'lib' => { mode: '040000', sha: 'def...' } },
#      'commit' => {} }

List the tree recursively

repo.ls_tree('HEAD', recursive: true)
# => { 'blob' => { 'lib/git.rb' => { mode: '100644', sha: '...' } }, ... }

Limit the listing to a path

repo.ls_tree('HEAD', path: 'lib/')

Parameters:

  • objectish (String)

    the tree-ish object to list

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

    additional options

Options Hash (opts):

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

    recurse into subtrees

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

    path or array of paths to limit the listing to

Returns:

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

    a three-level Hash keyed by object type ('blob', 'tree', 'commit'), then by filename, then holding :mode and :sha values

Raises:

  • (ArgumentError)

    when unsupported options are provided

  • (Git::FailedError)

    when git exits with a non-zero exit status

See Also:



446
447
448
449
450
451
452
453
454
# File 'lib/git/repository/object_operations.rb', line 446

def ls_tree(objectish, opts = {})
  SharedPrivate.assert_valid_opts!(LS_TREE_ALLOWED_OPTS, **opts)
  paths = Array(opts[:path]).compact
  r_value = opts[:recursive]
  safe_options = {}
  safe_options[:r] = r_value unless r_value.nil?
  result = Git::Commands::LsTree.new(@execution_context).call(objectish, *paths, **safe_options)
  Git::Parsers::LsTree.parse(result.stdout)
end

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

Find the first symbolic name for a commit-ish

Examples:

Find the symbolic name for a commit

repo.name_rev('abc123') #=> "main~5"

Find the symbolic name for HEAD

repo.name_rev('HEAD') #=> "main"

Parameters:

  • commit_ish (String)

    the commit-ish to find the symbolic name of

Returns:

  • (String, nil)

    the first symbolic name, or nil if stdout contains fewer than two words

Raises:

  • (ArgumentError)

    if commit_ish starts with a hyphen

  • (Git::FailedError)

    if git exits with a non-zero exit status

See Also:



392
393
394
395
396
# File 'lib/git/repository/object_operations.rb', line 392

def name_rev(commit_ish)
  raise ArgumentError, "Invalid commit_ish: '#{commit_ish}'" if commit_ish&.start_with?('-')

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

#object(objectish) ⇒ Git::Object::Blob, ...

Returns the appropriate git object for the given object reference

Runs git cat-file -t to determine the object type, then constructs and returns the corresponding Git::Object::* subclass instance.

Examples:

Get a commit object from HEAD

repo.object('HEAD')
#=> #<Git::Object::Commit ...>

Get a blob from a treeish path

repo.object('HEAD:README.md')
#=> #<Git::Object::Blob ...>

Parameters:

  • objectish (String)

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

Returns:

Raises:

  • (ArgumentError)

    if objectish starts with a hyphen

  • (Git::FailedError)

    if git exits with a non-zero exit status

See Also:



731
732
733
# File 'lib/git/repository/object_operations.rb', line 731

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

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

Resolve a revision specifier to its full object ID

Passes the given revision specifier to git rev-parse and returns the full object ID.

Examples:

Resolve HEAD to its full object ID

repo.rev_parse('HEAD') #=> "9b9b31e704c0b85ffdd8d2af2ded85170a5af87d"

Resolve an abbreviated SHA

repo.rev_parse('9b9b31e') #=> "9b9b31e704c0b85ffdd8d2af2ded85170a5af87d"

Resolve a tree object via rev-parse syntax

repo.rev_parse('HEAD^{tree}') #=> "94c827875e2cadb8bc8d4cdd900f19aa9e8634c7"

Parameters:

  • objectish (String)

    the revision specifier to resolve (branch name, tag, abbreviated SHA, refspec, etc.)

Returns:

  • (String)

    the full object ID of the resolved object

Raises:

See Also:



291
292
293
# File 'lib/git/repository/object_operations.rb', line 291

def rev_parse(objectish)
  Git::Commands::RevParse.new(@execution_context).call(objectish, '--', revs_only: true).stdout
end

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

Returns a tag object for the given tag name

Returns a Object::Tag for tag_name. The returned object is either an annotated or a lightweight tag depending on the underlying ref type.

Examples:

Get a tag object

repo.tag('v1.0')
#=> #<Git::Object::Tag name="v1.0" ...>

Parameters:

  • tag_name (String)

    the name of the tag

Returns:

Raises:

  • (Git::UnexpectedResultError)

    if tag_name does not name an existing tag

  • (Git::FailedError)

    if the underlying git show-ref invocation exits with an unexpected status (i.e., outside the allowed 0..1 range)



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

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

#tag_add(name, options = {}) ⇒ Git::Object::Tag #tag_add(name, target, options = {}) ⇒ Git::Object::Tag #tag_add(name, delete_options) ⇒ String

Create a new tag

Overloads:

  • #tag_add(name, options = {}) ⇒ Git::Object::Tag

    Returns the newly created tag.

    Examples:

    Create a lightweight tag on HEAD

    repo.tag_add('v1.0.0')

    Create an annotated tag on HEAD

    repo.tag_add('v1.0.0', annotate: true, message: 'Release 1.0.0')

    Replace an existing tag on HEAD

    repo.tag_add('v1.0.0', force: true)

    Parameters:

    • name (String)

      the name of the tag to create

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

      options for creating the tag

    Options Hash (options):

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

      make an unsigned, annotated tag object; requires :message or :file (alias: :a)

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

      alias for :annotate

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

      make a GPG-signed tag; requires :message or :file (alias: :s)

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

      alias for :sign

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

      override tag.gpgSign config to disable signing

    • :local_user (String) — default: nil

      make a signed tag using the given key (alias: :u)

    • :u (String) — default: nil

      alias for :local_user

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

      replace an existing tag with the given name instead of failing (alias: :f)

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

      alias for :force

    • :message (String) — default: nil

      use the given message as the tag message (alias: :m)

    • :m (String) — default: nil

      alias for :message

    • :file (String) — default: nil

      take the tag message from the given file; use - to read from standard input (alias: :F)

    • :F (String) — default: nil

      alias for :file

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

      open an editor to further edit the tag message (alias: :e)

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

      alias for :edit

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

      suppress the editor

    • :trailer (Hash, Array<Array>) — default: nil

      add trailers to the tag message

    • :cleanup (String) — default: nil

      set how the tag message is cleaned up; one of verbatim, whitespace, or strip

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

      create a reflog for the tag

    Returns:

  • #tag_add(name, target, options = {}) ⇒ Git::Object::Tag

    Returns the newly created tag.

    Examples:

    Create a lightweight tag on a specific commit

    repo.tag_add('v1.0.0', 'abc123')

    Create an annotated tag on a specific commit

    repo.tag_add('v1.0.0', 'abc123', annotate: true, message: 'Release 1.0.0')

    Parameters:

    • name (String)

      the name of the tag to create

    • target (String)

      the object to tag (commit SHA, branch name, etc.)

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

      options for creating the tag (same keys as the first overload)

    Returns:

  • #tag_add(name, delete_options) ⇒ String
    Deprecated.

    Use #tag_delete instead.

    Returns git's stdout from the delete.

    Examples:

    Delete a tag (deprecated)

    repo.tag_add('v1.0.0', d: true)

    Parameters:

    • name (String)

      the name of the tag to delete

    • delete_options ({ d: true }, { delete: true })

      deletion options; only :d or :delete (set to true) is accepted — no other keys and no target argument may be combined with this form

    Returns:

    • (String)

      git's stdout from the delete

    Raises:

    • (ArgumentError)

      if a target is also provided

    • (ArgumentError)

      if options other than :d/:delete are also provided

Raises:

  • (ArgumentError)

    if unsupported options are provided

  • (ArgumentError)

    if an annotated or signed tag is requested without a message

  • (Git::FailedError)

    if git exits with a non-zero exit status



875
876
877
878
879
880
881
882
883
884
885
886
# File 'lib/git/repository/object_operations.rb', line 875

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

  return Private.tag_add_delete_deprecated(self, name, target, options) if options[:d] || options[:delete]

  options = options.except(:d, :delete)
  SharedPrivate.assert_valid_opts!(TAG_ADD_ALLOWED_OPTS, **options)
  Private.validate_tag_options!(options)
  Git::Commands::Tag::Create.new(@execution_context).call(name, target, **options)
  tag(name)
end

#tag_delete(name) ⇒ String

Delete a tag

Examples:

Delete a tag

repo.tag_delete('v1.0.0')

Parameters:

  • name (String)

    the name of the tag to delete

Returns:

  • (String)

    git's stdout from the delete

Raises:



934
935
936
937
938
939
# File 'lib/git/repository/object_operations.rb', line 934

def tag_delete(name)
  result = Git::Commands::Tag::Delete.new(@execution_context).call(name)
  raise Git::FailedError, result if result.status.exitstatus.positive?

  result.stdout
end

#tag_sha(tag_name) ⇒ String

Returns the SHA of a named tag

Returns an empty string when the tag does not exist.

Examples:

Get the SHA of an existing tag

repo.tag_sha('v1.0')
#=> "abc1234567890abcdef1234567890abcdef123456"

Get the SHA of a non-existent tag

repo.tag_sha('nonexistent') #=> ""

Parameters:

  • tag_name (String)

    the tag name to look up

Returns:

  • (String)

    the SHA of the named tag, or an empty string if the tag does not exist

See Also:



315
316
317
318
319
320
321
# File 'lib/git/repository/object_operations.rb', line 315

def tag_sha(tag_name)
  tags_dir = File.expand_path(File.join(@execution_context.git_dir, 'refs', 'tags'))
  head = File.expand_path(File.join(tags_dir, tag_name))
  return File.read(head).chomp if head.start_with?("#{tags_dir}#{File::SEPARATOR}") && File.file?(head)

  Private.show_ref_tag_sha(@execution_context, tag_name)
end

#tagsArray<Git::Object::Tag>

Returns all tags in the repository as tag objects

Runs git tag --list with a machine-readable format, parses the output, and returns a Object::Tag for each tag name.

Examples:

List the names of all tags

repo.tags.map(&:name) #=> ["v1.0.0", "v2.0.0"]

No tags exist

repo.tags #=> []

Returns:

  • (Array<Git::Object::Tag>)

    one tag object per tag in the repository; empty when there are none

Raises:



751
752
753
754
# File 'lib/git/repository/object_operations.rb', line 751

def tags
  result = Git::Commands::Tag::List.new(@execution_context).call(format: Git::Parsers::Tag::FORMAT_STRING)
  Git::Parsers::Tag.parse_list(result.stdout).map { |info| tag(info.name) }
end

#tree_depth(objectish) ⇒ Integer

Returns the number of entries in a tree

Runs git ls-tree -r <objectish> and counts output lines. This matches Git::Lib#tree_depth behavior in the 4.x branch.

Examples:

Count entries in the tree rooted at HEAD

repo.tree_depth('HEAD^{tree}') #=> 42

Parameters:

  • objectish (String)

    the tree SHA or tree-ish specifier to recurse into

Returns:

  • (Integer)

    the number of entries in the recursive tree listing

Raises:

See Also:



369
370
371
# File 'lib/git/repository/object_operations.rb', line 369

def tree_depth(objectish)
  Git::Commands::LsTree.new(@execution_context).call(objectish, r: true).stdout.each_line.count
end