135 Commits

Author SHA1 Message Date
Philip Taron 5b5c421f52 nix-prefetch-git: also disable legacy auto-gc
Commit 88cfc54552 ("nix-prefetch-git: disable maintenance mode via
environment variables") disabled maintenance.auto (git's new
auto-maintenance) via GIT_CONFIG_*, which propagates to submodules. But
the legacy auto-gc path (gc.auto plus detached gc.autoDetach) is still
enabled, and it keeps repacking .git/modules/<sub>/objects after a nested
submodule reports "checked out", racing the later `rm -rf .git`:

- rm empties objects/pack, the detached gc drops a fresh pack in, and
  rmdir fails with "Directory not empty" (exit 123); or
- removal partially completes, leaving varying .git remnants, yielding a
  non-deterministic NAR hash.

Disable gc.auto/gc.autoDetach alongside maintenance.auto, using the same
GIT_CONFIG_* mechanism so the settings reach every git invocation and its
children (including nested submodule fetches). Fold the repeated
boilerplate into a small git_config_env helper.

The successful output is unchanged (.git is removed either way), so
pinned fetchgit hashes stay valid; this only makes removal deterministic.

Fixes #524215.

Assisted-by: Claude Code (claude-opus-4-8)
2026-06-11 08:25:04 -07:00
Pratham Patel 88cfc54552 nix-prefetch-git: disable maintenance mode via environment variables
The commit 011471c7f2 ("fetchgit: disable git maintenance") disabled
git's maintenance mode, but that does not affect git repositories with
submodules.

Switch to using the GIT_CONFIG_* environment variables. This is done in
a way to make the approach more generic, but also kinda not the best
("insane") so that it works with any future change, even with
`impureEnvVars`.

Maybe `git -c maintenance.auto=false` can work but I cannot figure out
how to use that here. I would prefer disabling maintenance mode in Git's
derivation itself but did not find any build-time knob to toggle that.
2026-05-28 22:43:24 +05:30
Adam Dinwoodie 011471c7f2 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.
2026-05-26 13:43:37 +01:00
Yueh-Shun Li 09030960d5 nix-prefetch-git: restore the tag-related clone flags when leaving .git
When leaveDotGit == true,
restore the cloning behaviour before
commit 7e085677f9 ("nix-prefetch-git: dont't fetch tags when deep clone unless leaving .git")
to preserve the fragile hashes of .git sources.

