summaryrefslogtreecommitdiff
path: root/src/buildtool/file_system/git_repo.cpp
diff options
context:
space:
mode:
authorPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2024-08-13 18:01:50 +0200
committerPaul Cristian Sarbu <paul.cristian.sarbu@huawei.com>2024-08-26 11:36:35 +0200
commita312e71b59340f7b6d8dc5aac9202137ae81d02b (patch)
tree0601795d12487a2d8e4e87704f9592fd00e8bd08 /src/buildtool/file_system/git_repo.cpp
parentd7f6ca59d2e2713efe40c96e2c6522f6d86180d2 (diff)
downloadjustbuild-a312e71b59340f7b6d8dc5aac9202137ae81d02b.tar.gz
GitRepo: Change logic that creates commits to explicitly give directory
In preparation for subsequent changes, specify the directory path containing the tree content to be committed explicitly. This change will allow eventually to be able to specify paths that are different from the root path of the repository in which the commit is created. This commit renames and refactors StageAndCommitAllAnnonymous to allow a directory path to be passed. The just-mr and serve service logic is updated such that current behaviour is otherwise unchanged.
Diffstat (limited to 'src/buildtool/file_system/git_repo.cpp')
-rw-r--r--src/buildtool/file_system/git_repo.cpp46
1 files changed, 31 insertions, 15 deletions
diff --git a/src/buildtool/file_system/git_repo.cpp b/src/buildtool/file_system/git_repo.cpp
index d378a2ba..11c5a569 100644
--- a/src/buildtool/file_system/git_repo.cpp
+++ b/src/buildtool/file_system/git_repo.cpp
@@ -591,8 +591,9 @@ auto GitRepo::GetGitOdb() const noexcept
return git_cas_->odb_;
}
-auto GitRepo::StageAndCommitAllAnonymous(std::string const& message,
- anon_logger_ptr const& logger) noexcept
+auto GitRepo::CommitDirectory(std::filesystem::path const& dir,
+ std::string const& message,
+ anon_logger_ptr const& logger) noexcept
-> std::optional<std::string> {
#ifdef BOOTSTRAP_BUILD_TOOL
return std::nullopt;
@@ -600,7 +601,7 @@ auto GitRepo::StageAndCommitAllAnonymous(std::string const& message,
try {
// only possible for real repository!
if (IsRepoFake()) {
- (*logger)("cannot stage and commit files using a fake repository!",
+ (*logger)("cannot commit directory using a fake repository!",
true /*fatal*/);
return std::nullopt;
}
@@ -610,11 +611,23 @@ auto GitRepo::StageAndCommitAllAnonymous(std::string const& message,
// cannot perform this operation on a bare repository; this has to be
// checked because git_index_add_bypath will not do it for us!
if (not FileSystemManager::Exists(GetGitPath() / ".git")) {
- (*logger)("cannot stage and commit files in a bare repository!",
+ (*logger)("cannot commit directory in a bare repository!",
true /*fatal*/);
return std::nullopt;
}
+ // the index approach to adding entries requires them to be reachable
+ // from root path
+ auto rel_path = dir.lexically_relative(GetGitPath());
+ if (rel_path.empty() or rel_path.string().starts_with("..")) {
+ (*logger)(
+ fmt::format("unsupported directory {}: not a subpath of {}",
+ dir.string(),
+ GetGitPath().string()),
+ true /*fatal*/);
+ return std::nullopt;
+ }
+
// add all files to be staged
git_index* index_ptr{nullptr};
git_repository_index(&index_ptr, repo_->Ptr());
@@ -624,19 +637,23 @@ auto GitRepo::StageAndCommitAllAnonymous(std::string const& message,
// due to mismanagement of .gitignore rules by libgit2 when doing a
// forced add all, we resort to using git_index_add_bypath manually for
// all entries, instead of git_index_add_all with GIT_INDEX_ADD_FORCE.
- auto use_entry = [&index](std::filesystem::path const& name,
- bool is_tree) {
+ auto use_entry = [&index, rel_path](std::filesystem::path const& name,
+ bool is_tree) {
return is_tree or
- git_index_add_bypath(index.get(), name.c_str()) == 0;
+ git_index_add_bypath(
+ index.get(),
+ (rel_path / name)
+ .lexically_relative(".") // remove "." prefix
+ .c_str()) == 0;
};
if (not FileSystemManager::ReadDirectoryEntriesRecursive(
- GetGitPath(),
+ dir,
use_entry,
/*ignored_subdirs=*/{".git"})) {
- (*logger)(fmt::format(
- "staging files in git repository {} failed with:\n{}",
- GetGitPath().string(),
- GitLastError()),
+ (*logger)(fmt::format("staging entries in git repository {} failed "
+ "with:\n{}",
+ GetGitPath().string(),
+ GitLastError()),
true /*fatal*/);
return std::nullopt;
}
@@ -711,9 +728,8 @@ auto GitRepo::StageAndCommitAllAnonymous(std::string const& message,
git_buf_dispose(&buffer);
return commit_hash; // success!
} catch (std::exception const& ex) {
- Logger::Log(LogLevel::Error,
- "stage and commit all failed with:\n{}",
- ex.what());
+ Logger::Log(
+ LogLevel::Error, "commit subdir failed with:\n{}", ex.what());
return std::nullopt;
}
#endif // BOOTSTRAP_BUILD_TOOL