Module: Git::Repository::ContextHelpers

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

Overview

Facade methods for block-based directory and index context helpers

These helpers allow callers to temporarily change the working directory, the git index, or both, restoring the original state unconditionally when the block exits — even if the block raises an exception.

Included by Git::Repository.

Instance Method Summary collapse

Instance Method Details

#chdir {|dir| ... } ⇒ Object

Changes the current working directory to the repository working directory for the duration of the block

Examples:

Write a file inside the repository working directory

repo.chdir do |dir|
  File.write('hello.txt', 'Hello, world!')
  repo.add('hello.txt')
end

Yields:

  • (dir)

    the repository working directory

Yield Parameters:

  • dir (Pathname)

    the working directory path

Yield Returns:

  • (Object)

    returned as the method's return value

Returns:

  • (Object)

    the value returned by the block

Raises:

  • (ArgumentError)

    if the repository has no working directory (bare repository)



41
42
43
44
45
# File 'lib/git/repository/context_helpers.rb', line 41

def chdir
  raise ArgumentError, 'cannot chdir: repository has no working directory (bare repository)' if dir.nil?

  Dir.chdir(dir.to_s) { yield dir }
end

#set_index(index_file, check = nil, must_exist: nil)

This method returns an undefined value.

Sets the git index to index_file and rebuilds the execution context

By default raises if index_file does not exist. Pass must_exist: false to skip the existence check (useful when the index will be created by git later).

Examples:

Set the index to a custom path

repo.set_index('/path/to/custom.index')

Parameters:

  • index_file (String, Pathname)

    path to the new index file

  • check (Boolean, nil) (defaults to: nil)

    deprecated positional argument — use must_exist: instead; emits a deprecation warning when non-nil

  • must_exist (Boolean, nil) (defaults to: nil)

    when true (the default), raises ArgumentError if index_file does not exist on disk

Raises:

  • (ArgumentError)

    if must_exist: true (the default) and index_file does not exist



196
197
198
199
200
201
# File 'lib/git/repository/context_helpers.rb', line 196

def set_index(index_file, check = nil, must_exist: nil)
  must_exist = context_helpers_deprecate_check_argument(check, must_exist)
  new_path = context_helpers_validate_path(index_file, must_exist)
  context_helpers_rebuild_context(git_index_file: new_path.to_s)
  nil
end

#set_working(work_dir, check = nil, must_exist: nil)

This method returns an undefined value.

Sets the git working directory to work_dir and rebuilds the execution context

By default raises if work_dir does not exist. Pass must_exist: false to skip the existence check.

Examples:

Set the working directory to a custom path

repo.set_working('/path/to/working')

Parameters:

  • work_dir (String, Pathname)

    path to the new working directory

  • check (Boolean, nil) (defaults to: nil)

    deprecated positional argument — use must_exist: instead; emits a deprecation warning when non-nil

  • must_exist (Boolean, nil) (defaults to: nil)

    when true (the default), raises ArgumentError if work_dir does not exist on disk

Raises:

  • (ArgumentError)

    if must_exist: true (the default) and work_dir does not exist



225
226
227
228
229
230
# File 'lib/git/repository/context_helpers.rb', line 225

def set_working(work_dir, check = nil, must_exist: nil)
  must_exist = context_helpers_deprecate_check_argument(check, must_exist)
  new_path = context_helpers_validate_path(work_dir, must_exist)
  context_helpers_rebuild_context(git_work_dir: new_path.to_s)
  nil
end

#with_index(new_index) {|repo| ... } ⇒ Object

Temporarily switches the git index to new_index for the duration of the block

Rebuilds the repository execution context to point to the new index file, yields self, then unconditionally restores the original execution context — even if the block raises an exception.

Examples:

Read a tree into a custom index

repo.with_index('/tmp/custom.index') do
  repo.read_tree('HEAD')
end

Parameters:

  • new_index (String, Pathname)

    path to the replacement index file

Yields:

  • (repo)

    the repository instance with the new index active

Yield Parameters:

Yield Returns:

  • (Object)

    returned as the method's return value

Returns:

  • (Object)

    the value returned by the block



69
70
71
72
73
74
75
# File 'lib/git/repository/context_helpers.rb', line 69

def with_index(new_index) # :yields: self
  old_context = @execution_context
  set_index(new_index, must_exist: false)
  yield self
ensure
  @execution_context = old_context
end

#with_temp_index {|repo| ... } ⇒ Object

Temporarily switches the git index to a new temporary file for the duration of the block, then removes the file

The temporary index file does not exist until git creates it on first write. A unique temporary directory is created to hold the index path, avoiding the risk of presenting an empty file to git (which git would reject as a corrupt index). The directory — and any files inside it — are removed unconditionally after the block exits, even if the block raises an exception.

Examples:

Stage changes using a temporary index

repo.with_temp_index do
  repo.read_tree('HEAD')
  repo.write_tree
end

Yields:

  • (repo)

    the repository instance with the temporary index active

Yield Parameters:

Yield Returns:

  • (Object)

    returned as the method's return value

Returns:

  • (Object)

    the value returned by the block



101
102
103
104
105
106
107
108
109
110
111
# File 'lib/git/repository/context_helpers.rb', line 101

def with_temp_index(&) # :yields: self
  # Use a unique temp directory so the index file path is collision-free
  # and does not exist until git writes it. An existing empty file would
  # be treated as a corrupt index by git.
  temp_dir = Dir.mktmpdir('git-temp-index-')
  begin
    with_index(File.join(temp_dir, 'index'), &)
  ensure
    FileUtils.remove_entry(temp_dir, true)
  end
end

#with_temp_working {|repo| ... } ⇒ Object

Temporarily switches the git working directory to a new temporary directory for the duration of the block, then removes the directory and its contents

The temporary directory is removed unconditionally after the block exits, even if the block raises an exception.

Examples:

Write files in an isolated temporary working directory

repo.with_temp_working do
  File.write('scratch.txt', 'temporary content')
end

Yields:

  • (repo)

    the repository instance with the temporary working directory active

Yield Parameters:

Yield Returns:

  • (Object)

    returned as the method's return value

Returns:

  • (Object)

    the value returned by the block



170
171
172
# File 'lib/git/repository/context_helpers.rb', line 170

def with_temp_working(&block) # :yields: self
  Dir.mktmpdir('temp-workdir') { |temp_dir| with_working(temp_dir, &block) }
end

#with_working(work_dir) {|repo| ... } ⇒ Object

Temporarily switches the git working directory to work_dir for the duration of the block

Rebuilds the repository execution context to point to the new working directory, changes the process working directory via Dir.chdir, yields self, then unconditionally restores the original execution context — even if the block raises an exception.

Examples:

Commit changes from a different worktree path

repo.with_working('/path/to/worktree') do
  repo.add('.')
  repo.commit('chore: automated update')
end

Parameters:

  • work_dir (String, Pathname)

    path to the replacement working directory

Yields:

  • (repo)

    the repository instance with the new working directory active

Yield Parameters:

Yield Returns:

  • (Object)

    returned as the method's return value

Returns:

  • (Object)

    the value returned by the block

Raises:

  • (ArgumentError)

    if work_dir does not exist on disk



141
142
143
144
145
146
147
# File 'lib/git/repository/context_helpers.rb', line 141

def with_working(work_dir) # :yields: self
  old_context = @execution_context
  set_working(work_dir)
  Dir.chdir(dir.to_s) { yield self }
ensure
  @execution_context = old_context
end