From aa8635c6863646f5df78b54832f51db16aac25ba Mon Sep 17 00:00:00 2001 From: Maksim Denisov Date: Tue, 14 Jan 2025 17:59:01 +0100 Subject: TreeStructureUtils: export from git --- .../tree_structure/tree_structure_utils.cpp | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) (limited to 'src/buildtool/tree_structure/tree_structure_utils.cpp') diff --git a/src/buildtool/tree_structure/tree_structure_utils.cpp b/src/buildtool/tree_structure/tree_structure_utils.cpp index b607cb9f..7cc04b6f 100644 --- a/src/buildtool/tree_structure/tree_structure_utils.cpp +++ b/src/buildtool/tree_structure/tree_structure_utils.cpp @@ -15,6 +15,7 @@ #include "src/buildtool/tree_structure/tree_structure_utils.hpp" #include +#include #include #include #include @@ -27,7 +28,9 @@ #include "src/buildtool/common/artifact.hpp" #include "src/buildtool/common/artifact_digest_factory.hpp" #include "src/buildtool/common/protocol_traits.hpp" +#include "src/buildtool/common/repository_config.hpp" #include "src/buildtool/crypto/hash_function.hpp" +#include "src/buildtool/execution_api/git/git_api.hpp" #include "src/buildtool/file_system/file_system_manager.hpp" #include "src/buildtool/file_system/git_repo.hpp" #include "src/buildtool/file_system/object_type.hpp" @@ -198,3 +201,38 @@ auto TreeStructureUtils::ImportToGit( } return *digest; } + +auto TreeStructureUtils::ExportFromGit( + ArtifactDigest const& tree, + std::vector const& source_repos, + IExecutionApi const& target_api) noexcept -> expected { + if (not tree.IsTree() or not ProtocolTraits::IsNative(tree.GetHashType())) { + return unexpected{fmt::format("Not a git tree: {}", tree.hash())}; + } + + // Find git repo that contains the tree: + std::filesystem::path const* repo = nullptr; + for (std::size_t i = 0; i < source_repos.size() and repo == nullptr; ++i) { + auto in_repo = GitRepo::IsTreeInRepo(source_repos[i], tree.hash()); + if (not in_repo.has_value()) { + return unexpected{std::move(in_repo).error()}; + } + if (*in_repo) { + repo = &source_repos[i]; + } + } + + // Check that at least one repo contains the tree: + if (repo == nullptr) { + return false; + } + + RepositoryConfig repo_config{}; + if (not repo_config.SetGitCAS(*repo)) { + return unexpected{ + fmt::format("Failed to set git cas at {}", repo->string())}; + } + auto const git_api = GitApi{&repo_config}; + return git_api.RetrieveToCas({Artifact::ObjectInfo{tree, ObjectType::Tree}}, + target_api); +} -- cgit v1.2.3