From 02098d2073e2f7c06b6d05c6749ae2b76b7f57d5 Mon Sep 17 00:00:00 2001 From: Graham Christensen Date: Fri, 17 Aug 2018 10:29:32 -0400 Subject: [PATCH] fetchGit: use a better caching scheme The current usage technically works by putting multiple different repos in to the same git directory. However, it is very slow as Git tries very hard to find common commits between the two repositories. If the two repositories are large (like Nixpkgs and another long-running project,) it is maddeningly slow. This change busts the cache for existing deployments, but users will be promptly repaid in per-repository performance. --- src/libexpr/primops/fetchGit.cc | 4 +++- tests/fetchGit.sh | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc index 7aa98e0b..aeb2df5f 100644 --- a/src/libexpr/primops/fetchGit.cc +++ b/src/libexpr/primops/fetchGit.cc @@ -3,6 +3,7 @@ #include "download.hh" #include "store-api.hh" #include "pathlocks.hh" +#include "hash.hh" #include @@ -84,9 +85,10 @@ GitInfo exportGit(ref store, const std::string & uri, if (rev != "" && !std::regex_match(rev, revRegex)) throw Error("invalid Git revision '%s'", rev); - Path cacheDir = getCacheDir() + "/nix/git"; + Path cacheDir = getCacheDir() + "/nix/gitv2/" + hashString(htSHA256, uri).to_string(Base32, false); if (!pathExists(cacheDir)) { + createDirs(dirOf(cacheDir)); runProgram("git", true, { "init", "--bare", cacheDir }); } diff --git a/tests/fetchGit.sh b/tests/fetchGit.sh index 530ac7bb..4c46bdf0 100644 --- a/tests/fetchGit.sh +++ b/tests/fetchGit.sh @@ -9,7 +9,7 @@ clearStore repo=$TEST_ROOT/git -rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix/git +rm -rf $repo ${repo}-tmp $TEST_HOME/.cache/nix/gitv2 git init $repo git -C $repo config user.email "foobar@example.com" @@ -129,7 +129,7 @@ path5=$(nix eval --raw "(builtins.fetchGit { url = $repo; ref = \"dev\"; }).outP # Nuke the cache -rm -rf $TEST_HOME/.cache/nix/git +rm -rf $TEST_HOME/.cache/nix/gitv2 # Try again, but without 'git' on PATH NIX=$(command -v nix)