Class: Git::CommandLine::Capturing

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

Overview

Executes a git command and captures both stdout and stderr in memory

Capturing is the buffering strategy: it calls ProcessExecuter.run_with_capture, which reads all subprocess output into String objects before returning. Use this class (via Lib#command_capturing) for the vast majority of git subcommands whose output fits comfortably in memory.

Streaming is the complementary strategy for commands (such as cat-file -p <blob>) whose stdout may be too large to buffer.

Examples:

capturing = Git::CommandLine::Capturing.new(
  {}, '/usr/bin/git', %w[--git-dir /repo/.git], Logger.new($stdout)
)
result = capturing.run('log', '--oneline', '-5')
result.stdout   # => "abc1234 Initial commit\n..."
result.stderr   # => ""

See Also:

Constant Summary collapse

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

Default options accepted by #run

{
  in: nil,
  out: nil,
  err: nil,
  chdir: nil,
  timeout: nil,
  raise_on_failure: true,
  env: {},
  normalize: false,
  chomp: false,
  merge: false
}.freeze

Instance Attribute Summary

Attributes inherited from Base

#binary_path, #env, #global_opts, #logger

Instance Method Summary collapse

Methods inherited from Base

#initialize

Constructor Details

This class inherits a constructor from Git::CommandLine::Base

Instance Method Details

#run(**options_hash) ⇒ Git::CommandLineResult

Execute a git command, capture stdout and stderr, and return the result

Non-option command-line arguments to pass to git. If you collect the arguments in an array, splat the array into the parameter list.

NORMALIZATION

The command output is returned as a Unicode string containing the binary output from the command. If the binary output is not valid UTF-8, the output will cause problems because the encoding will be invalid.

Normalization is a process that tries to convert the binary output to a valid UTF-8 string. It uses the rchardet gem to detect the encoding of the binary output and then converts it to UTF-8.

Normalization is not enabled by default. Pass normalize: true to enable it. When enabled, normalization is applied to both stdout and stderr in the returned result object, regardless of the out: or err: options. Only the captured in-memory strings are normalized; any external IO you provide will receive the raw subprocess output.

Examples:

Run a command and return the output

result = capturing.run('version')
result.stdout #=> "git version 2.39.1\n"

The args array should be splatted into the parameter list

args = %w[log -n 1 --oneline]
result = capturing.run(*args)
result.stdout #=> "f5baa11 beginning of Ruby/Git project\n"

Run a command and return the chomped output

result = capturing.run('version', chomp: true)
result.stdout #=> "git version 2.39.1"

Run a command without normalizing the output

capturing.run('version', normalize: false) #=> "git version 2.39.1\n"

Capture stdout in a temporary file

require 'tempfile'
Tempfile.create('git') do |file|
  capturing.run('version', out: file)
  file.rewind
  file.read #=> "git version 2.39.1\n"
end

Capture stderr in a StringIO object

require 'stringio'
stderr = StringIO.new
begin
  capturing.run('log', 'nonexistent-branch', err: stderr)
rescue Git::FailedError => e
  stderr.string #=> "unknown revision or path not in the working tree.\n"
end

Parameters:

  • options_hash (Hash)

    the options to pass to the command

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 (not StringIO).

  • :out (#write, nil)

    the object to write stdout to, or nil to capture stdout in the returned result.

    If this is a StringIO object, stdout_writer.string will be returned.

    In general, only specify a stdout_writer when you want to redirect stdout to a file or other #write-responding object. The default behaviour returns the command output.

  • :err (#write, nil)

    the object to write stderr to, or nil to capture stderr in the returned result.

  • :normalize (Boolean) — default: false

    whether to normalize the encoding of stdout and stderr output

  • :chomp (Boolean) — default: false

    whether to chomp both stdout and stderr output

  • :merge (Boolean) — default: false

    whether to merge stdout and stderr in the returned string

  • :chdir (String, nil)

    the directory to run the command in

  • :timeout (Numeric, nil)

    the maximum seconds to wait for the command to complete. Zero means no timeout. A timeout kills the process via SIGKILL and raises TimeoutError.

  • :raise_on_failure (Boolean) — default: true

    whether to raise FailedError on non-zero exit status. TimeoutError and SignaledError are always raised regardless.

  • :env (Hash) — default: {}

    additional environment variable overrides for this command. String keys map to String values (to set) or nil (to unset).

Returns:

Raises:

  • (ArgumentError)

    if args contains an array or an unknown option is passed

  • (Git::SignaledError)

    if the command was terminated by an uncaught signal

  • (Git::FailedError)

    if the command returned a non-zero exit status

  • (Git::ProcessIOError)

    if an exception was raised while collecting subprocess output

  • (Git::TimeoutError)

    if the command times out



156
157
158
159
160
161
# File 'lib/git/command_line/capturing.rb', line 156

def run(*, **options_hash)
  options = merge_and_validate_options(RUN_OPTION_DEFAULTS, options_hash)

  result = execute(*, **options)
  process_result(result, options)
end