Clean up fetchTagsCompat,
as fetchTagsCompat is no longer needed
after restoring the old tag-fetching flags.
2025-12-24 21:59:46 +08:00
Yueh-Shun Li 62b2dbef68 nix-prefetch-git: Name FETCHED_HEAD "$ref" only for refs/tags/* 2025-12-23 04:50:05 +08:00
Yueh-Shun Li 7e085677f9 nix-prefetch-git: dont't fetch tags when deep clone unless leaving .git
Co-authored-by: Adam Dinwoodie <adam@dinwoodie.org>
2025-12-17 01:19:43 +08:00
Yueh-Shun Li d4dd261ab5 nix-prefetch-git: fetch the fetching tag for NIX_PREFETCH_GIT_CHECKOUT_HOOK
Co-authored-by: Adam Dinwoodie <adam@dinwoodie.org>
2025-12-17 01:14:55 +08:00
Alexander Bantyev f12f3dfb21 nix-prefetch-git: add --no-add-path argument
Adds a new argument to `nix-prefetch-git`: `--no-add-path`. It disables
adding the path to the store. It is useful when working with a read-only
store.
2025-09-24 22:18:32 +04:00
Philip Taron 754ee2fc40 fetchgit: Add rootDir argument (#427165) 2025-08-10 17:38:43 -07:00
Yuriy Taraday 3985afc65c nix-prefetch-git: Add --root-dir argument
With this argument nix-prefetch-git will make a subdirectory of the Git
repository a root of the resulting store path. This is helpful for
dealing with monorepos where many projects are in separate directories
and don't need a new source hash every time the monorepo is updated.

The corresponding fetchgit change follows.
2025-08-08 16:20:05 +02:00
Ryan Hendrickson a3947d986f tor: add tor.proxyHook
tor.proxyHook is a setup hook intended for use with HTTP-based fetchers,
enabling them to download from .onion addresses using Tor as a proxy.
2025-07-24 13:25:04 -04:00
Jared Baur 5cd869caa4 fetchgit: pass --checkout when fetching submodules
For projects that have `submodule.$name.update` set to something other
than the default value of "checkout", this change will ensure those
submodules are fetched as well.
2025-07-16 22:13:22 -07:00
Tim Black 1247031689 pkgs/build-support/fetchgit: add fetchTags parameter
Added fetchTags feature to fetchgit, explicit and clear support for
fetching all tags after the source tree fetch completes. Doing this at
build-time in the fetcher is required for packages that invoke commands
like 'git describe' which require tags, and since the nix store is
read-only by design, it is not possible to git fetch --tags at
activation- or run-time. This feature may have been possible by
specifying a postFetch option including calling git fetch --tags,
however doing so obfuscates the solution to this very real problem.
Explicit support for fetching tags should be a first class citizen just
like fetching other refs.
2025-05-28 16:47:34 -07:00
Valentin Gagarin c59a777a97 nix-prefetch-git: add --name parameter
This allows tools like `npins` to avoid re-downloading pre-fetched sources at evaluation time,
by setting the same symbolic store path name as `builtins.fetchGit` does,
and would make hacks such as [0] obsolete.

Historical note: `builtins.fetchGit` was introduced in 2016 [1] and
released in 2018 [2]. Before that, there was only the Nixpkgs `fetchgit`,
and the convention for using constant store path names [3] was not established yet [4].

While arguably in retrospect store path names were a mistake, we cannot
undo it here even partially by setting them to a constant, as it would invalidate
countless fixed-output derivations and thus incur an increase in
resource consumption and potentially a large number of build failures.

[0]: https://github.com/andir/npins/commit/f0449d090cd4cbf17849d29821a53ead9a88c42a
[1]: https://github.com/nixos/nix/commit/38539b943a060d9cdfc24d6e5d997c0885b8aa2f
[2]: https://github.com/NixOS/nix/releases/tag/2.0
[3]: https://github.com/NixOS/nix.dev/blob/db00265e810b3729a1077a0e5f8f4112f49019af/source/guides/best-practices.md#L263-L264
[4]: https://github.com/NixOS/nixpkgs/commit/a8603605aaaf780aa45edd0f16c8c9588455ccf2
2025-04-15 12:10:00 +02:00
Jonathan del Strother 6cb8c5ec01 build-support: Simplify tmpdir creation with coreutils
macOS 10.12 doesn't have a usable --tmpdir flag on the builtin mktemp, but we can
make use of coreutil's mktemp instead.
2024-11-25 09:41:02 +00:00
Jonathan del Strother 0c3d16a7d5 build-support: fix nix-prefetch-* on macOS
Since nix 2.20, `nix-store --add-fixed` doesn't accept paths where the
parent directory is a symlink. On macOS, /tmp is a symlink to
/private/tmp, which causes a "'/tmp' is a symlink" error:

```
$ nix run github:nixos/nixpkgs/24.11-beta#nix-prefetch-git -- --url https://github.com/IFTTT/polo.git --rev 316aa2ac210a45a7fc400ab921831493d5dd21b8 --hash sha256
Initialized empty Git repository in /private/tmp/git-checkout-tmp-1Bf9bIv7/polo-316aa2a/.git/
remote: Enumerating objects: 51, done.
remote: Counting objects: 100% (51/51), done.
remote: Compressing objects: 100% (42/42), done.
remote: Total 51 (delta 8), reused 19 (delta 5), pack-reused 0 (from 0)
Unpacking objects: 100% (51/51), 19.57 KiB | 541.00 KiB/s, done.
From https://github.com/IFTTT/polo
 * branch            HEAD       -> FETCH_HEAD
Switched to a new branch 'fetchgit'
removing `.git'...
error: path '/tmp' is a symlink
```

Avoid this by resolving /tmp to a real directory in all the prefetch scripts
2024-11-25 09:32:14 +00:00
thomasjm 4f13c7cc7b nix-prefetch-git: fix error in home folder cleanup 2024-10-23 03:24:02 -07:00
Tim Cuthbertson 911aa1440f treewide: support NIX_SSL_CERT_FILE as an impureEnvVar
This envvar is also added to lib.proxyImpureEnvVars since it's
typically required for https proxies.

This change also updates fetchgit and go module fetching to use this
envvar. NIX_GIT_SSL_CAINFO is still supported for backwards
compatibility in fetchgit.
2024-08-23 21:34:22 +10:00
Scott Worley 697bba9892 fetchgit: Support fetching signed tags over dumb http transport 2024-04-22 02:16:02 +02:00
linsui 1ed37ac9f3 fetchgit: set http.proxy globally for submodules
git config in the repo doesn't work for submodules
2024-03-21 19:14:00 +08:00
SharzyL b186e2d76e nix-prefetch-git: make it quiet
Some programs (e.g. nvfetcher) parse the output of nix-prefetch-git as
JSON. However, there is a pushd/popd command in nix-prefetch-git that
outputs the directory name, breaking the structure of the result JSON.
We suppressed it with `>/dev/null`.

Passingly fixes a mixuse of tab and spaces.
2023-11-12 15:20:16 +01:00
Elliot Cameron 3a99d1b642 nix-prefetch-git: respect NETRC
This script needs to support being run both as part of a `fetchgit`
derivation and as a standalone, command-line tool.

The use of `$NIX_BUILD_TOP` only works when used in `fetchgit` but not when
invoked as a standalone tool. Instead we try to respect `$NETRC` so that
the command-line invocation behaves more like standard tools and the
`fetchgit` derivation can explicitly set `$NETRC` when `netrcPhase` is used
to avoid all ambiguity.
2023-11-11 19:34:54 +01:00
Shogo Takata d6e1c7cae6 fetchgit: shallow clone for submodules (#254172) 2023-11-09 04:32:13 +02:00
K900 fa40d6457a nix-prefetch-git: download submodules with --progress 2023-11-05 20:49:03 +03:00
Domen Kožar 3c6cf39435 Merge pull request #249733 from Aleksanaa/nix-prefetch-git
nix-prefetch-git: fix make_deterministic_repo in submodules
2023-10-16 11:12:11 +01:00
Sandro Jäckel d09cd1d7d1 fetchgit: use $NIX_BUILD_TOP instead of hardcoding /build/
Co-authored-by: Bjørn Forsman <133602+bjornfor@users.noreply.github.com>
2023-10-08 00:10:59 +02:00
Sandro Jäckel 025a028c47 fetchgit: fix private fetching via netrc
This fixes a regression introduced in https://github.com/NixOS/nixpkgs/pull/256628
which broke fetching with private = true through a netrc file.
Tested locally with a really special github enterprise.
2023-10-05 13:54:00 +00:00
Alyssa Ross 7d40fbbc04 nix-prefetch-git: ignore global and user git config
nix-prefetch-git is either run as part of a build, usually sandboxed,
or outside a build, unsandboxed, to prefetch something that will later
be used in a build.  It's important that the latter use produces
hashes that can be reproduced by the former.

One way that they can differ is if the user's git config does
something that changes the result of git clone.  I ran into this,
because my global git config automatically enables git-lfs, whereas
nix-prefetch-git otherwise only uses git-lfs if specifically
requested.  This led to very confusing hash mismatches.
2023-09-22 06:59:40 +00:00
Silvan Mosberger 7cbc8215fd Merge pull request #252865 from emily-is-my-username/fix/fetchgit-deepclone
`fetchgit`: don't shallow clone if `deepClone` is requested
2023-09-06 14:08:06 +02:00
aleksana 981754aba8 nix-prefetch-git: fix make_deterministic_repo in submodules 2023-08-31 18:25:06 +08:00
PedroHLC ☭ 0142902fc4 nix-prefetch-git: add sri-hash to output 2023-07-09 14:46:58 -03:00
Emily ad94541662 fetchgit: don't shallow clone if deepClone is requested
fixes: https://github.com/NixOS/nixpkgs/issues/179788
2023-07-01 00:10:26 +02:00
Mario Rodas 922d55bf2d fetchgit: add a default NIX_BUILD_CORES variable
NIX_BUILD_CORES might not be defined at runtime, so the command would
fail.
2023-06-24 04:20:00 +00:00
Domen Kožar 4f72b6af8b fetchgit: fetch submodules in parallel 2023-06-20 10:36:10 +01:00
fetsorn 29f3903f62 nix-prefetch-git: fix typo 2023-05-31 04:00:32 +04:00
Ryan Hendrickson 0f6712d45a nix-prefetch-git: redirect git lfs to stderr 2023-05-21 09:05:49 +02:00
Winter dbd18a63a7 fetchgit: allow disabling cone mode for sparse checkouts, fix test 2022-08-14 23:03:07 +02:00
Sebastian Jordan 783e2ef46e Revert "nix-prefetch-git: Fix inconsistency with fetchgit regarding deepClone"
This reverts commit 1dfaad73ed.
2022-06-30 11:52:36 +00:00
Sebastian Jordan 1dfaad73ed nix-prefetch-git: Fix inconsistency with fetchgit regarding deepClone
The fetchgit function in nixpkgs sets the leaveDotGit argument to true
if deepClone is set to true. nix-prefetch-git did behave differently. It
would not assume --leave-dotGit if --deepClone is specified. With this
change the inconsistency is addressed by assuming --leave-dotGit if
--deepClone is specified.
2022-06-14 00:23:16 +02:00
Zhong Jianxin d03a07d5a7 fetchgit: Support sparse checkout
This allow git checkout small parts of a large repo, and avoid fetching
unnecessary blobs from server.
2022-01-24 11:23:56 +08:00
Tomas Bravo 80ab168c4a nix-prefetch-git: fix incorrect mktemp usage 2021-12-22 16:45:18 +01:00
Sandro Jäckel 6f53c06748 fetchgit: add support for netrc file through impure NIX_GIT_SSL_CAINFO env 2021-09-28 15:00:11 +02:00
Bjørn Forsman 9bd51f0db9 nix-prefetch-git: add fetchLFS flag to the JSON output
Similarly to the other flags (e.g. fetchSubmodules).
2021-08-28 10:14:48 +02:00
Bjørn Forsman f43829a1d8 nix-prefetch-git: provide fallback for $TMPDIR
$TMPDIR is not set by default in NixOS (nor Ubuntu), so without this
change nix-prefetch-git fails when using git-lfs.
2021-08-28 10:14:48 +02:00
Atemu 11df41199b nix-prefetch-git: don't fetch everything when given a hash
It's hugely inefficient as we can't use shallow cloning (--depth=1).

This has been tested and adapted for quite a few hosts fetchgit is used on in
Nixpkgs. For those where fetching the hash directly doesn't work (most notably
git.savannah.gnu.org), we simply fall back to the old method.
2021-07-12 20:50:52 +02:00
Bjørn Forsman 2e8f6e0d93 fetchgit: document --fetch-lfs flag
Fixes: 74128561 ("fetchgit: add lfs support")
2021-05-07 15:38:54 -07:00
taku0 a964d7094a Merge pull request #104714 from codedownio/tree-hashes
fetchgit: support passing tree hashes as "rev"
2021-02-20 15:22:57 +09:00
Michael Weiss 2aadb9a53d nix-prefetch-git: Run git-init with --initial-branch=master
The reason for this change is simply to avoid the following messages
that are unnecessary and can be confusing (and these messages will be
repeated for each submodule):
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>

With this change the behaviour remains unchanged (apart from the
suppressed "warning" in the console output of course) and therefore this
doesn't cause any hashes to change and by default nix-prefetch-git uses
the "fetchgit" branch anyway (branchName can be set to override the
default):
Switched to a new branch 'fetchgit'

For that reason the initial branch name doesn't matter anyway and since
we're not relying on / hardcoding "master" we could simply switch to
"main" (which seems most common nowadays). See [0] for more details on
why this wouldn't break anything.
However, since the initial branch name doesn't matter and to avoid any
additional risks it was "decided" to keep using "master" (s. #113313).

[0]: https://github.com/NixOS/nixpkgs/pull/113313#issuecomment-780589516
2021-02-18 11:34:34 +01:00
Tom McLaughlin 6779902b32 fetchgit: support passing tree hashes as "rev" 2021-02-13 22:12:08 -08:00
Jonathan Ringer 741285611f fetchgit: add lfs support 2021-01-11 09:41:06 -08:00