mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-15 02:36:16 +02:00
create git caches atomically
When working on speeding up the CI, I triggered a race condition in the creation of the tarball cache. This code now instead will ensure that half-initialized repositories are no longer visible to any other nix process. This is the error message that I got before: error: opening Git repository '"/Users/runner/.cache/nix/tarball-cache"': could not find repository at '/Users/runner/.cache/nix/tarball-cache'
This commit is contained in:
parent
a5959aa121
commit
12d5b2cfa1
1 changed files with 24 additions and 7 deletions
|
@ -205,6 +205,27 @@ static git_packbuilder_progress PACKBUILDER_PROGRESS_CHECK_INTERRUPT = &packBuil
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|
||||||
|
static void initRepoAtomically(std::filesystem::path &path, bool bare) {
|
||||||
|
if (pathExists(path.string())) return;
|
||||||
|
|
||||||
|
Path tmpDir = createTempDir(std::filesystem::path(path).parent_path());
|
||||||
|
AutoDelete delTmpDir(tmpDir, true);
|
||||||
|
Repository tmpRepo;
|
||||||
|
|
||||||
|
if (git_repository_init(Setter(tmpRepo), tmpDir.c_str(), bare))
|
||||||
|
throw Error("creating Git repository %s: %s", path, git_error_last()->message);
|
||||||
|
try {
|
||||||
|
std::filesystem::rename(tmpDir, path);
|
||||||
|
} catch (std::filesystem::filesystem_error & e) {
|
||||||
|
if (e.code() == std::errc::file_exists) // Someone might race us to create the repository.
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
throw SysError("moving temporary git repository from %s to %s", tmpDir, path);
|
||||||
|
}
|
||||||
|
// we successfully moved the repository, so the temporary directory no longer exists.
|
||||||
|
delTmpDir.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
{
|
{
|
||||||
/** Location of the repository on disk. */
|
/** Location of the repository on disk. */
|
||||||
|
@ -226,13 +247,9 @@ struct GitRepoImpl : GitRepo, std::enable_shared_from_this<GitRepoImpl>
|
||||||
{
|
{
|
||||||
initLibGit2();
|
initLibGit2();
|
||||||
|
|
||||||
if (pathExists(path.string())) {
|
initRepoAtomically(path, 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);
|
||||||
} else {
|
|
||||||
if (git_repository_init(Setter(repo), path.string().c_str(), bare))
|
|
||||||
throw Error("creating Git repository '%s': %s", path, git_error_last()->message);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectDb odb;
|
ObjectDb odb;
|
||||||
if (git_repository_odb(Setter(odb), repo.get()))
|
if (git_repository_odb(Setter(odb), repo.get()))
|
||||||
|
|
Loading…
Reference in a new issue