diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/buildtool/file_system/TARGETS | 2 | ||||
-rw-r--r-- | src/buildtool/file_system/git_cas.cpp | 18 | ||||
-rw-r--r-- | src/buildtool/file_system/git_cas.hpp | 7 | ||||
-rw-r--r-- | src/buildtool/file_system/git_repo.cpp | 25 |
4 files changed, 36 insertions, 16 deletions
diff --git a/src/buildtool/file_system/TARGETS b/src/buildtool/file_system/TARGETS index c676cb8b..41b9772e 100644 --- a/src/buildtool/file_system/TARGETS +++ b/src/buildtool/file_system/TARGETS @@ -70,7 +70,7 @@ , "name": ["git_cas"] , "hdrs": ["git_cas.hpp"] , "srcs": ["git_cas.cpp"] - , "deps": ["git_utils", "object_type"] + , "deps": ["git_utils", "object_type", ["@", "gsl", "", "gsl"]] , "stage": ["src", "buildtool", "file_system"] , "private-deps": [ "git_context" diff --git a/src/buildtool/file_system/git_cas.cpp b/src/buildtool/file_system/git_cas.cpp index 2d1c4c33..69fc8922 100644 --- a/src/buildtool/file_system/git_cas.cpp +++ b/src/buildtool/file_system/git_cas.cpp @@ -108,6 +108,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 8751b1e6..10a43111 100644 --- a/src/buildtool/file_system/git_cas.hpp +++ b/src/buildtool/file_system/git_cas.hpp @@ -23,6 +23,7 @@ #include <string> #include <utility> +#include "gsl/gsl" #include "src/buildtool/file_system/git_utils.hpp" #include "src/buildtool/file_system/object_type.hpp" @@ -35,6 +36,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; @@ -44,6 +47,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 ccb888c7..f43a1f5f 100644 --- a/src/buildtool/file_system/git_repo.cpp +++ b/src/buildtool/file_system/git_repo.cpp @@ -1975,7 +1975,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 { @@ -1983,17 +1982,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); } @@ -2011,17 +2009,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()) { |