aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorShea Levy <shea@shealevy.com>2017-12-05 11:16:39 -0500
committerShea Levy <shea@shealevy.com>2017-12-05 11:16:39 -0500
commit11a7f8ce14afbdc60b9acf424d941ccda1adc141 (patch)
treefbd99244f4fe0c346d26b770580cb37a993cbb4a /src
parent7f2c324ed18cba4004ff89dfd84cf2df979b2571 (diff)
parenteedbc4e06c017d84814b4c1fad8c6b6db958f3da (diff)
Merge branch 'fetchGit-fast-revision-update'
Diffstat (limited to 'src')
-rw-r--r--src/libexpr/primops/fetchGit.cc59
1 files changed, 35 insertions, 24 deletions
diff --git a/src/libexpr/primops/fetchGit.cc b/src/libexpr/primops/fetchGit.cc
index fd3e84c29..e92e06380 100644
--- a/src/libexpr/primops/fetchGit.cc
+++ b/src/libexpr/primops/fetchGit.cc
@@ -89,32 +89,43 @@ GitInfo exportGit(ref<Store> store, const std::string & uri,
Path localRefFile = cacheDir + "/refs/heads/" + localRef;
- /* If the local ref is older than ‘tarball-ttl’ seconds, do a git
- fetch to update the local ref to the remote ref. */
+ bool doFetch;
time_t now = time(0);
- struct stat st;
- if (stat(localRefFile.c_str(), &st) != 0 ||
- st.st_mtime <= now - settings.tarballTtl)
- {
- if (rev == "" ||
- chomp(runProgram(
- RunOptions("git", { "-C", cacheDir, "cat-file", "-t", rev })
- .killStderr(true)).second) != "commit")
- {
- Activity act(*logger, lvlTalkative, actUnknown, fmt("fetching Git repository '%s'", uri));
-
- // FIXME: git stderr messes up our progress indicator, so
- // we're using --quiet for now. Should process its stderr.
- runProgram("git", true, { "-C", cacheDir, "fetch", "--quiet", "--force", "--", uri, *ref + ":" + localRef });
-
- struct timeval times[2];
- times[0].tv_sec = now;
- times[0].tv_usec = 0;
- times[1].tv_sec = now;
- times[1].tv_usec = 0;
-
- utimes(localRefFile.c_str(), times);
+ /* If a rev was specified, we need to fetch if it's not in the
+ repo. */
+ if (rev != "") {
+ try {
+ runProgram("git", true, { "-C", cacheDir, "cat-file", "-e", rev });
+ doFetch = false;
+ } catch (ExecError & e) {
+ if (WIFEXITED(e.status)) {
+ doFetch = true;
+ } else {
+ throw;
+ }
}
+ } else {
+ /* If the local ref is older than ‘tarball-ttl’ seconds, do a
+ git fetch to update the local ref to the remote ref. */
+ struct stat st;
+ doFetch = stat(localRefFile.c_str(), &st) != 0 ||
+ st.st_mtime <= now - settings.tarballTtl;
+ }
+ if (doFetch)
+ {
+ Activity act(*logger, lvlTalkative, actUnknown, fmt("fetching Git repository '%s'", uri));
+
+ // FIXME: git stderr messes up our progress indicator, so
+ // we're using --quiet for now. Should process its stderr.
+ runProgram("git", true, { "-C", cacheDir, "fetch", "--quiet", "--force", "--", uri, *ref + ":" + localRef });
+
+ struct timeval times[2];
+ times[0].tv_sec = now;
+ times[0].tv_usec = 0;
+ times[1].tv_sec = now;
+ times[1].tv_usec = 0;
+
+ utimes(localRefFile.c_str(), times);
}
// FIXME: check whether rev is an ancestor of ref.