summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/buildtool/file_system/TARGETS10
-rw-r--r--src/buildtool/file_system/git_cas.cpp46
-rw-r--r--src/buildtool/file_system/git_cas.hpp8
-rw-r--r--src/buildtool/file_system/git_context.cpp37
-rw-r--r--src/buildtool/file_system/git_context.hpp36
5 files changed, 104 insertions, 33 deletions
diff --git a/src/buildtool/file_system/TARGETS b/src/buildtool/file_system/TARGETS
index 20a1aab9..3bc4471e 100644
--- a/src/buildtool/file_system/TARGETS
+++ b/src/buildtool/file_system/TARGETS
@@ -29,7 +29,7 @@
, "name": ["git_cas"]
, "hdrs": ["git_cas.hpp"]
, "srcs": ["git_cas.cpp"]
- , "deps": ["object_type", ["@", "gsl-lite", "", "gsl-lite"]]
+ , "deps": ["object_type", "git_context", ["@", "gsl-lite", "", "gsl-lite"]]
, "stage": ["src", "buildtool", "file_system"]
, "private-deps":
[ "file_system_manager"
@@ -57,6 +57,14 @@
, ["src/buildtool/logging", "logging"]
]
}
+, "git_context":
+ { "type": ["@", "rules", "CC", "library"]
+ , "name": ["git_context"]
+ , "hdrs": ["git_context.hpp"]
+ , "srcs": ["git_context.cpp"]
+ , "stage": ["src", "buildtool", "file_system"]
+ , "private-deps": [["src/buildtool/logging", "logging"], ["", "libgit2"]]
+ }
, "file_root":
{ "type": ["@", "rules", "CC", "library"]
, "name": ["file_root"]
diff --git a/src/buildtool/file_system/git_cas.cpp b/src/buildtool/file_system/git_cas.cpp
index 799068f2..d1ea0870 100644
--- a/src/buildtool/file_system/git_cas.cpp
+++ b/src/buildtool/file_system/git_cas.cpp
@@ -317,22 +317,12 @@ auto GitCAS::Open(std::filesystem::path const& repo_path) noexcept
return nullptr;
}
-GitCAS::GitCAS() noexcept {
-#ifndef BOOTSTRAP_BUILD_TOOL
- if (not(initialized_ = (git_libgit2_init() >= 0))) {
- Logger::Log(LogLevel::Error, "initializing libgit2 failed");
- }
-#endif
-}
GitCAS::~GitCAS() noexcept {
#ifndef BOOTSTRAP_BUILD_TOOL
if (odb_ != nullptr) {
git_odb_free(odb_);
odb_ = nullptr;
}
- if (initialized_) {
- git_libgit2_shutdown();
- }
#endif
}
@@ -341,7 +331,7 @@ auto GitCAS::ReadObject(std::string const& id, bool is_hex_id) const noexcept
#ifdef BOOTSTRAP_BUILD_TOOL
return std::nullopt;
#else
- if (not initialized_) {
+ if (odb_ == nullptr) {
return std::nullopt;
}
@@ -419,7 +409,7 @@ auto GitCAS::ReadTree(std::string const& id, bool is_hex_id) const noexcept
auto GitCAS::ReadHeader(std::string const& id, bool is_hex_id) const noexcept
-> std::optional<std::pair<std::size_t, ObjectType>> {
#ifndef BOOTSTRAP_BUILD_TOOL
- if (not initialized_) {
+ if (odb_ == nullptr) {
return std::nullopt;
}
@@ -507,29 +497,27 @@ auto GitCAS::OpenODB(std::filesystem::path const& repo_path) noexcept -> bool {
#ifdef BOOTSTRAP_BUILD_TOOL
return false;
#else
- if (initialized_) {
- { // lock as git_repository API has no thread-safety guarantees
- std::unique_lock lock{repo_mutex};
- git_repository* repo = nullptr;
- if (git_repository_open(&repo, repo_path.c_str()) != 0) {
- Logger::Log(LogLevel::Error,
- "opening git repository {} failed with:\n{}",
- repo_path.string(),
- GitLastError());
- return false;
- }
- git_repository_odb(&odb_, repo);
- git_repository_free(repo);
- }
- if (odb_ == nullptr) {
+ { // lock as git_repository API has no thread-safety guarantees
+ std::unique_lock lock{repo_mutex};
+ git_repository* repo = nullptr;
+ if (git_repository_open(&repo, repo_path.c_str()) != 0) {
Logger::Log(LogLevel::Error,
- "obtaining git object database {} failed with:\n{}",
+ "opening git repository {} failed with:\n{}",
repo_path.string(),
GitLastError());
return false;
}
+ git_repository_odb(&odb_, repo);
+ git_repository_free(repo);
+ }
+ if (odb_ == nullptr) {
+ Logger::Log(LogLevel::Error,
+ "obtaining git object database {} failed with:\n{}",
+ repo_path.string(),
+ GitLastError());
+ return false;
}
- return initialized_;
+ return true;
#endif
}
diff --git a/src/buildtool/file_system/git_cas.hpp b/src/buildtool/file_system/git_cas.hpp
index 26acc52f..3670d188 100644
--- a/src/buildtool/file_system/git_cas.hpp
+++ b/src/buildtool/file_system/git_cas.hpp
@@ -21,6 +21,7 @@
#include <unordered_map>
#include <vector>
+#include "src/buildtool/file_system/git_context.hpp"
#include "src/buildtool/file_system/object_type.hpp"
extern "C" {
@@ -30,7 +31,7 @@ using git_odb = struct git_odb;
class GitCAS;
using GitCASPtr = std::shared_ptr<GitCAS const>;
-/// \brief Git CAS that maintains its own libgit2 global state.
+/// \brief Git CAS that maintains its Git context.
class GitCAS {
public:
// Stores the data for defining a single Git tree entry, which consists of
@@ -55,7 +56,7 @@ class GitCAS {
static auto Open(std::filesystem::path const& repo_path) noexcept
-> GitCASPtr;
- GitCAS() noexcept;
+ GitCAS() noexcept = default;
~GitCAS() noexcept;
// prohibit moves and copies
@@ -123,8 +124,9 @@ class GitCAS {
-> std::optional<std::pair<std::string, std::string>>;
private:
+ // IMPORTANT: the GitContext needs to be initialized before any git object!
+ GitContext git_context_{}; // maintains a Git context while CAS is alive
git_odb* odb_{nullptr};
- bool initialized_{false};
[[nodiscard]] auto OpenODB(std::filesystem::path const& repo_path) noexcept
-> bool;
diff --git a/src/buildtool/file_system/git_context.cpp b/src/buildtool/file_system/git_context.cpp
new file mode 100644
index 00000000..04d4498d
--- /dev/null
+++ b/src/buildtool/file_system/git_context.cpp
@@ -0,0 +1,37 @@
+// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "src/buildtool/file_system/git_context.hpp"
+
+#include "src/buildtool/logging/logger.hpp"
+
+extern "C" {
+#include <git2.h>
+}
+
+GitContext::GitContext() noexcept {
+#ifndef BOOTSTRAP_BUILD_TOOL
+ if (not(initialized_ = (git_libgit2_init() >= 0))) {
+ Logger::Log(LogLevel::Error, "initializing libgit2 failed");
+ }
+#endif
+}
+
+GitContext::~GitContext() noexcept {
+#ifndef BOOTSTRAP_BUILD_TOOL
+ if (initialized_) {
+ git_libgit2_shutdown();
+ }
+#endif
+} \ No newline at end of file
diff --git a/src/buildtool/file_system/git_context.hpp b/src/buildtool/file_system/git_context.hpp
new file mode 100644
index 00000000..d6aaeab6
--- /dev/null
+++ b/src/buildtool/file_system/git_context.hpp
@@ -0,0 +1,36 @@
+// Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef INCLUDED_SRC_BUILDTOOL_FILE_SYSTEM_GIT_CONTEXT_HPP
+#define INCLUDED_SRC_BUILDTOOL_FILE_SYSTEM_GIT_CONTEXT_HPP
+
+/// \brief Maintainer of a libgit2 state.
+/// Classes, static methods, and global functions dealing with Git operations
+/// should create a GitContext before using Git operations.
+class GitContext {
+ public:
+ // prohibit moves and copies
+ GitContext(GitContext const&) = delete;
+ GitContext(GitContext&& other) = delete;
+ auto operator=(GitContext const&) = delete;
+ auto operator=(GitContext&& other) = delete;
+
+ GitContext() noexcept;
+ ~GitContext() noexcept;
+
+ private:
+ bool initialized_{false};
+};
+
+#endif // INCLUDED_SRC_BUILDTOOL_FILE_SYSTEM_GIT_CONTEXT_HPP \ No newline at end of file