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 #add_tag(name, delete: true) ⇒ String

Create a new tag

Overloads:

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

    Returns the newly created tag.

    Examples:

    Create a lightweight tag on HEAD

    repo.add_tag('v1.0.0')

    Create an annotated tag on HEAD

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

    Replace an existing tag on HEAD

    repo.add_tag('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:

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

    Returns the newly created tag.

    Examples:

    Create a lightweight tag on a specific commit

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

    Create an annotated tag on a specific commit

    repo.add_tag('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:

  • #add_tag(name, delete: true) ⇒ String
    Deprecated.

    Use #delete_tag instead.

    Returns git's stdout from the delete.

    Examples:

    Delete a tag (deprecated)

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

    Parameters:

    • name (String)

      the name of the tag to delete

    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



828
829
830
831
832
833
834
835
836
837
838
839
# File 'lib/git/repository/object_operations.rb', line 828

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

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

  opts = opts.except(:d, :delete)
  SharedPrivate.assert_valid_opts!(ADD_TAG_ALLOWED_OPTS, **opts)
  Private.validate_tag_options!(opts)
  Git::Commands::Tag::Create.new(@execution_context).call(name, target, **opts)
  tag(name)
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:



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

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

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:



172
173
174
175
# File 'lib/git/repository/object_operations.rb', line 172

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

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

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:



110
111
112
113
114
# File 'lib/git/repository/object_operations.rb', line 110

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

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:



219
220
221
222
223
224
# File 'lib/git/repository/object_operations.rb', line 219

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

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:



135
136
137
138
139
# File 'lib/git/repository/object_operations.rb', line 135

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

Delete a tag

Examples:

Delete a tag

repo.delete_tag('v1.0.0')

Parameters:

  • name (String)

    the name of the tag to delete

Returns:

  • (String)

    git's stdout from the delete

Raises:



852
853
854
855
856
857
# File 'lib/git/repository/object_operations.rb', line 852

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

  result.stdout
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:



306
307
308
# File 'lib/git/repository/object_operations.rb', line 306

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:



586
587
588
# File 'lib/git/repository/object_operations.rb', line 586

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:



610
611
612
# File 'lib/git/repository/object_operations.rb', line 610

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:



464
465
466
467
468
469
470
471
472
473
# File 'lib/git/repository/object_operations.rb', line 464

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:



630
631
632
# File 'lib/git/repository/object_operations.rb', line 630

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:



397
398
399
400
401
402
403
404
405
# File 'lib/git/repository/object_operations.rb', line 397

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?

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:



350
351
352
353
354
# File 'lib/git/repository/object_operations.rb', line 350

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:



682
683
684
# File 'lib/git/repository/object_operations.rb', line 682

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

#rev_parse(objectish) ⇒ String

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:



251
252
253
# File 'lib/git/repository/object_operations.rb', line 251

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)



654
655
656
# File 'lib/git/repository/object_operations.rb', line 654

def tag(tag_name)
  Git::Object::Tag.new(self, tag_name)
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:



273
274
275
276
277
278
279
# File 'lib/git/repository/object_operations.rb', line 273

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:



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

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:



327
328
329
# File 'lib/git/repository/object_operations.rb', line 327

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