1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-12-23 09:21:09 +01:00

Add GitRepo::Options type

This makes a bunch of bool parameters more explicit.
This commit is contained in:
Eelco Dolstra 2025-12-15 14:25:02 +01:00
parent a6eb2e91b7
commit 1c728ce0de
4 changed files with 29 additions and 22 deletions

View file

@ -48,7 +48,7 @@ public:
ref<GitRepo> openRepo() ref<GitRepo> openRepo()
{ {
return GitRepo::openRepo(tmpDir, true, false); return GitRepo::openRepo(tmpDir, {.create = true});
} }
std::string getRepoName() const std::string getRepoName() const

View file

@ -234,7 +234,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
/** Location of the repository on disk. */ /** Location of the repository on disk. */
std::filesystem::path path; std::filesystem::path path;
bool bare; Options options;
/** /**
* libgit2 repository. Note that new objects are not written to disk, * libgit2 repository. Note that new objects are not written to disk,
@ -255,18 +255,18 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
*/ */
git_odb_backend * packBackend = nullptr; git_odb_backend * packBackend = nullptr;
GitRepoImpl(std::filesystem::path _path, bool create, bool bare, bool packfilesOnly = false) GitRepoImpl(std::filesystem::path _path, Options _options)
: path(std::move(_path)) : path(std::move(_path))
, bare(bare) , options(_options)
{ {
initLibGit2(); initLibGit2();
initRepoAtomically(path, bare); initRepoAtomically(path, options.bare);
if (git_repository_open(Setter(repo), path.string().c_str())) if (git_repository_open(Setter(repo), path.string().c_str()))
throw Error("opening Git repository %s: %s", path, git_error_last()->message); throw Error("opening Git repository %s: %s", path, git_error_last()->message);
ObjectDb odb; ObjectDb odb;
if (packfilesOnly) { if (options.packfilesOnly) {
/* Create a fresh object database because by default the repo also /* Create a fresh object database because by default the repo also
loose object backends. We are not using any of those for the loose object backends. We are not using any of those for the
tarball cache, but libgit2 still does a bunch of unnecessary tarball cache, but libgit2 still does a bunch of unnecessary
@ -295,7 +295,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
if (git_odb_add_backend(odb.get(), mempackBackend, 999)) if (git_odb_add_backend(odb.get(), mempackBackend, 999))
throw Error("adding mempack backend to Git object database: %s", git_error_last()->message); throw Error("adding mempack backend to Git object database: %s", git_error_last()->message);
if (packfilesOnly) { if (options.packfilesOnly) {
if (git_repository_set_odb(repo.get(), odb.get())) if (git_repository_set_odb(repo.get(), odb.get()))
throw Error("setting Git object database: %s", git_error_last()->message); throw Error("setting Git object database: %s", git_error_last()->message);
} }
@ -366,7 +366,7 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
{ {
// TODO: as an optimization, it would be nice to include `this` in the pool. // TODO: as an optimization, it would be nice to include `this` in the pool.
return Pool<GitRepoImpl>(std::numeric_limits<size_t>::max(), [this]() -> ref<GitRepoImpl> { return Pool<GitRepoImpl>(std::numeric_limits<size_t>::max(), [this]() -> ref<GitRepoImpl> {
return make_ref<GitRepoImpl>(path, false, bare); return make_ref<GitRepoImpl>(path, options);
}); });
} }
@ -712,9 +712,9 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
} }
}; };
ref<GitRepo> GitRepo::openRepo(const std::filesystem::path & path, bool create, bool bare, bool packfilesOnly) ref<GitRepo> GitRepo::openRepo(const std::filesystem::path & path, GitRepo::Options options)
{ {
return make_ref<GitRepoImpl>(path, create, bare, packfilesOnly); return make_ref<GitRepoImpl>(path, options);
} }
/** /**
@ -1428,7 +1428,7 @@ namespace fetchers {
ref<GitRepo> Settings::getTarballCache() const ref<GitRepo> Settings::getTarballCache() const
{ {
static auto repoDir = std::filesystem::path(getCacheDir()) / "tarball-cache"; static auto repoDir = std::filesystem::path(getCacheDir()) / "tarball-cache";
return GitRepo::openRepo(repoDir, /*create=*/true, /*bare=*/true, /*packfilesOnly=*/true); return GitRepo::openRepo(repoDir, {.create = true, .bare = true, .packfilesOnly = true});
} }
} // namespace fetchers } // namespace fetchers
@ -1442,7 +1442,7 @@ GitRepo::WorkdirInfo GitRepo::getCachedWorkdirInfo(const std::filesystem::path &
if (i != cache->end()) if (i != cache->end())
return i->second; return i->second;
} }
auto workdirInfo = GitRepo::openRepo(path)->getWorkdirInfo(); auto workdirInfo = GitRepo::openRepo(path, {})->getWorkdirInfo();
_cache.lock()->emplace(path, workdirInfo); _cache.lock()->emplace(path, workdirInfo);
return workdirInfo; return workdirInfo;
} }

View file

