about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libstore/build.cc6
-rw-r--r--src/libstore/store-api.cc13
-rw-r--r--src/libstore/store-api.hh5
-rw-r--r--src/libutil/ref.hh7
-rw-r--r--src/nix/copy.cc6
5 files changed, 27 insertions, 10 deletions
diff --git a/src/libstore/build.cc b/src/libstore/build.cc
index 65df2eea59a0..3b9ecab1c12a 100644
--- a/src/libstore/build.cc
+++ b/src/libstore/build.cc
@@ -3222,11 +3222,7 @@ void SubstitutionGoal::tryToRun()
             /* Wake up the worker loop when we're done. */
             Finally updateStats([this]() { outPipe.writeSide.close(); });
 
-            StringSink sink;
-            sub->exportPaths({storePath}, false, sink);
-
-            StringSource source(*sink.s);
-            worker.store.importPaths(false, source, 0);
+            copyStorePath(ref<Store>(sub), ref<Store>(worker.store.shared_from_this()), storePath);
 
             promise.set_value();
         } catch (...) {
diff --git a/src/libstore/store-api.cc b/src/libstore/store-api.cc
index 463e132e0299..b03e4080afc2 100644
--- a/src/libstore/store-api.cc
+++ b/src/libstore/store-api.cc
@@ -357,6 +357,19 @@ const Store::Stats & Store::getStats()
 }
 
 
+void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
+    const Path & storePath)
+{
+    auto info = srcStore->queryPathInfo(storePath);
+
+    StringSink sink;
+    srcStore->exportPaths({storePath}, false, sink);
+
+    StringSource source(*sink.s);
+    dstStore->importPaths(false, source, 0);
+}
+
+
 ValidPathInfo decodeValidPathInfo(std::istream & str, bool hashGiven)
 {
     ValidPathInfo info;
diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh
index 29685c9d1676..099aa1d67b68 100644
--- a/src/libstore/store-api.hh
+++ b/src/libstore/store-api.hh
@@ -502,6 +502,11 @@ Path computeStorePathForText(const string & name, const string & s,
     const PathSet & references);
 
 
+/* Copy a path from one store to another. */
+void copyStorePath(ref<Store> srcStore, ref<Store> dstStore,
+    const Path & storePath);
+
+
 /* Remove the temporary roots file for this process.  Any temporary
    root becomes garbage after this point unless it has been registered
    as a (permanent) root. */
diff --git a/src/libutil/ref.hh b/src/libutil/ref.hh
index 9f5da09152c9..85afa28119a9 100644
--- a/src/libutil/ref.hh
+++ b/src/libutil/ref.hh
@@ -28,6 +28,13 @@ public:
             throw std::invalid_argument("null pointer cast to ref");
     }
 
+    explicit ref<T>(T * p)
+        : p(p)
+    {
+        if (!p)
+            throw std::invalid_argument("null pointer cast to ref");
+    }
+
     T* operator ->() const
     {
         return &*p;
diff --git a/src/nix/copy.cc b/src/nix/copy.cc
index be51fee62712..de306cbf91d9 100644
--- a/src/nix/copy.cc
+++ b/src/nix/copy.cc
@@ -65,11 +65,7 @@ struct CmdCopy : StorePathsCommand
                 if (!dstStore->isValidPath(storePath)) {
                     Activity act(*logger, lvlInfo, format("copying ‘%s’...") % storePath);
 
-                    StringSink sink;
-                    srcStore->exportPaths({storePath}, false, sink);
-
-                    StringSource source(*sink.s);
-                    dstStore->importPaths(false, source, 0);
+                    copyStorePath(srcStore, dstStore, storePath);
 
                     logger->incProgress(copiedLabel);
                 } else