Skip to content

Commit 908b802

Browse files
committed
Cache calls to GitRepo::getWorkdirInfo()
A command like `nix flake metadata` was causing about 4 calls to getWorkdirInfo(), which is slow for large repos (even when they're not dirty).
1 parent ab49546 commit 908b802

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/libfetchers/git-utils.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "signals.hh"
66
#include "users.hh"
77
#include "fs-sink.hh"
8+
#include "sync.hh"
89

910
#include <git2/attr.h>
1011
#include <git2/blob.h>
@@ -1276,4 +1277,17 @@ ref<GitRepo> getTarballCache()
12761277
return GitRepo::openRepo(repoDir, true, true);
12771278
}
12781279

1280+
GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path & path)
1281+
{
1282+
static Sync<std::unordered_map<std::filesystem::path, WorkdirInfo>> _cache;
1283+
{
1284+
auto cache(_cache.lock());
1285+
auto i = cache->find(path);
1286+
if (i != cache->end()) return i->second;
1287+
}
1288+
auto workdirInfo = GitRepo::openRepo(path)->getWorkdirInfo();
1289+
_cache.lock()->emplace(path, workdirInfo);
1290+
return workdirInfo;
1291+
}
1292+
12791293
}

src/libfetchers/git-utils.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ struct GitRepo
7070

7171
virtual WorkdirInfo getWorkdirInfo() = 0;
7272

73+
static WorkdirInfo getCachedWorkdirInfo(const std::filesystem::path & path);
74+
7375
/* Get the ref that HEAD points to. */
7476
virtual std::optional<std::string> getWorkdirRef() = 0;
7577

src/libfetchers/git.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ struct GitInputScheme : InputScheme
431431
// If this is a local directory and no ref or revision is
432432
// given, then allow the use of an unclean working tree.
433433
if (!input.getRef() && !input.getRev() && repoInfo.isLocal)
434-
repoInfo.workdirInfo = GitRepo::openRepo(repoInfo.url)->getWorkdirInfo();
434+
repoInfo.workdirInfo = GitRepo::getCachedWorkdirInfo(repoInfo.url);
435435

436436
return repoInfo;
437437
}

0 commit comments

Comments
 (0)