Program Listing for File gitWrapper.cpp
↰ Return to documentation for file (include/editor/featureWrapper/GitWrap/gitWrapper.cpp
)
#include "gitWrapper.hpp"
#include "PDJE_LOG_SETTER.hpp"
#include "editorCommit.hpp"
#include "git2/commit.h"
#include "git2/oid.h"
#include <chrono>
#include <sstream>
#include <string>
// #include "CommitFinder.hpp"
MAYBE_BLAME
GitWrapper::Blame(const fs::path &filepath,
const gitwrap::commit &newCommit,
const gitwrap::commit &oldCommit)
{
auto newBlame = BlameController();
git_blame_options opts;
git_blame_options_init(&opts, GIT_BLAME_OPTIONS_VERSION);
opts.newest_commit = newCommit.commitID;
opts.oldest_commit = oldCommit.commitID;
if (newBlame.BlameOpen(repo, filepath, &opts)) {
return std::move(newBlame);
} else {
critlog("failed to blame. from GitWrapper Blame. gitLog: ");
critlog(git_error_last()->message);
return std::nullopt;
}
}
DiffResult
GitWrapper::diff(const gitwrap::commit &oldCommit,
const gitwrap::commit &newCommit)
{
auto DiffHandle = DiffController();
DiffResult results;
if (oldCommit.commitPointer == nullptr) {
critlog("old commit pointer is null. from GitWrapper diff.");
return results;
}
if (newCommit.commitPointer != nullptr) {
if (!DiffHandle.CommitToCommit(
repo, newCommit.commitID, oldCommit.commitID)) {
critlog("failed to diff commit to commit. from GitWrapper diff. "
"gitLog: ");
critlog(git_error_last()->message);
return results;
}
} else {
if (!DiffHandle.CommitToNow(repo, oldCommit.commitID)) {
critlog(
"failed to diff commit to now. from GitWrapper diff. gitLog: ");
critlog(git_error_last()->message);
return results;
}
}
DiffHandle.execute(&results);
return results;
}
bool
GitWrapper::add(const fs::path &path)
{
if (addIndex.has_value()) {
addIndex.reset();
}
addIndex.emplace();
if (!addIndex->open(repo)) {
critlog("failed to open repo. from GitWrapper add. gitLog: ");
critlog(git_error_last()->message);
return false;
}
if (!addIndex->addFile(path)) {
critlog("failed to add file. from GitWrapper add. gitLog: ");
critlog(git_error_last()->message);
return false;
}
return true;
}
bool
GitWrapper::open(const fs::path &path)
{
auto safeStr = path.generic_string();
if (git_repository_open(&repo, safeStr.c_str()) == 0) {
handleBranch.emplace(repo);
return true;
} else {
auto res = git_repository_init(&repo, safeStr.c_str(), false);
if (res == 0) {
handleBranch.emplace(repo);
return true;
} else {
critlog("failed to open & init repository. from GitWrapper open. "
"gitLog: ");
critlog(git_error_last()->message);
return false;
}
}
}
bool
GitWrapper::close()
{
if (repo == nullptr) {
warnlog("failed to close. repo is nullptr. from GitWrapper close. "
"gitLog: ");
warnlog(git_error_last()->message);
return false;
}
git_repository_free(repo);
repo = nullptr;
return true;
}
GitWrapper::GitWrapper()
{
git_libgit2_init();
}
GitWrapper::~GitWrapper()
{
if (repo != nullptr) {
git_repository_free(repo);
}
if (addIndex.has_value()) {
addIndex.reset();
}
git_libgit2_shutdown();
}
bool
GitWrapper::commit(git_signature *sign, const DONT_SANITIZE &message)
{
git_oid tree_id, commit_id, parent_id;
git_tree *tree = nullptr;
git_commit *parent_commit = nullptr;
bool result = false;
if (!handleBranch.has_value()) {
critlog("handleBranch has no value. from GitWrapper commit. gitLog: ");
critlog(git_error_last()->message);
return false;
}
if (handleBranch->FLAG_TEMP_CHECKOUT.has_value()) {
auto tempcommit = gitwrap::commit();
git_commit_lookup(&(tempcommit.commitPointer),
repo,
&(handleBranch->FLAG_TEMP_CHECKOUT.value()));
handleBranch->MakeNewFromCommit(tempcommit, GenTimeStamp());
}
if (!addIndex.has_value()) {
critlog("failed because addIndex has no value. from GitWrapper commit. "
"gitLog: ");
critlog(git_error_last()->message);
goto cleanup;
}
if (git_index_write_tree(&tree_id, addIndex->index) != 0) {
critlog("failed because index write tree failed. from GitWrapper "
"commit. gitLog: ");
critlog(git_error_last()->message);
goto cleanup;
}
if (git_tree_lookup(&tree, repo, &tree_id) != 0) {
critlog("failed because lookup tree failed. from GitWrapper commit. "
"gitLog: ");
critlog(git_error_last()->message);
goto cleanup;
}
// 부모 커밋이 있는 경우
if (git_reference_name_to_id(&parent_id, repo, "HEAD") == 0 &&
git_commit_lookup(&parent_commit, repo, &parent_id) == 0) {
// const git_commit* parents[1] = { parent_commit };
if (git_commit_create_v(&commit_id,
repo,
"HEAD",
sign,
sign,
nullptr,
message.c_str(),
tree,
1,
parent_commit) == 0) {
result = true;
}
} else {
// 최초 커밋(부모 없음)
if (git_commit_create_v(&commit_id,
repo,
"HEAD",
sign,
sign,
nullptr,
message.c_str(),
tree,
0) == 0) {
result = true;
}
}
cleanup:
if (tree)
git_tree_free(tree);
if (parent_commit)
git_commit_free(parent_commit);
addIndex.reset();
if (!result) {
critlog("something failed. from GitWrapper commit. gitLog: ");
critlog(git_error_last()->message);
}
return result;
}
bool
GitWrapper::log()
{
if (!log_hdl.has_value()) {
log_hdl.emplace(repo);
}
if (!handleBranch.has_value()) {
critlog("handleBranch has no value. from GitWrapper log. gitLog: ");
critlog(git_error_last()->message);
return false;
}
auto branches = handleBranch->ShowExistBranch();
for (auto &i : branches) {
if (!log_hdl->WalkBranch(i)) {
critlog("walkBranch failed. from GitWrapper log. gitLog: ");
critlog(git_error_last()->message);
return false;
}
}
return true;
}
bool
GitWrapper::log(const DONT_SANITIZE &branchName)
{
if (!log_hdl.has_value()) {
log_hdl.emplace(repo);
}
if (!log_hdl->WalkBranch(branchName)) {
critlog("walkBranch failed. from GitWrapper log(branchName). gitLog: ");
critlog(git_error_last()->message);
return false;
}
return true;
}
DONT_SANITIZE
GitWrapper::GenTimeStamp()
{
using namespace std::chrono;
auto now = system_clock::now();
std::time_t tt = system_clock::to_time_t(now);
std::tm tm{};
#if defined(_WIN32)
localtime_s(&tm, &tt);
#else
localtime_r(&tt, &tm);
#endif
auto ms = duration_cast<milliseconds>(now - system_clock::from_time_t(tt))
.count();
std::ostringstream oss;
oss << std::put_time(&tm, "%Y-%m-%d %H:%M:%S");
oss << '.' << std::setw(3) << std::setfill('0') << ms;
return oss.str();
}