Class: Git::CommandLine

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

Overview

Runs a git command and returns the result

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env, binary_path, global_opts, logger) ⇒ CommandLine

Create a Git::CommandLine object

Examples:

env = { 'GIT_DIR' => '/path/to/git/dir' }
binary_path = '/usr/bin/git'
global_opts = %w[--git-dir /path/to/git/dir]
logger = Logger.new(STDOUT)
cli = CommandLine.new(env, binary_path, global_opts, logger)
cli.run('version') #=> #<Git::CommandLineResult:0x00007f9b0c0b0e00

Parameters:

  • env (Hash<String, String>)

    environment variables to set

  • global_opts (Array<String>)

    global options to pass to git

  • logger (Logger)

    the logger to use



28
29
30
31
32
33
# File 'lib/git/command_line.rb', line 28

def initialize(env, binary_path, global_opts, logger)
  @env = env
  @binary_path = binary_path
  @global_opts = global_opts
  @logger = logger
end

Instance Attribute Details

#binary_pathString (readonly)

The path to the command line binary to run

Examples:

binary_path = '/usr/bin/git'
command_line = Git::CommandLine.new({}, binary_path, ['version'], Logger.new(STDOUT))
command_line.binary_path #=> '/usr/bin/git'

Returns:

  • (String)


62
63
64
# File 'lib/git/command_line.rb', line 62

def binary_path
  @binary_path
end

#envHash<String, String> (readonly)

Variables to set (or unset) in the git command's environment

Examples:

env = { 'GIT_DIR' => '/path/to/git/dir' }
command_line = Git::CommandLine.new(env, '/usr/bin/git', [], Logger.new(STDOUT))
command_line.env #=> { 'GIT_DIR' => '/path/to/git/dir' }

Returns:

  • (Hash<String, String>)

See Also:



49
50
51
# File 'lib/git/command_line.rb', line 49

def env
  @env
end

#global_optsArray<String> (readonly)

The global options to pass to git

These are options that are passed to git before the command name and arguments. For example, in git --git-dir /path/to/git/dir version, the global options are %w[--git-dir /path/to/git/dir].

Examples:

env = {}
global_opts = %w[--git-dir /path/to/git/dir]
logger = Logger.new(nil)
cli = CommandLine.new(env, '/usr/bin/git', global_opts, logger)
cli.global_opts #=> %w[--git-dir /path/to/git/dir]

Returns:

  • (Array<String>)


81
82
83
# File 'lib/git/command_line.rb', line 81

def global_opts
  @global_opts
end

#loggerLogger (readonly)

The logger to use for logging git commands and results

Examples:

env = {}
global_opts = %w[]
logger = Logger.new(STDOUT)
cli = CommandLine.new(env, '/usr/bin/git', global_opts, logger)
cli.logger == logger #=> true

Returns:

  • (Logger)


96
97
98
# File 'lib/git/command_line.rb', line 96

def logger
  @logger
end

Instance Method Details

#run(*args, out:, err:, normalize:, chomp:, merge:, chdir: nil, timeout: nil) ⇒ Git::CommandLineResult

Execute a git command, wait for it to finish, and return the result

NORMALIZATION

The command output is returned as a Unicde 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 trys 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 Git::CommandLine#run to enable it. Normalization will only be performed on stdout and only if the out:` option is nil or is a StringIO object. If the out: option is set to a file or other IO object, the normalize option will be ignored.

Examples:

Run a command and return the output

cli.run('version') #=> "git version 2.39.1\n"

The args array should be splatted into the parameter list

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

Run a command and return the chomped output

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

Run a command and without normalizing the output

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

Capture stdout in a temporary file

require 'tempfile'
tempfile = Tempfile.create('git') do |file|
  cli.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
  cli.run('log', 'nonexistent-branch', err: stderr)
rescue Git::FailedError => e
  stderr.string #=> "unknown revision or path not in the working tree.\n"
end

Parameters:

  • args (Array<String>)

    the command line arguements to pass to git

    This array should be splatted into the parameter list.

  • out (#write, nil)

    the object to write stdout to or nil to ignore stdout

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

    In general, only specify a stdout_writer object when you want to redirect stdout to a file or some other object that responds to #write. The default behavior will return the output of the command.

  • err (#write)

    the object to write stderr to or nil to ignore stderr

    If this is a 'StringIO' object and merged_output is true, then stderr_writer.string will be merged into the output returned by this method.

  • normalize (Boolean)

    whether to normalize the output to a valid encoding

  • chomp (Boolean)

    whether to chomp the output

  • merge (Boolean)

    whether to merge stdout and stderr in the string returned

  • chdir (String) (defaults to: nil)

    the directory to run the command in

  • timeout (Numeric, nil) (defaults to: nil)

    the maximum seconds to wait for the command to complete

    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:



192
193
194
195
196
197
198
199
# File 'lib/git/command_line.rb', line 192

def run(*args, out:, err:, normalize:, chomp:, merge:, chdir: nil, timeout: nil)
  git_cmd = build_git_cmd(args)
  out ||= StringIO.new
  err ||= (merge ? out : StringIO.new)
  status = execute(git_cmd, out, err, chdir: (chdir || :not_set), timeout: timeout)

  process_result(git_cmd, status, out, err, normalize, chomp, timeout)
end