summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/file_system/git_repo.cpp47
-rw-r--r--src/buildtool/file_system/git_repo.hpp9
2 files changed, 56 insertions, 0 deletions
diff --git a/src/buildtool/file_system/git_repo.cpp b/src/buildtool/file_system/git_repo.cpp
index 1498b229..5a285499 100644
--- a/src/buildtool/file_system/git_repo.cpp
+++ b/src/buildtool/file_system/git_repo.cpp
@@ -965,6 +965,53 @@ auto GitRepo::GetRepoRootFromPath(std::filesystem::path const& fpath,
#endif // BOOTSTRAP_BUILD_TOOL
}
+auto GitRepo::CheckTreeExists(std::string const& tree_id,
+ anon_logger_ptr const& logger) noexcept
+ -> std::optional<bool> {
+#ifdef BOOTSTRAP_BUILD_TOOL
+ return std::nullopt;
+#else
+ try {
+ // preferably with a "fake" repository!
+ if (not IsRepoFake()) {
+ Logger::Log(LogLevel::Debug,
+ "Subtree lookup called on a real repository");
+ }
+ // get git oid
+ git_oid tree_oid;
+ if (git_oid_fromstr(&tree_oid, tree_id.c_str()) != 0) {
+ (*logger)(fmt::format("tree ID parsing in git repository {} failed "
+ "with:\n{}",
+ GetGitCAS()->git_path_.string(),
+ GitLastError()),
+ true /*fatal*/);
+ return std::nullopt;
+ }
+ // get tree object
+ git_tree* tree_ptr = nullptr;
+ auto lookup_res = git_tree_lookup(&tree_ptr, repo_.get(), &tree_oid);
+ git_tree_free(tree_ptr);
+ if (lookup_res != 0) {
+ if (lookup_res == GIT_ENOTFOUND) {
+ return false; // tree not found
+ }
+ (*logger)(
+ fmt::format("tree lookup in git repository {} failed with:\n{}",
+ GetGitCAS()->git_path_.string(),
+ GitLastError()),
+ true /*fatal*/);
+ return std::nullopt;
+ }
+ return true; // tree found
+ } catch (std::exception const& ex) {
+ Logger::Log(LogLevel::Error,
+ "check subtree exists failed with:\n{}",
+ ex.what());
+ return std::nullopt;
+ }
+#endif // BOOTSTRAP_BUILD_TOOL
+}
+
auto GitRepo::IsRepoFake() const noexcept -> bool {
return is_repo_fake_;
}
diff --git a/src/buildtool/file_system/git_repo.hpp b/src/buildtool/file_system/git_repo.hpp
index a5a8da7a..eba826d9 100644
--- a/src/buildtool/file_system/git_repo.hpp
+++ b/src/buildtool/file_system/git_repo.hpp
@@ -186,6 +186,15 @@ class GitRepo {
anon_logger_ptr const& logger) noexcept
-> std::optional<std::filesystem::path>;
+ /// \brief Check if given tree ID is present in the directory structure of
+ /// the local repository.
+ /// Calling it from a fake repository allows thread-safe use.
+ /// Returns a status of tree presence, or nullopt if failure.
+ /// It guarantees the logger is called exactly once with fatal if failure.
+ [[nodiscard]] auto CheckTreeExists(std::string const& tree_id,
+ anon_logger_ptr const& logger) noexcept
+ -> std::optional<bool>;
+
private:
// IMPORTANT! The GitCAS object must be defined before the repo object to
// keep the GitContext alive until cleanup ends.