@ -639,6 +639,7 @@ struct GitInputScheme : InputScheme
// If we don't check here for the path existence, then we can give libgit2 any directory // If we don't check here for the path existence, then we can give libgit2 any directory
// and it will initialize them as git directories. // and it will initialize them as git directories.
// FIXME
if (!pathExists(path)) { if (!pathExists(path)) {
throw Error("The path '%s' does not exist.", path); throw Error("The path '%s' does not exist.", path);
} }
@ -703,7 +704,7 @@ struct GitInputScheme : InputScheme
if (auto res = cache->lookup(key)) if (auto res = cache->lookup(key))
return getIntAttr(*res, "lastModified"); return getIntAttr(*res, "lastModified");
auto lastModified = GitRepo::openRepo(repoDir)->getLastModified(rev); auto lastModified = GitRepo::openRepo(repoDir, {})->getLastModified(rev);
cache->upsert(key, {{"lastModified", lastModified}}); cache->upsert(key, {{"lastModified", lastModified}});
@ -726,7 +727,7 @@ struct GitInputScheme : InputScheme
Activity act( Activity act(
*logger, lvlChatty, actUnknown, fmt("getting Git revision count of '%s'", repoInfo.locationToArg())); *logger, lvlChatty, actUnknown, fmt("getting Git revision count of '%s'", repoInfo.locationToArg()));
auto revCount = GitRepo::openRepo(repoDir)->getRevCount(rev); auto revCount = GitRepo::openRepo(repoDir, {})->getRevCount(rev);
cache->upsert(key, Attrs{{"revCount", revCount}}); cache->upsert(key, Attrs{{"revCount", revCount}});
@ -737,7 +738,7 @@ struct GitInputScheme : InputScheme
{ {
auto head = std::visit( auto head = std::visit(
overloaded{ overloaded{
[&](const std::filesystem::path & path) { return GitRepo::openRepo(path)->getWorkdirRef(); }, [&](const std::filesystem::path & path) { return GitRepo::openRepo(path, {})->getWorkdirRef(); },
[&](const ParsedURL & url) { return readHeadCached(url.to_string(), shallow); }}, [&](const ParsedURL & url) { return readHeadCached(url.to_string(), shallow); }},
repoInfo.location); repoInfo.location);
if (!head) { if (!head) {
@ -795,7 +796,7 @@ struct GitInputScheme : InputScheme
if (auto repoPath = repoInfo.getPath()) { if (auto repoPath = repoInfo.getPath()) {
repoDir = *repoPath; repoDir = *repoPath;
if (!input.getRev()) if (!input.getRev())
input.attrs.insert_or_assign("rev", GitRepo::openRepo(repoDir)->resolveRef(ref).gitRev()); input.attrs.insert_or_assign("rev", GitRepo::openRepo(repoDir, {})->resolveRef(ref).gitRev());
} else { } else {
auto repoUrl = std::get<ParsedURL>(repoInfo.location); auto repoUrl = std::get<ParsedURL>(repoInfo.location);
std::filesystem::path cacheDir = getCachePath(repoUrl.to_string(), shallow); std::filesystem::path cacheDir = getCachePath(repoUrl.to_string(), shallow);
@ -805,7 +806,7 @@ struct GitInputScheme : InputScheme
std::filesystem::create_directories(cacheDir.parent_path()); std::filesystem::create_directories(cacheDir.parent_path());
PathLocks cacheDirLock({cacheDir.string()}); PathLocks cacheDirLock({cacheDir.string()});
auto repo = GitRepo::openRepo(cacheDir, true, true); auto repo = GitRepo::openRepo(cacheDir, {.create = true, .bare = true});
// We need to set the origin so resolving submodule URLs works // We need to set the origin so resolving submodule URLs works
repo->setRemote("origin", repoUrl.to_string()); repo->setRemote("origin", repoUrl.to_string());
@ -876,7 +877,7 @@ struct GitInputScheme : InputScheme
// the remainder // the remainder
} }
auto repo = GitRepo::openRepo(repoDir); auto repo = GitRepo::openRepo(repoDir, {});
auto isShallow = repo->isShallow(); auto isShallow = repo->isShallow();
@ -963,7 +964,7 @@ struct GitInputScheme : InputScheme
for (auto & submodule : repoInfo.workdirInfo.submodules) for (auto & submodule : repoInfo.workdirInfo.submodules)
repoInfo.workdirInfo.files.insert(submodule.path); repoInfo.workdirInfo.files.insert(submodule.path);
auto repo = GitRepo::openRepo(repoPath, false, false); auto repo = GitRepo::openRepo(repoPath, {});
auto exportIgnore = getExportIgnoreAttr(input); auto exportIgnore = getExportIgnoreAttr(input);
@ -1003,7 +1004,7 @@ struct GitInputScheme : InputScheme
} }
if (!repoInfo.workdirInfo.isDirty) { if (!repoInfo.workdirInfo.isDirty) {
auto repo = GitRepo::openRepo(repoPath); auto repo = GitRepo::openRepo(repoPath, {});
if (auto ref = repo->getWorkdirRef()) if (auto ref = repo->getWorkdirRef())
input.attrs.insert_or_assign("ref", *ref); input.attrs.insert_or_assign("ref", *ref);

View file

@ -32,8 +32,14 @@ struct GitRepo
{ {
virtual ~GitRepo() {} virtual ~GitRepo() {}
static ref<GitRepo> struct Options
openRepo(const std::filesystem::path & path, bool create = false, bool bare = false, bool packfilesOnly = false); {
bool create = false;
bool bare = false;
bool packfilesOnly = false;
};
static ref<GitRepo> openRepo(const std::filesystem::path & path, Options options);
virtual uint64_t getRevCount(const Hash & rev) = 0; virtual uint64_t getRevCount(const Hash & rev) = 0;