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]: f0449d090c
[1]: 38539b943a
[2]: https://github.com/NixOS/nix/releases/tag/2.0
[3]: db00265e81/source/guides/best-practices.md (L263-L264)
[4]: a8603605aa
This commit is contained in:
Valentin Gagarin
2025-04-09 20:11:27 +02:00
parent 6b691c15cd
commit c59a777a97
2 changed files with 11 additions and 3 deletions

View File

@@ -6,7 +6,7 @@
echo "exporting $url (rev $rev) into $out"
$SHELL $fetcher --builder --url "$url" --out "$out" --rev "$rev" \
$SHELL $fetcher --builder --url "$url" --out "$out" --rev "$rev" --name "$name" \
${leaveDotGit:+--leave-dotGit} \
${fetchLFS:+--fetch-lfs} \
${deepClone:+--deepClone} \

View File

@@ -47,6 +47,7 @@ Options:
--url url Any url understood by 'git clone'.
--rev ref Any sha1 or references (such as refs/heads/master)
--hash h Expected hash.
--name n Symbolic store path name to use for the result (default: based on URL)
--branch-name Branch name to check out into
--sparse-checkout Only fetch and checkout part of the repository.
--non-cone-mode Use non-cone mode for sparse checkouts.
@@ -75,6 +76,7 @@ for arg; do
--url) argfun=set_url;;
--rev) argfun=set_rev;;
--hash) argfun=set_hashType;;
--name) argfun=set_symbolicName;;
--branch-name) argfun=set_branchName;;
--deepClone) deepClone=true;;
--sparse-checkout) argfun=set_sparseCheckout;;
@@ -424,6 +426,12 @@ if test -z "$branchName"; then
branchName=fetchgit
fi
if [ -v symbolicName ]; then
storePathName="$symbolicName"
else
storePathName="$(url_to_name "$url" "$rev")"
fi
tmpHomePath="$(mktemp -d "${TMPDIR:-/tmp}/nix-prefetch-git-tmp-home-XXXXXXXXXX")"
exit_handlers+=(remove_tmpHomePath)
ln -s "${NETRC:-$HOME/.netrc}" "$tmpHomePath/.netrc"
@@ -443,7 +451,7 @@ else
# If the hash was given, a file with that hash may already be in the
# store.
if test -n "$expHash"; then
finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" "$(url_to_name "$url" "$rev")")
finalPath=$(nix-store --print-fixed-path --recursive "$hashType" "$expHash" "$storePathName")
if ! nix-store --check-validity "$finalPath" 2> /dev/null; then
finalPath=
fi
@@ -458,7 +466,7 @@ else
tmpPath="$(realpath "$(mktemp -d --tmpdir git-checkout-tmp-XXXXXXXX)")"
exit_handlers+=(remove_tmpPath)
tmpFile="$tmpPath/$(url_to_name "$url" "$rev")"
tmpFile="$tmpPath/$storePathName"
mkdir -p "$tmpFile"
# Perform the checkout.