about summary refs log tree commit diff
path: root/src/libexpr/primops/fetchgit.cc
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2017-07-27T14·16+0200
committerEelco Dolstra <edolstra@gmail.com>2017-07-27T14·16+0200
commit6d7de7f3ded6254ea3a284b2c9b6a51fc8b041bb (patch)
treeab250e77f77a8abc09af7ca6f160df5087151bfc /src/libexpr/primops/fetchgit.cc
parent57b95057311d4dafb948c78889693a98ec349460 (diff)
builtins.fetchgit: Cache hash -> store path mappings
This prevents an expensive call to addToStore() in the cached case.
Diffstat (limited to 'src/libexpr/primops/fetchgit.cc')
-rw-r--r--src/libexpr/primops/fetchgit.cc20
1 files changed, 18 insertions, 2 deletions
diff --git a/src/libexpr/primops/fetchgit.cc b/src/libexpr/primops/fetchgit.cc
index 3e4ece2cffdc..1ac9b364f520 100644
--- a/src/libexpr/primops/fetchgit.cc
+++ b/src/libexpr/primops/fetchgit.cc
@@ -2,6 +2,7 @@
 #include "eval-inline.hh"
 #include "download.hh"
 #include "store-api.hh"
+#include "pathlocks.hh"
 
 namespace nix {
 
@@ -28,7 +29,18 @@ Path exportGit(ref<Store> store, const std::string & uri, const std::string & re
 
     unlink(localRefFile.c_str());
 
-    debug(format("got revision ‘%s’") % commitHash);
+    printTalkative("using revision %s of repo ‘%s’", uri, commitHash);
+
+    Path storeLink = cacheDir + "/" + commitHash + ".link";
+    PathLocks storeLinkLock({storeLink}, fmt("waiting for lock on ‘%1%’...", storeLink));
+
+    if (pathExists(storeLink)) {
+        auto storePath = readLink(storeLink);
+        store->addTempRoot(storePath);
+        if (store->isValidPath(storePath)) {
+            return storePath;
+        }
+    }
 
     // FIXME: should pipe this, or find some better way to extract a
     // revision.
@@ -39,7 +51,11 @@ Path exportGit(ref<Store> store, const std::string & uri, const std::string & re
 
     runProgram("tar", true, { "x", "-C", tmpDir }, tar);
 
-    return store->addToStore("git-export", tmpDir);
+    auto storePath = store->addToStore("git-export", tmpDir);
+
+    replaceSymlink(storePath, storeLink);
+
+    return storePath;
 }
 
 static void prim_fetchgit(EvalState & state, const Pos & pos, Value * * args, Value & v)