mirror of
https://github.com/NixOS/nixpkgs.git
synced 2026-06-13 08:43:41 +00:00
fetchgit: disable git maintenance
By default, Git commands will trigger background processes to perform repository maintenance. As of Git v2.54.0, and in particular as of 452b12c2e0 (builtin/maintenance: use "geometric" strategy by default, 2026-02-24), Git has changed the strategy it uses to decide whether maintenance needs performing, and as a result will kick off background maintenance processes much more often. These background processes will potentially change the contents of the `.git` directory while `nix-prefetch-git` is deleting it. This results in effectively random failures, when files are added to the `.git` directory during the `rm -rf` operation (causing it to fail) or after the operation has completed (causing the `.git` directory to be recreated and resulting in a FOD hash mismatch). This also causes problems for the determinism of Git's own tests. They've resolved this in 09505b1115 (t: fix races caused by background maintenance, 2026-02-24) by having the maintenance processes run in the foreground. The discussion in that commit explains they considered just disabling maintenance entirely, but opted for the foreground option because disabling maintenance would mean the tests looked even less like how most Git users work with Git. `nix-prefetch-git` is nothing like most Git users. In almost every case, the `.git` directory will be deleted during or immediately after the script is called. The repositories certainly don't benefit from ongoing maintenance. To avoid the non-determinism created by the background maintenance processes, just disable maintenance entirely. This is done with `git config` after initialising the repository, rather than `git config --global` earlier in the script, as `git config --global` will fail if `fetchgit` was called with a `gitConfig` argument. It would be possible to set this option with `GIT_CONFIG_[COUNT|KEY_<n>|VALUE_<n>]` environment variables; I've opted against that because (a) they're less familiar to most people who might want to come to edit this script in future and (b) because if someone is using those values themselves via `impureEnvVars` or similar, making our configuration play nicely with someone else's would require some fairly complex logic. I haven't made this a configurable option: any use of `nix-prefetch-git` will run with maintenance disabled, as I cannot think of a use case where it would be useful. If there is such a use case, it would be straightforward to extend `nix-prefetch-git` and `fetchgit` to allow users to change the behaviour. Fixes #524215.
This commit is contained in:
@@ -123,6 +123,10 @@ fi
|
||||
init_remote(){
|
||||
local url=$1
|
||||
clean_git init --initial-branch=master
|
||||
# Disable maintenance: it's not useful for a short-lived clone, and
|
||||
# background maintenance causes non-deterministic builds.
|
||||
# https://github.com/NixOS/nixpkgs/issues/524215
|
||||
clean_git config maintenance.auto false
|
||||
clean_git remote add origin "$url"
|
||||
if [ -n "$sparseCheckout" ]; then
|
||||
git config remote.origin.partialclonefilter "blob:none"
|
||||
|
||||
Reference in New Issue
Block a user