ITADN

git: enable Rust build support (drop NO_RUST=1) to match upstream defaults

#290963ClosedAaronMegs 创建于 2026-07-02
A
AaronMegscommented
# git: enable Rust build support (drop `NO_RUST=1`) to match upstream defaults ## Summary Since **Git 2.55**, Rust support is **enabled by default** in upstream Git's build system. The `Formula/g/git.rb` formula, however, is currently pinned to the legacy C-only configuration by passing **`NO_RUST=1`** to `make`. As a result Homebrew's `git` bottle ships **without** the memory-safe Rust subsystems that every default upstream build (and most other distributions moving to 2.55) now includes. This issue proposes enabling Rust in the formula so the bottle matches upstream defaults and is ready for **Git 3.0**, where Rust becomes a **mandatory, non-optional** build requirement. - Formula: `Formula/g/git.rb` - Current stable in formula: `git 2.55.0` - Offending line (in `install`): ```ruby args = %W[ ... NO_TCLTK=1 NO_RUST=1 # <-- opts out of upstream's default Rust build ] ``` - No `depends_on "rust"` is declared. ## Background: what changed upstream in 2.55 Git's build system reversed the Rust opt-in/opt-out polarity in 2.55. From the upstream `Makefile` (`v2.55.0`): ```make # == Optional Rust support == # # Define NO_RUST if you want to disable features and subsystems written in Rust # from being compiled into Git. For now, Rust is still an optional feature of # the build process. With Git 3.0 though, Rust will always be enabled. # # Building Rust code requires Cargo. ``` And the migration plan is documented explicitly in `Documentation/BreakingChanges.adoc` (`v2.55.0`): > There will be multiple milestones for the introduction of Rust: > 1. Initially, with Git 2.52, support for Rust will be auto-detected by Meson […] > 2. **In Git 2.55, both build systems will default-enable support for Rust.** > Consequently, builds will break by default if Rust is not available on the > build host. The use of Rust can still be explicitly disabled via build > options. > 3. **In Git 3.0, the build options will be removed and support for Rust is > [mandatory].** Key mechanical facts (verified against `v2.55.0` `Makefile`): - The old `WITH_RUST` knob was **renamed to `NO_RUST`** (semantics inverted: opt-in → opt-out). - When Rust is enabled, the build compiles the `gitcore` crate from `RUST_SOURCES`: ``` src/csum_file.rs src/hash.rs src/lib.rs src/loose.rs src/varint.rs ``` and links `-DWITH_RUST` + `$(RUST_LIB)` into `git`. - The Meson build sets `option('rust', type: 'feature', value: 'enabled')`. ## The concrete problem in `git.rb` There are two distinct issues: 1. **We opt out of the upstream default.** By passing `NO_RUST=1`, the Homebrew `git` is built from a configuration that upstream no longer builds by default and that will **cease to exist** at Git 3.0. When 3.0 lands, `NO_RUST=1` will be an *unrecognized/removed* option and the formula will need this change anyway — better to make the (small, safe) transition now, on our schedule, than under a hard deadline. 2. **A subtle correctness detail around `varint`.** The `NO_RUST` code path is *not* a pure no-op — it swaps implementations. In the `Makefile`: ```make ifdef NO_RUST LIB_OBJS += varint.o # C implementation endif ... RUST_SOURCES += src/varint.rs # Rust implementation (used when NO_RUST unset) ``` So today Homebrew ships the **C** `varint`; upstream's default 2.55 build ships the **Rust** `varint` (via `gitcore`). Enabling Rust aligns us with the implementation upstream actually tests and ships by default. ## Why enable it (impact on dependencies, performance, security) ### Dependencies - Adds a single **build-time-only** dependency: `depends_on "rust" => :build`. `rust` is already a well-maintained core formula (currently `1.96.0`), used as a build dep by many formulae, so this does not introduce a new runtime dep and does not change `git`'s runtime dependency graph or bottle linkage for end users. - No new *runtime* libraries: the Rust code is statically linked into `git` (`$(RUST_LIB)` → `libgitcore.a`), so there is no added `dylib` and no change to `otool -L`/`ldd` output for consumers. - Aligns Homebrew with other distributions that are declaring a Rust build dep for their 2.55 packaging cycle. ### Security (the primary upstream motivation) - The subsystems being migrated to Rust are exactly the historically memory-unsafe hot spots: object/loose-object handling (`loose.rs`), hashing and checksum streaming (`hash.rs`, `csum_file.rs`), and variable-length integer decoding (`varint.rs`). These parse untrusted, attacker-controllable repository data. - Rust's ownership/borrow model eliminates whole bug classes (buffer overflow, use-after-free, out-of-bounds reads) **at compile time** in these paths. Shipping the Rust build means Homebrew users get the memory-safety hardening upstream intends for the default build, rather than the legacy C path. ### Performance - Upstream frames 2.55 primarily as a **safety** milestone, not a performance one, and the migrated crates are designed as zero-/low-overhead replacements (`RUST_TARGET_DIR = target/release`, i.e. optimized). Expect **parity** on the migrated subsystems today, with headroom for future Rust-side optimizations (e.g. packfile/merge machinery) that Homebrew users would only receive if the Rust build is enabled. ### Future-proofing - Git 3.0 (targeted late 2026) removes the opt-out entirely. Making git's bottle Rust-enabled now de-risks the 3.0 bump: the `depends_on "rust"` machinery and bottle rebuild will already be proven. ## Proposed fix 1. Add `depends_on "rust" => :build`. 2. Remove `NO_RUST=1` from the `make` args (let upstream default enable Rust). 3. Add a `test do` assertion that the produced binary actually links the Rust subsystems, to guard against a silent regression back to a `NO_RUST` build. A Rust-enabled 2.55 binary reports this via `git version --build-options`: ``` $ git version --build-options git version 2.55.0 ... rust: enabled # <-- present only when built without NO_RUST ... ``` A PR implementing exactly this is attached (see the linked PR). The diff is minimal and touches only `Formula/g/git.rb`. ## Notes / prior art - Upstream already fixed a related edge case for building the macOS keychain helper *without* Rust (`js/osxkeychain-build-wo-rust`, merged for 2.55) — a reminder that the C-only path is increasingly a special case rather than the default. - The `contrib/credential/osxkeychain` helper that this formula builds separately is unaffected by enabling Rust for the main build; it continues to build with the same `args` (now without `NO_RUST`). ## Checklist - [x] Verified against upstream `v2.55.0` `Makefile`, `meson_options.txt`, and `Documentation/BreakingChanges.adoc`. - [x] Confirmed `rust` formula is available as a build dependency. - [x] Built `git 2.55.0` from source with Rust enabled locally (rustc/cargo 1.96.0) — build succeeds, links `target/release/libgitcore.a`, and `git version --build-options` reports `rust: enabled`. - [ ] `brew install --build-from-source git` + `brew test git` on a CI runner (bottle rebuild).
关闭于 2026-07-02 1 条评论