Use --end-of-options for Git arguments

This commit is contained in:
Andrew Nesbitt committed 2026-07-20 18:52:35 +01:00
1 parent b48c7994b5
commit 806fb27fe7
12 files changed
+83 -19

No files matched your search

+3 -5
View File
@@ -637,6 +637,9 @@ HOMEBREW_MACOS_NEWEST_SUPPORTED="26"
HOMEBREW_MACOS_OLDEST_SUPPORTED="14"
HOMEBREW_MACOS_OLDEST_ALLOWED="10.15"
# Some Git versions are too old for some Homebrew functionality we rely on.
HOMEBREW_MINIMUM_GIT_VERSION="2.30.0"
if [[ -n "${HOMEBREW_MACOS}" ]]
then
HOMEBREW_PRODUCT="Homebrew"
@@ -685,9 +688,6 @@ then
HOMEBREW_SYSTEM_CA_CERTIFICATES_TOO_OLD="1"
HOMEBREW_FORCE_BREWED_CA_CERTIFICATES="1"
fi
# Some Git versions are too old for some Homebrew functionality we rely on.
HOMEBREW_MINIMUM_GIT_VERSION="2.14.3"
else
if [[ -r "/proc/cpuinfo" ]] &&
[[ "${HOMEBREW_PROCESSOR}" == "x86_64" ]]
@@ -732,8 +732,6 @@ Minimum required version: ${HOMEBREW_MINIMUM_CURL_VERSION}
fi
# Ensure the system Git is at or newer than the minimum required version.
# Git 2.7.4 is the version of git on Ubuntu 16.04 LTS (Xenial Xerus).
HOMEBREW_MINIMUM_GIT_VERSION="2.7.0"
git_version_output="$(${HOMEBREW_GIT} --version 2>/dev/null)"
# $extra is intentionally discarded.
# shellcheck disable=SC2034
+2 -2
View File
@@ -665,7 +665,7 @@ EOS
then
safe_cd "${HOMEBREW_REPOSITORY}"
echo "HOMEBREW_BREW_GIT_REMOTE set: using ${HOMEBREW_BREW_GIT_REMOTE} as the Homebrew/brew Git remote."
git remote set-url origin "${HOMEBREW_BREW_GIT_REMOTE}"
git remote set-url origin --end-of-options "${HOMEBREW_BREW_GIT_REMOTE}"
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch --force --tags origin
SKIP_FETCH_BREW_REPOSITORY=1
@@ -676,7 +676,7 @@ EOS
then
safe_cd "${HOMEBREW_CORE_REPOSITORY}"
echo "HOMEBREW_CORE_GIT_REMOTE set: using ${HOMEBREW_CORE_GIT_REMOTE} as the Homebrew/homebrew-core Git remote."
git remote set-url origin "${HOMEBREW_CORE_GIT_REMOTE}"
git remote set-url origin --end-of-options "${HOMEBREW_CORE_GIT_REMOTE}"
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git config fetch.prune true
git fetch --force origin
@@ -104,7 +104,8 @@ class GitDownloadStrategy < VCSDownloadStrategy
sig { returns(T::Boolean) }
def ref?
silent_command("git",
args: ["--git-dir", git_dir, "rev-parse", "-q", "--verify", "#{@ref}^{commit}"])
args: ["--git-dir", git_dir, "rev-parse", "-q", "--verify", "--end-of-options",
"#{@ref}^{commit}"])
.success?
end
@@ -145,7 +146,7 @@ class GitDownloadStrategy < VCSDownloadStrategy
args << "--config" << "advice.detachedHead=false" # Silences “detached head” warning.
args << "--config" << "core.fsmonitor=false" # Prevent `fsmonitor` from watching this repository.
args << @url << cached_location.to_s
args << "--end-of-options" << @url << cached_location.to_s
end
sig { returns(String) }
+1 -1
View File
@@ -124,7 +124,7 @@ module Homebrew
def self.ls_remote_tags(url)
stdout, stderr, _status = system_command(
"git",
args: ["ls-remote", "--tags", url],
args: ["ls-remote", "--tags", "--end-of-options", url],
env: { "GIT_TERMINAL_PROMPT" => "0" },
print_stdout: false,
print_stderr: false,
+1 -1
View File
@@ -281,7 +281,7 @@ module Homebrew
return unless url.to_s.end_with?(".git")
return unless Utils::Git.remote_exists?(url.to_s)
detected_branch = Utils.popen_read("git", "ls-remote", "--symref", url.to_s, "HEAD")
detected_branch = Utils.popen_read("git", "ls-remote", "--symref", "--end-of-options", url.to_s, "HEAD")
.match(%r{ref: refs/heads/(.*?)\s+HEAD})&.to_a&.second
if specs[:branch].blank?
+4 -4
View File
@@ -588,8 +588,7 @@ class Tap
clear_cache
end
# `--` guards against a redirect value that begins with `-` being treated as a `git` option.
safe_system "git", "-C", path, "remote", "set-url", "origin", "--", redirected_remote
safe_system "git", "-C", path, "remote", "set-url", "origin", "--end-of-options", redirected_remote
clear_cache
Tap.clear_cache
@@ -703,7 +702,7 @@ class Tap
Tap.clear_cache
$stderr.ohai "Tapping #{name}" unless quiet
args = %W[clone #{requested_remote} #{path}]
args = %w[clone]
# Override possible user configs like:
# git config --global clone.defaultRemoteName notorigin
@@ -714,6 +713,7 @@ class Tap
args << "--template="
# Prevent `fsmonitor` from watching this repository.
args << "--config" << "core.fsmonitor=false"
args << "--end-of-options" << requested_remote << path.to_s
begin
if worktree_source_tap_path
@@ -808,7 +808,7 @@ class Tap
def fix_remote_configuration(requested_remote: nil, quiet: false)
if requested_remote.present?
path.cd do
safe_system "git", "remote", "set-url", "origin", requested_remote
safe_system "git", "remote", "set-url", "origin", "--end-of-options", requested_remote
safe_system "git", "config", "remote.origin.fetch", "+refs/heads/*:refs/remotes/origin/*"
end
$stderr.ohai "#{name}: changed remote from #{remote} to #{requested_remote}" unless quiet
@@ -16,6 +16,26 @@ RSpec.describe GitDownloadStrategy do
FileUtils.mkpath cached_location
end
describe "#clone_args" do
it "terminates options before the URL" do
expect(strategy.send(:clone_args)).to end_with("--end-of-options", url, cached_location.to_s)
end
end
describe "#ref?" do
it "terminates options before the ref" do
expect(strategy).to receive(:silent_command)
.with(
"git",
args: ["--git-dir", cached_location/".git", "rev-parse", "-q", "--verify", "--end-of-options",
"master^{commit}"],
)
.and_return(instance_double(SystemCommand::Result, success?: true))
strategy.send(:ref?)
end
end
def git_commit_all
system "git", "add", "--all"
# Allow instance variables here to have nice commit messages.
@@ -891,13 +891,19 @@ RSpec.describe Homebrew::FormulaAuditor do
end
it "requires `branch:` to be specified for Git head URLs" do
head_url = "https://github.com/Homebrew/homebrew-test-bot.git"
fa = formula_auditor "foo", <<~RUBY, online: true
class Foo < Formula
url "https://brew.sh/foo-1.0.tgz"
sha256 "31cccfc6630528db1c8e3a06f6decf2a370060b982841cfab2b8677400a5092e"
head "https://github.com/Homebrew/homebrew-test-bot.git"
head "#{head_url}"
end
RUBY
allow(Utils::Git).to receive(:remote_exists?).and_return(true)
allow(Utils).to receive(:popen_read).and_call_original
expect(Utils).to receive(:popen_read)
.with("git", "ls-remote", "--symref", "--end-of-options", head_url, "HEAD")
.and_return("ref: refs/heads/main\tHEAD\n")
fa.audit_specs
# This is `.last` because the first problem is the unreachable stable URL.
@@ -183,6 +183,22 @@ RSpec.describe Homebrew::Livecheck::Strategy::Git do
end
describe "::ls_remote_tags" do
it "terminates options before the URL" do
expect(git).to receive(:system_command)
.with(
"git",
args: ["ls-remote", "--tags", "--end-of-options", "-u:evil"],
env: { "GIT_TERMINAL_PROMPT" => "0" },
print_stdout: false,
print_stderr: false,
debug: false,
verbose: false,
)
.and_return([nil, nil, nil])
git.ls_remote_tags("-u:evil")
end
it "returns the Git tags for the provided remote URL", :needs_network do
expect(git.ls_remote_tags(git_url)).not_to be_empty
end
+17 -2
View File
@@ -699,6 +699,21 @@ RSpec.describe Tap do
end
end
describe "#fix_remote_configuration" do
it "terminates options before the requested remote" do
tap = described_class.fetch("dashy", "foo")
tap.path.mkpath
allow(tap).to receive(:remote)
allow(tap).to receive(:safe_system)
expect(tap).to receive(:safe_system)
.with("git", "remote", "set-url", "origin", "--end-of-options", "-u:evil")
tap.fix_remote_configuration(requested_remote: "-u:evil")
ensure
FileUtils.rm_rf HOMEBREW_TAP_DIRECTORY/"dashy"
end
end
specify "Git variant" do
touch path/"README"
setup_git_repo
@@ -867,8 +882,8 @@ RSpec.describe Tap do
allow(tap).to receive_messages(command_files: [], formula_files: [], cask_files: [],
formula_names: [], cask_tokens: [], link_completions_and_manpages: nil)
expect(tap).to receive(:git_command!)
.with(["clone", requested_remote, tap.path.to_s, "--origin=origin", "--template=",
"--config", "core.fsmonitor=false"])
.with(["clone", "--origin=origin", "--template=", "--config", "core.fsmonitor=false",
"--end-of-options", requested_remote, tap.path.to_s])
.and_wrap_original do
tap.path.mkpath
(tap.path/".git").mkpath
+8
View File
@@ -228,6 +228,14 @@ RSpec.describe Utils::Git do
end
context "when git is available" do
it "terminates options before the URL" do
expect(described_class).to receive(:quiet_system)
.with("git", "ls-remote", "--end-of-options", "-u:evil")
.and_return(false)
described_class.remote_exists?("-u:evil")
end
it "returns true when git remote exists", :needs_network do
git = HOMEBREW_SHIMS_PATH/"shared/git"
url = "https://github.com/Homebrew/homebrew.github.io"
+1 -1
View File
@@ -53,7 +53,7 @@ module Utils
def self.remote_exists?(url)
return true unless available?
quiet_system "git", "ls-remote", url
quiet_system "git", "ls-remote", "--end-of-options", url
end
sig { void }