summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaksim Denisov <denisov.maksim@huawei.com>2024-12-04 13:12:15 +0100
committerKlaus Aehlig <klaus.aehlig@huawei.com>2025-01-13 16:21:08 +0100
commit98f1e8224753e7d7bfaf697012302887d85bff6c (patch)
tree5430fa4e9f8d971d8e8043e62e3aa57aef231217
parent0c50b8a6a181795697be882bd62c0d37efab078c (diff)
downloadjustbuild-98f1e8224753e7d7bfaf697012302887d85bff6c.tar.gz
GitCAS: implement method for creation of an empty GitCAS
...and use it in GitRepo to set custom backends. (cherry-picked 99860b78304817c4d5b27ec4c661b733e30a430a)
-rw-r--r--src/buildtool/file_system/TARGETS3
-rw-r--r--src/buildtool/file_system/git_cas.cpp18
-rw-r--r--src/buildtool/file_system/git_cas.hpp7
-rw-r--r--src/buildtool/file_system/git_repo.cpp25
4 files changed, 37 insertions, 16 deletions
diff --git a/src/buildtool/file_system/TARGETS b/src/buildtool/file_system/TARGETS
index 790111f1..ff145084 100644
--- a/src/buildtool/file_system/TARGETS
+++ b/src/buildtool/file_system/TARGETS
@@ -68,7 +68,8 @@
, "name": ["git_cas"]
, "hdrs": ["git_cas.hpp"]
, "srcs": ["git_cas.cpp"]
- , "deps": ["git_context", "git_utils", ["@", "gsl", "", "gsl"]]
+ , "deps":
+ ["git_context", "git_utils", "object_type", ["@", "gsl", "", "gsl"]]
, "stage": ["src", "buildtool", "file_system"]
, "private-deps":
[ ["", "libgit2"]
diff --git a/src/buildtool/file_system/git_cas.cpp b/src/buildtool/file_system/git_cas.cpp
index 13177cea..f40c83cf 100644
--- a/src/buildtool/file_system/git_cas.cpp
+++ b/src/buildtool/file_system/git_cas.cpp
@@ -109,6 +109,24 @@ auto GitCAS::Open(std::filesystem::path const& repo_path) noexcept
#endif
}
+auto GitCAS::CreateEmpty() noexcept -> GitCASPtr {
+#ifdef BOOTSTRAP_BUILD_TOOL
+ return nullptr;
+#else
+ auto result = std::make_shared<GitCAS>();
+
+ git_odb* odb_ptr{nullptr};
+ if (git_odb_new(&odb_ptr) != 0 or odb_ptr == nullptr) {
+ Logger::Log(LogLevel::Error,
+ "creating an empty database failed with:\n{}",
+ GitLastError());
+ return nullptr;
+ }
+ result->odb_.reset(odb_ptr); // retain odb pointer
+ return std::const_pointer_cast<GitCAS const>(result);
+#endif
+}
+
auto GitCAS::ReadObject(std::string const& id, bool is_hex_id) const noexcept
-> std::optional<std::string> {
#ifdef BOOTSTRAP_BUILD_TOOL
diff --git a/src/buildtool/file_system/git_cas.hpp b/src/buildtool/file_system/git_cas.hpp
index 78cb6d0c..f358e65b 100644
--- a/src/buildtool/file_system/git_cas.hpp
+++ b/src/buildtool/file_system/git_cas.hpp
@@ -24,6 +24,7 @@
#include <utility>
#include <vector>
+#include "gsl/gsl"
#include "src/buildtool/file_system/git_context.hpp"
#include "src/buildtool/file_system/git_utils.hpp"
@@ -36,6 +37,8 @@ class GitCAS {
[[nodiscard]] static auto Open(
std::filesystem::path const& repo_path) noexcept -> GitCASPtr;
+ [[nodiscard]] static auto CreateEmpty() noexcept -> GitCASPtr;
+
GitCAS() noexcept;
~GitCAS() noexcept = default;
@@ -45,6 +48,10 @@ class GitCAS {
auto operator=(GitCAS const&) = delete;
auto operator=(GitCAS&& other) = delete;
+ [[nodiscard]] auto GetODB() const noexcept -> gsl::not_null<git_odb*> {
+ return odb_.get();
+ }
+
/// \brief Read object from CAS.
/// \param id The object id.
/// \param is_hex_id Specify whether `id` is hex string or raw.
diff --git a/src/buildtool/file_system/git_repo.cpp b/src/buildtool/file_system/git_repo.cpp
index def30f6a..4a2fb626 100644
--- a/src/buildtool/file_system/git_repo.cpp
+++ b/src/buildtool/file_system/git_repo.cpp
@@ -1972,7 +1972,6 @@ auto GitRepo::ReadTreeData(
#ifndef BOOTSTRAP_BUILD_TOOL
try {
InMemoryODBBackend b{.parent = kInMemoryODBParent};
- auto cas = std::make_shared<GitCAS>();
if (auto raw_id =
is_hex_id ? FromHexString(id) : std::make_optional(id)) {
try {
@@ -1980,17 +1979,16 @@ auto GitRepo::ReadTreeData(
} catch (...) {
return std::nullopt;
}
- // create a GitCAS from a special-purpose in-memory object database.
- git_odb* odb_ptr{nullptr};
- if (git_odb_new(&odb_ptr) == 0 and
+ // create a GitCAS from a special-purpose in-memory object
+ // database.
+ auto cas = GitCAS::CreateEmpty();
+ if (cas != nullptr and
git_odb_add_backend(
- odb_ptr,
+ cas->GetODB(),
reinterpret_cast<git_odb_backend*>(&b), // NOLINT
0) == 0) {
- cas->odb_.reset(odb_ptr); // take ownership of odb
// wrap odb in "fake" repo
- auto repo =
- GitRepo(std::static_pointer_cast<GitCAS const>(cas));
+ auto repo = GitRepo(cas);
return repo.ReadTree(
*raw_id, check_symlinks, /*is_hex_id=*/false);
}
@@ -2008,17 +2006,14 @@ auto GitRepo::CreateShallowTree(tree_entries_t const& entries) noexcept
#ifndef BOOTSTRAP_BUILD_TOOL
try {
InMemoryODBBackend b{.parent = kInMemoryODBParent, .entries = &entries};
- auto cas = std::make_shared<GitCAS>();
- // create a GitCAS from a special-purpose in-memory object database.
- git_odb* odb_ptr{nullptr};
- if (git_odb_new(&odb_ptr) == 0 and
+ auto cas = GitCAS::CreateEmpty();
+ if (cas != nullptr and
git_odb_add_backend(
- odb_ptr,
+ cas->GetODB(),
reinterpret_cast<git_odb_backend*>(&b), // NOLINT
0) == 0) {
- cas->odb_.reset(odb_ptr); // take ownership of odb
// wrap odb in "fake" repo
- auto repo = GitRepo(std::static_pointer_cast<GitCAS const>(cas));
+ auto repo = GitRepo(cas);
if (auto raw_id = repo.CreateTree(entries)) {
// read result from in-memory trees
if (auto it = b.trees.find(*raw_id); it != b.trees.end()) {