Skip to content

Fix git_repository checkouts altered by host line-ending config - #30036

Open
rdesgroppes wants to merge 1 commit into
bazelbuild:masterfrom
rdesgroppes:git-repository-line-endings
Open

Fix git_repository checkouts altered by host line-ending config#30036
rdesgroppes wants to merge 1 commit into
bazelbuild:masterfrom
rdesgroppes:git-repository-line-endings

Conversation

@rdesgroppes

@rdesgroppes rdesgroppes commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Description

The present fix proposes to pin both knobs for every git invocation in git_worker.bzl's _execute with both -c core.autocrlf=false and -c core.eol=lf.
A -c override outranks every config source (~/.gitconfig, /etc/gitconfig, $XDG_CONFIG_HOME/git/config, ...) and works on git 1.7.2+.

The checkout then reproduces the committed bytes:

  • LF stays LF,
  • an in-tree .gitattributes still wins so a repo keeping CRLF via eol=crlf is preserved,
  • a CRLF blob is never stripped (the checkout path only ever adds CR, never removes it).

This is not neutralizing config sources:

  • GIT_CONFIG_NOSYSTEM=1 would only drop /etc/gitconfig, not the user's ~/.gitconfig,
  • GIT_CONFIG_GLOBAL and GIT_CONFIG_SYSTEM (set to /dev/null) need git 2.32+,
  • worse, both of the above would wipe corresponding system-wide and user-specific configs, including environment-sensitive settings such as core.symlinks, credential.helper, http.proxy, etc.

The -c overrides touch only the two line-ending knobs.

There are 2 new black box tests that neutralize, in isolation, an injected host core.autocrlf (from $HOME/.gitconfig) and core.eol (from a GIT_CONFIG_SYSTEM file), asserting the checkout is byte-for-byte without shadowing corresponding in-tree .gitattributes settings.

Motivation

Fixes #30026.

git_repository and new_git_repository shell out to the system git, so their checkout inherits the host's git configuration. core.autocrlf and core.eol then rewrite line endings on checkout: with autocrlf=true (the Git for Windows default), a repository stored with LF is materialized with CRLF on one machine and LF on another, so a fetch is not reproducible and byte-sensitive rules break.

This pushes teams to fall back to http_archive, but that workaround doesn't of course apply to transitive bazel_deps.

Build API Changes

No

Checklist

  • I have added tests for the new use cases (if any).
  • I have updated the documentation (if applicable).

Release Notes

RELNOTES: git_repository and new_git_repository now check out files with the line endings stored in the repository, regardless of the host git configuration (core.autocrlf, core.eol).

@rdesgroppes
rdesgroppes force-pushed the git-repository-line-endings branch from f3549ee to 44c9547 Compare June 26, 2026 13:26
@rdesgroppes
rdesgroppes force-pushed the git-repository-line-endings branch 4 times, most recently from 4a7b2e3 to 2d7b879 Compare June 26, 2026 17:09
@rdesgroppes rdesgroppes changed the title Fix git_repository checkout depending on host line-ending config Fix git_repository checkouts altered by host line-ending config Jun 26, 2026
@rdesgroppes
rdesgroppes marked this pull request as ready for review June 26, 2026 17:14
@github-actions github-actions Bot added the awaiting-review PR is awaiting review from an assigned reviewer label Jun 26, 2026
`git_repository` and `new_git_repository` shell out to the system git,
so their checkout inherits the host's git configuration.
`core.autocrlf` and `core.eol` then rewrite line endings on checkout:
with `autocrlf=true` (the Git for Windows default), a repository stored
with LF is materialized with `CRLF` on one machine and `LF` on another,
so a fetch is not reproducible and byte-sensitive rules break.

This pushes teams to resort to falling back to `http_archive`, but that
workaround doesn't of course apply to transitive `bazel_dep`s.

The present fix proposes to pin both knobs for every `git` invocation in
`git_worker.bzl`'s `_execute` with both `-c core.autocrlf=false` and
`-c core.eol=lf`.
A `-c` override outranks every config source (`~/.gitconfig`,
`/etc/gitconfig`, `$XDG_CONFIG_HOME/git/config`, ...) and works on git
1.7.2+.

The checkout then reproduces the committed bytes:
- `LF` stays `LF`,
- an **in-tree `.gitattributes` still wins** so a repo keeping `CRLF`
  via `eol=crlf` is preserved,
- a `CRLF` blob is never stripped (the checkout path only ever adds
  `CR`, never removes it).

This is **not** neutralizing config sources:
- `GIT_CONFIG_NOSYSTEM=1` would only drop `/etc/gitconfig`, not the
  user's `~/.gitconfig`,
- `GIT_CONFIG_GLOBAL` and `GIT_CONFIG_SYSTEM` (set to `/dev/null`) need
  git 2.32+,
- worse, both of the above would wipe corresponding system-wide and user
  configs,   including environment-sensitive settings such as
  `core.symlinks`, `credential.helper`, `http.proxy`, etc.

The `-c` overrides touch only the two line-ending knobs.

There are 2 new black box tests that neutralize, in isolation, an
injected host `core.autocrlf` (from `$HOME/.gitconfig`) and `core.eol`
(from a `GIT_CONFIG_SYSTEM` file), asserting the checkout is
byte-for-byte without shadowing corresponding in-tree `.gitattributes`
settings.

Fixes bazelbuild#30026

RELNOTES: `git_repository` and `new_git_repository` now check out files
with the line endings stored in the repository, regardless of the host
git configuration (`core.autocrlf`, `core.eol`).
@rdesgroppes
rdesgroppes force-pushed the git-repository-line-endings branch from 2d7b879 to 0faabaf Compare June 29, 2026 07:06
@iancha1992 iancha1992 added the team-Core Skyframe, bazel query, BEP, options parsing, bazelrc label Jun 30, 2026
@bazel-docs-pr-commenter

Copy link
Copy Markdown

✅ Bazel docs preview is ready!

Preview URL: https://bazel-pr-30036.mintlify.app/

Updated for 0faabafe580979db81bda7b89985b68bb8965e2b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-review PR is awaiting review from an assigned reviewer team-Core Skyframe, bazel query, BEP, options parsing, bazelrc

Projects

None yet

Development

Successfully merging this pull request may close these issues.

git_repository checkout is non-hermetic w.r.t. host core.autocrlf/core.eol

3 participants