Skip to content

Commit

Permalink
Do not change ENV variables of a current process
Browse files Browse the repository at this point in the history
Instead pass relevant environment to the actual shell command being run

Signed-off-by: James Couball <jcouball@yahoo.com>
  • Loading branch information
jcouball committed Dec 27, 2023
1 parent b0d89ac commit 4a969a0
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 58 deletions.
6 changes: 4 additions & 2 deletions lib/git/base.rb
Expand Up @@ -69,8 +69,10 @@ def self.root_of_worktree(working_dir)
status = nil

git_cmd = "#{Git::Base.config.binary_path} -c core.quotePath=true -c color.ui=false rev-parse --show-toplevel 2>&1"
result, status = Open3.capture2(git_cmd, chdir: File.expand_path(working_dir))
result = result.chomp
IO.popen(git_cmd, :chdir => working_dir) do |io|
status = Process.wait2(io.pid).last
result = io.read.chomp
end

raise ArgumentError, "'#{working_dir}' is not in a git working tree" unless status.success?
result
Expand Down
67 changes: 11 additions & 56 deletions lib/git/lib.rb
Expand Up @@ -7,8 +7,6 @@
module Git
class Lib

@@semaphore = Mutex.new

# The path to the Git working copy. The default is '"./.git"'.
#
# @return [Pathname] the path to the Git working copy.
Expand Down Expand Up @@ -442,10 +440,7 @@ def worktree_prune
def list_files(ref_dir)
dir = File.join(@git_dir, 'refs', ref_dir)
files = []
begin
files = Dir.glob('**/*', base: dir).select { |f| File.file?(File.join(dir, f)) }
rescue
end
files = Dir.glob(File.join(dir, '**/*')).select { |f| File.file?(f) } rescue nil
files
end

Expand Down Expand Up @@ -1146,41 +1141,14 @@ def command_lines(cmd, *opts, chdir: nil)
op.split("\n")
end

# Takes the current git's system ENV variables and store them.
def store_git_system_env_variables
@git_system_env_variables = {}
ENV_VARIABLE_NAMES.each do |env_variable_name|
@git_system_env_variables[env_variable_name] = ENV[env_variable_name]
end
end

# Takes the previously stored git's ENV variables and set them again on ENV.
def restore_git_system_env_variables
ENV_VARIABLE_NAMES.each do |env_variable_name|
ENV[env_variable_name] = @git_system_env_variables[env_variable_name]
end
end

# Sets git's ENV variables to the custom values for the current instance.
def set_custom_git_env_variables
ENV['GIT_DIR'] = @git_dir
ENV['GIT_WORK_TREE'] = @git_work_dir
ENV['GIT_INDEX_FILE'] = @git_index_file
ENV['GIT_SSH'] = Git::Base.config.git_ssh
end

# Runs a block inside an environment with customized ENV variables.
# It restores the ENV after execution.
#
# @param [Proc] block block to be executed within the customized environment
def with_custom_env_variables(&block)
@@semaphore.synchronize do
store_git_system_env_variables()
set_custom_git_env_variables()
return block.call()
end
ensure
restore_git_system_env_variables()
# git's ENV variables for the current instance.
def custom_git_env_variables
{
'GIT_DIR' => @git_dir,
'GIT_WORK_TREE' => @git_work_dir,
'GIT_INDEX_FILE' => @git_index_file,
'GIT_SSH' => Git::Base.config.git_ssh,
}
end

def command(*cmd, redirect: '', chomp: true, chdir: nil, &block)
Expand All @@ -1200,18 +1168,7 @@ def command(*cmd, redirect: '', chomp: true, chdir: nil, &block)

git_cmd = "#{Git::Base.config.binary_path} #{global_opts} #{escaped_cmd} #{redirect} 2>&1"

output = nil

command_thread = nil;

status = nil

with_custom_env_variables do
command_thread = Thread.new do
output, status = run_command(git_cmd, chdir, &block)
end
command_thread.join
end
output, status = run_command(git_cmd, chdir, &block)

@logger.info(git_cmd)
@logger.debug(output)
Expand Down Expand Up @@ -1298,9 +1255,7 @@ def run_command(git_cmd, chdir=nil, &block)
opts = {}
opts[:chdir] = File.expand_path(chdir) if chdir

Open3.popen2(git_cmd, opts) do |stdin, stdout, wait_thr|
[block.call(stdout), wait_thr.value]
end
[IO.popen(custom_git_env_variables, git_cmd, opts, &block), $?]
end

def escape(s)
Expand Down

0 comments on commit 4a969a0

Please sign in to comment.