about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraham Christensen <graham.christensen@target.com>2018-08-17T14·29-0400
committerGraham Christensen <graham.christensen@target.com>2018-08-17T15·27-0400
commit02098d2073e2f7c06b6d05c6749ae2b76b7f57d5 (patch)
treeb5e37e17af5e63f484d44259efbcbcbc30dd10af
parentd277442df53a01343ba7c1df0bbd2a294058dcba (diff)
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.
-rw-r--r--src/libexpr/primops/fetchGit.cc4
-rw-r--r--tests/fetchGit.sh4
2 files changed, 5 insertions, 3 deletions
diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc
index 7aa98e0bfab3..aeb2df5f8aee 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 <sys/time.h>
 
@@ -84,9 +85,10 @@ GitInfo exportGit(ref<Store> 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 530ac7bb813c..4c46bdf0465b 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)