core/pkgs/build-support/fetchgit/default.nix

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

148 lines
4.2 KiB
Nix
Raw Normal View History

2024-05-02 00:46:19 +00:00
{
lib,
stdenvNoCC,
git,
git-lfs,
cacert,
}:
let
urlToName =
url: rev:
2024-06-30 08:12:46 +00:00
let
2024-05-02 00:46:19 +00:00
inherit (lib) removeSuffix splitString last;
base = last (splitString ":" (baseNameOf (removeSuffix "/" url)));
matched = builtins.match "(.*)\\.git" base;
short = builtins.substring 0 7 rev;
appendShort = lib.optionalString ((builtins.match "[a-f0-9]*" rev) != null) "-${short}";
in
"${if matched == null then base else builtins.head matched}${appendShort}";
in
lib.makeOverridable (
{
url,
rev ? "HEAD",
sha256 ? "",
hash ? "",
leaveDotGit ? deepClone,
fetchSubmodules ? true,
deepClone ? false,
branchName ? null,
sparseCheckout ? [ ],
nonConeMode ? false,
name ? urlToName url rev,
# Shell code executed after the file has been fetched
# successfully. This can do things like check or transform the file.
postFetch ? "",
preferLocalBuild ? true,
fetchLFS ? false,
# Shell code to build a netrc file for BASIC auth
netrcPhase ? null,
# Impure env vars (https://nixos.org/nix/manual/#sec-advanced-attributes)
# needed for netrcPhase
netrcImpureEnvVars ? [ ],
2024-03-07 17:11:29 +00:00
passthru ? { },
2024-05-02 00:46:19 +00:00
meta ? { },
allowedRequisites ? null,
}:
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
/*
NOTE:
fetchgit has one problem: git fetch only works for refs.
This is because fetching arbitrary (maybe dangling) commits creates garbage collection risks
and checking whether a commit belongs to a ref is expensive. This may
change in the future when some caching is added to git (?)
Usually refs are either tags (refs/tags/*) or branches (refs/heads/*)
Cloning branches will make the hash check fail when there is an update.
But not all patches we want can be accessed by tags.
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
The workaround is getting the last n commits so that it's likely that they
still contain the hash we want.
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
for now : increase depth iteratively (TODO)
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
real fix: ask git folks to add a
git fetch $HASH contained in $BRANCH
facility because checking that $HASH is contained in $BRANCH is less
expensive than fetching --depth $N.
Even if git folks implemented this feature soon it may take years until
server admins start using the new version?
2024-06-30 08:12:46 +00:00
*/
2024-05-02 00:46:19 +00:00
assert deepClone -> leaveDotGit;
assert nonConeMode -> (sparseCheckout != [ ]);
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
if hash != "" && sha256 != "" then
throw "Only one of sha256 or hash can be set"
else if builtins.isString sparseCheckout then
# Changed to throw on 2023-06-04
2024-06-30 08:12:46 +00:00
throw
2024-05-02 00:46:19 +00:00
"Please provide directories/patterns for sparse checkout as a list of strings. Passing a (multi-line) string is not supported any more."
else
stdenvNoCC.mkDerivation {
inherit name;
builder = ./builder.sh;
fetcher = ./nix-prefetch-git;
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
nativeBuildInputs = [ git ] ++ lib.optionals fetchLFS [ git-lfs ];
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
outputHashAlgo = if hash != "" then null else "sha256";
outputHashMode = "recursive";
outputHash =
if hash != "" then
2024-06-30 08:12:46 +00:00
hash
2024-05-02 00:46:19 +00:00
else if sha256 != "" then
2024-06-30 08:12:46 +00:00
sha256
else
2024-05-02 00:46:19 +00:00
lib.fakeSha256;
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
# git-sparse-checkout(1) says:
# > When the --stdin option is provided, the directories or patterns are read
# > from standard in as a newline-delimited list instead of from the arguments.
sparseCheckout = builtins.concatStringsSep "\n" sparseCheckout;
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
inherit
url
rev
leaveDotGit
fetchLFS
fetchSubmodules
deepClone
branchName
nonConeMode
postFetch
;
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
postHook =
if netrcPhase == null then
null
else
''
${netrcPhase}
# required that git uses the netrc file
mv {,.}netrc
export NETRC=$PWD/.netrc
export HOME=$PWD
'';
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
impureEnvVars =
lib.fetchers.proxyImpureEnvVars
++ netrcImpureEnvVars
++ [
"GIT_PROXY_COMMAND"
"NIX_GIT_SSL_CAINFO"
"SOCKS_SERVER"
];
2024-06-30 08:12:46 +00:00
2024-05-02 00:46:19 +00:00
inherit preferLocalBuild meta allowedRequisites;
2024-06-30 08:12:46 +00:00
2024-03-07 17:11:29 +00:00
passthru = passthru // {
2024-05-02 00:46:19 +00:00
gitRepoUrl = url;
};
}
)