diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/file_system/git_repo.cpp | 24 | ||||
-rw-r--r-- | src/buildtool/file_system/git_utils.hpp | 5 |
2 files changed, 23 insertions, 6 deletions
diff --git a/src/buildtool/file_system/git_repo.cpp b/src/buildtool/file_system/git_repo.cpp index bf0b6ddc..4c88e4a7 100644 --- a/src/buildtool/file_system/git_repo.cpp +++ b/src/buildtool/file_system/git_repo.cpp @@ -361,8 +361,16 @@ auto GitRepo::InitAndOpen(std::filesystem::path const& repo_path, auto git_state = GitContext(); // initialize libgit2 + // check if init is actually needed + if (git_repository_open_ext(nullptr, + repo_path.c_str(), + GIT_REPOSITORY_OPEN_NO_SEARCH, + nullptr) == 0) { + return GitRepo(repo_path); // success + } + git_repository* tmp_repo{nullptr}; - size_t max_attempts = 3; // number of tries + size_t max_attempts = kGitLockNumTries; // number of tries int err = 0; std::string err_mess{}; while (max_attempts > 0) { @@ -373,7 +381,11 @@ auto GitRepo::InitAndOpen(std::filesystem::path const& repo_path, git_repository_free(tmp_repo); return GitRepo(repo_path); // success } - err_mess = GitLastError(); // store last error message + err_mess = GitLastError(); // store last error message + // only retry if failure is due to locking + if (err != GIT_ELOCKED) { + break; + } git_repository_free(tmp_repo); // cleanup before next attempt // check if init hasn't already happened in another process if (git_repository_open_ext(nullptr, @@ -383,7 +395,8 @@ auto GitRepo::InitAndOpen(std::filesystem::path const& repo_path, return GitRepo(repo_path); // success } // repo still not created, so sleep and try again - std::this_thread::sleep_for(std::chrono::milliseconds(kWaitTime)); + std::this_thread::sleep_for( + std::chrono::milliseconds(kGitLockWaitTime)); } Logger::Log(LogLevel::Error, "initializing git repository {} failed with:\n{}", @@ -582,7 +595,7 @@ auto GitRepo::KeepTag(std::string const& commit, git_oid oid; auto name = fmt::format("keep-{}", commit); - size_t max_attempts = 3; // number of tries + size_t max_attempts = kGitLockNumTries; // number of tries int err = 0; git_strarray tag_names{}; while (max_attempts > 0) { @@ -607,7 +620,8 @@ auto GitRepo::KeepTag(std::string const& commit, git_strarray_dispose( &tag_names); // free any allocated unused space // tag still not in, so sleep and try again - std::this_thread::sleep_for(std::chrono::milliseconds(kWaitTime)); + std::this_thread::sleep_for( + std::chrono::milliseconds(kGitLockWaitTime)); } (*logger)(fmt::format("tag creation in git repository {} failed", GetGitCAS()->git_path_.string()), diff --git a/src/buildtool/file_system/git_utils.hpp b/src/buildtool/file_system/git_utils.hpp index 68eb670b..5749c8b5 100644 --- a/src/buildtool/file_system/git_utils.hpp +++ b/src/buildtool/file_system/git_utils.hpp @@ -36,7 +36,10 @@ struct git_tree_entry; struct git_config; } -constexpr std::size_t kWaitTime{2}; // time in ms between tries for git locks +// time in ms between tries for git locks +constexpr std::size_t kGitLockWaitTime{100}; +// number of retries for git locks +constexpr std::size_t kGitLockNumTries{10}; [[nodiscard]] auto GitObjectID(std::string const& id, bool is_hex_id = false) noexcept |