- A plain `brew upgrade` raised "It seems there is already a
Binary at ..." even when the existing symlink resolved to the
exact source about to be linked, because the realpath check sat
behind `force`/`adopt`. The revert left the symlink in place so
every retry failed identically until manual intervention.
- Treat an already-correct symlink as a no-op: log and skip the
link. Genuine conflicts, such as a real file at the target or a
symlink elsewhere, still require `--force` or `--adopt`.
- Rescue errors resolving the target, like `conflicting_formula`
does, so unreadable symlinks fall back to the existing conflict
and error handling instead of raising `Errno` exceptions.
- FixesHomebrew/brew#23426.
- Landlock needs no separate executable, installation or `sysctl`
configuration, so use it as the only Linux sandbox implementation
rather than an opt-in behind `$HOMEBREW_SANDBOX_LINUX_LANDLOCK`.
- Delete `Sandbox::Bubblewrap`, the `brew setup-sandbox` command and
the implicit `bubblewrap` dependency, none of which Landlock needs.
- Remove the Bubblewrap-era `Sandbox` API (`ensure_sandbox_installed!`,
`configure!`, `configuration_commands`, `sandbox_install_command`)
and its call sites now that no backend needs installing or
configuring.
- Simplify `brew doctor`'s `check_linux_sandbox` to report the
Landlock failure reason with the `$HOMEBREW_NO_SANDBOX_LINUX`
workaround.
- Since #23312, `brew services start` always regenerated the service
definition from the formula `service` block. Formulae that bundle
their own service file only declare `name` there, so the generated
plist had empty `ProgramArguments` and `launchctl bootstrap` failed
with `Input/output error`.
- Read the installed service file instead unless the `service` block
defines a command, the same gate `FormulaInstaller#install_service`
uses when writing generated service files into the keg.
- Fixes https://github.com/Homebrew/brew/issues/23408.
- `brew bump` reported formulae as up to date when a newer upstream
release was suppressed by the release cooldown, confusing upstream
authors waiting for autobump.
- Show the suppressed version with how recently it was released, add
a `Bump-ready version:` line for what can be bumped now and change
the headline from `is up to date!` to `has a new version in
release cooldown`.
- Fixes#23396.
- Drop the status write that fork pull requests cannot receive.
- Pin the `2026.08.03.2` action release that fails validation jobs.
- Report the required check for synthetic merge queue commits.
- After #23381, homebrew-core CI fails installing dependencies on
version-bump PRs: the bumped formula's stale bottle block derives
its manifest URL from the new version, whose bottle has not been
published yet, and `DownloadQueue#fetch` treats every bottle
manifest failure as fatal.
- Before that change the default ask-mode plan fetched manifests
synchronously via `Formula#fetch_bottle_tab`, which rescues
download errors so dependency resolution falls back to a full
install, and the installer's memoisation then kept the queue from
retrying the download.
- Add `DownloadQueue#fetch(allow_failures:)`: failed downloads are
still reported but neither raise nor mark the fetch or run as
failed. Use it for the metadata-only drains (`fetch_formulae`'s
bottle manifest waits, `brew install`'s ask-mode drain and
`brew upgrade`'s tab prefetch), restoring the synchronous path's
tolerance. Manifest failures in fetches that pour bottles remain
fatal.
`brew info --installed --json=v2` emits `==> Downloading Homebrew API
data` to stdout when the API data needs (re)downloading, corrupting
the JSON for anything parsing it (e.g. piping to `jq`).
The heading was added in 284cd0ed4c (#23381) as an unconditional
`oh1`, regressing the intent of 43137fe877 (#20980), which moved the
queue's non-TTY per-download report lines to stderr for exactly this
reason. Print the heading to stderr when stdout is not a TTY so it
stays off parsed stdout and on the same stream as those report lines.
TTY behaviour is unchanged.
Use `$stderr.puts oh1_title(...)` rather than `$stderr.oh1` as
RSpec's `to_stderr` matcher replaces `$stderr` with a plain
`StringIO` that lacks the `Utils::Output::Mixin` extension.
- `brew install` only started network transfers after preinstall
checks and, in ask mode, fetched each bottle manifest serially
while computing the dry-run plan.
- Enqueue bottle manifests on the shared download queue right after
building formula installers in both ask and no-ask modes so
transfers overlap preinstall checks and dependant scanning and
manifests for multiple formulae download concurrently. Ask mode
drains them under a `Downloading bottle manifests` heading before
printing the plan; warm runs enqueue nothing and stay silent.
- Once downloads are confirmed (`--yes` installs, reinstall, upgrade
and other `Install.fetch_formulae` callers), also enqueue the
formula's own bottle in `FormulaInstaller#prelude_fetch`: the blob
URL needs neither the manifest nor dependency resolution, so both
transfer concurrently and staging joins the same queue cycle.
- Skip the `enqueue_fetch` requeue for bottles the prelude fetch
already enqueued so a completed early download is not reported a
second time.
- Give `DownloadQueue#fetch` `only:` and `heading:` so a heading is
always printed before any queue output and never for empty fetches:
dependency resolution inside `Install.fetch_formulae` waits on just
the bottle manifests it needs (under `Downloading bottle manifests`)
and the cask source pre-fetch on just its cask files, keeping other
in-flight downloads queued and unreported so bottles only ever
appear under the `Fetching downloads for:` heading, which now
prints lazily from the fetch that reports them (`brew upgrade`
enqueues before it knows that heading's contents). This replaces
`Install.show_combined_fetch_downloads_heading`, `brew upgrade`'s
manual manifest heading predicate and its dead
`show_downloads_heading` plumbing.
- Instrument `Install.perform_preinstall_checks_once` as a
`preinstall_checks` phase timing to keep the reordering visible.
- Archive-cold `brew install hello`: the first transfer starts at
~375ms instead of ~442ms, the bottle no longer waits for the
manifest round trip (~672ms before, ~375ms now) and `--yes` wall
time drops around 30%. Two-formula ask-mode installs drop one full
manifest round trip (~1240ms to ~1030ms).