diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index a849031497..7deeee8da4 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -3,7 +3,7 @@ # HOMEBREW_API_DOMAIN, HOMEBREW_CURLRC, HOMEBREW_DEBUG, HOMEBREW_DEVELOPER, HOMEBREW_GIT_EMAIL, HOMEBREW_GIT_NAME, # HOMEBREW_GITHUB_API_TOKEN, HOMEBREW_NO_ENV_HINTS, HOMEBREW_NO_INSTALL_CLEANUP, HOMEBREW_NO_INSTALL_FROM_API, # HOMEBREW_UPDATE_TO_TAG are from the user environment -# HOMEBREW_LIBRARY, HOMEBREW_PREFIX, HOMEBREW_REPOSITORY are set by bin/brew +# HOMEBREW_LIBRARY, HOMEBREW_PREFIX, HOMEBREW_REPOSITORY, HOMEBREW_USER_SET_VARS are set by bin/brew # HOMEBREW_API_DEFAULT_DOMAIN, HOMEBREW_AUTO_UPDATE_CASK_TAP, HOMEBREW_AUTO_UPDATE_CORE_TAP, # HOMEBREW_AUTO_UPDATE_SECS, HOMEBREW_BREW_DEFAULT_GIT_REMOTE, HOMEBREW_BREW_GIT_REMOTE, HOMEBREW_CACHE, # HOMEBREW_CASK_REPOSITORY, HOMEBREW_CELLAR, HOMEBREW_CORE_DEFAULT_GIT_REMOTE, HOMEBREW_CORE_GIT_REMOTE, @@ -713,7 +713,8 @@ EOS git_init_if_necessary - if [[ "${HOMEBREW_BREW_DEFAULT_GIT_REMOTE}" != "${HOMEBREW_BREW_GIT_REMOTE}" ]] + if [[ "${HOMEBREW_BREW_DEFAULT_GIT_REMOTE}" != "${HOMEBREW_BREW_GIT_REMOTE}" || + " ${HOMEBREW_USER_SET_VARS} " == *" HOMEBREW_BREW_GIT_REMOTE "* ]] then safe_cd "${HOMEBREW_REPOSITORY}" echo "HOMEBREW_BREW_GIT_REMOTE set: using ${HOMEBREW_BREW_GIT_REMOTE} as the Homebrew/brew Git remote." >&2 @@ -724,7 +725,8 @@ EOS fi if [[ -d "${HOMEBREW_CORE_REPOSITORY}" ]] && - [[ "${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}" != "${HOMEBREW_CORE_GIT_REMOTE}" ]] + [[ "${HOMEBREW_CORE_DEFAULT_GIT_REMOTE}" != "${HOMEBREW_CORE_GIT_REMOTE}" || + " ${HOMEBREW_USER_SET_VARS} " == *" HOMEBREW_CORE_GIT_REMOTE "* ]] then safe_cd "${HOMEBREW_CORE_REPOSITORY}" echo "HOMEBREW_CORE_GIT_REMOTE set: using ${HOMEBREW_CORE_GIT_REMOTE} as the Homebrew/homebrew-core Git remote." >&2 diff --git a/Library/Homebrew/test/cmd/update_spec.rb b/Library/Homebrew/test/cmd/update_spec.rb index ee6dc8bb7f..4e297d9454 100644 --- a/Library/Homebrew/test/cmd/update_spec.rb +++ b/Library/Homebrew/test/cmd/update_spec.rb @@ -51,6 +51,62 @@ RSpec.describe Homebrew::Cmd::Update do expect([status.success?, stdout]).to eq([false, ""]) end + test_each([ + ["explicit brew default", "HOMEBREW_BREW_GIT_REMOTE", "https://github.com/Homebrew/brew", "mirror/core"], + ["explicit core default", "HOMEBREW_CORE_GIT_REMOTE", "mirror/brew", "https://github.com/Homebrew/homebrew-core"], + ["implicit defaults", "", "mirror/brew", "mirror/core"], + ["non-default remotes", "", "other/brew", "other/homebrew-core"], + ].product(["", "--auto-update"])) do |(description, user_set_vars, brew_remote, core_remote), option| + it "honours #{description} during update #{option}" do + setup_update_utils + FileUtils.ln_s repository_root/"Library/Homebrew/shims", test_root/"Library/Homebrew/shims" + (test_root/"core").mkpath + remote_base = (description == "non-default remotes") ? "other" : "https://github.com/Homebrew" + + _stdout, stderr, status = run_update_shell( + <<~SH, + source "#{update_script}" + git() { + case "$*" in + fetch*) return 0 ;; + "config --local --get remote.origin.url") + "#{Utils::Git.git}" -C "#{test_root}" remote get-url origin > "#{test_root}/remotes" + "#{Utils::Git.git}" -C "#{test_root}/core" remote get-url origin >> "#{test_root}/remotes" + exit + ;; + esac + "#{Utils::Git.git}" "$@" + } + for repository in "#{test_root}" "#{test_root}/core" + do + git -C "${repository}" init -q + done + git -C "#{test_root}" remote add origin mirror/brew + git -C "#{test_root}/core" remote add origin mirror/core + lock() { :; } + homebrew-update #{option} + SH + { + "HOMEBREW_BREW_DEFAULT_GIT_REMOTE" => "https://github.com/Homebrew/brew", + "HOMEBREW_BREW_GIT_REMOTE" => "#{remote_base}/brew", + "HOMEBREW_CORE_DEFAULT_GIT_REMOTE" => "https://github.com/Homebrew/homebrew-core", + "HOMEBREW_CORE_GIT_REMOTE" => "#{remote_base}/homebrew-core", + "HOMEBREW_CORE_REPOSITORY" => (test_root/"core").to_s, + "HOMEBREW_FORCE_BREWED_CA_CERTIFICATES" => nil, + "HOMEBREW_FORCE_BREWED_CURL" => nil, + "HOMEBREW_FORCE_BREWED_GIT" => nil, + "HOMEBREW_LIBRARY" => (test_root/"Library").to_s, + "HOMEBREW_NO_INSTALL_FROM_API" => "1", + "HOMEBREW_REPOSITORY" => test_root.to_s, + "HOMEBREW_USER_SET_VARS" => user_set_vars, + }, + ) + + expect([status.success?, (test_root/"remotes").read]).to eq([true, "#{brew_remote}\n#{core_remote}\n"]), + stderr + end + end + it "installs Git when the Git wrapper cannot find an executable" do setup_update_utils (test_root/"Library/Homebrew/shims/shared").mkpath diff --git a/docs/Installation.md b/docs/Installation.md index 4da370cf8d..98a7c0da96 100644 --- a/docs/Installation.md +++ b/docs/Installation.md @@ -138,7 +138,15 @@ export HOMEBREW_CORE_GIT_REMOTE="..." # put your Git mirror of Homebrew/homebre /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" ``` -The default Git remote will be used if the corresponding environment variable is unset and works best for most users. +During installation, the default Git remote will be used if the corresponding environment variable is unset and works best for most users. +After installation, `brew update` preserves the configured remotes when these variables are unset. +To reset existing repositories to the default Git remotes, set the URLs explicitly: + +```bash +HOMEBREW_BREW_GIT_REMOTE="https://github.com/Homebrew/brew" \ +HOMEBREW_CORE_GIT_REMOTE="https://github.com/Homebrew/homebrew-core" \ + brew update +``` **Note:** if you set these variables you are granting these repositories the same level of trust you currently grant to Homebrew itself. You should be extremely confident that these repositories will not be compromised.