Skip to content
Merged
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,12 @@ set(GIT2CPP_SRC
${GIT2CPP_SOURCE_DIR}/subcommand/checkout_subcommand.hpp
${GIT2CPP_SOURCE_DIR}/subcommand/clone_subcommand.cpp
${GIT2CPP_SOURCE_DIR}/subcommand/clone_subcommand.hpp
${GIT2CPP_SOURCE_DIR}/subcommand/commit_subcommand.cpp
${GIT2CPP_SOURCE_DIR}/subcommand/commit_subcommand.hpp
${GIT2CPP_SOURCE_DIR}/subcommand/init_subcommand.cpp
${GIT2CPP_SOURCE_DIR}/subcommand/init_subcommand.hpp
${GIT2CPP_SOURCE_DIR}/subcommand/reset_subcommand.cpp
${GIT2CPP_SOURCE_DIR}/subcommand/reset_subcommand.hpp
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.cpp
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.hpp
${GIT2CPP_SOURCE_DIR}/utils/common.cpp
Expand All @@ -69,6 +73,8 @@ set(GIT2CPP_SRC
${GIT2CPP_SOURCE_DIR}/wrapper/refs_wrapper.hpp
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.cpp
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.hpp
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.cpp
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.hpp
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.cpp
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.hpp
${GIT2CPP_SOURCE_DIR}/wrapper/wrapper_base.hpp
Expand Down
4 changes: 4 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@
#include "subcommand/branch_subcommand.hpp"
#include "subcommand/checkout_subcommand.hpp"
#include "subcommand/clone_subcommand.hpp"
#include "subcommand/commit_subcommand.hpp"
#include "subcommand/init_subcommand.hpp"
#include "subcommand/reset_subcommand.hpp"
#include "subcommand/status_subcommand.hpp"

int main(int argc, char** argv)
Expand All @@ -29,6 +31,8 @@ int main(int argc, char** argv)
branch_subcommand branch(lg2_obj, app);
checkout_subcommand checkout(lg2_obj, app);
clone_subcommand clone(lg2_obj, app);
commit_subcommand commit(lg2_obj, app);
reset_subcommand reset(lg2_obj, app);

app.require_subcommand(/* min */ 0, /* max */ 1);

Expand Down
2 changes: 2 additions & 0 deletions src/subcommand/add_subcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,11 @@ void add_subcommand::run()
if (m_all_flag)
{
index.add_all();
index.write();
}
else
{
index.add_entries(m_add_files);
index.write();
}
}
34 changes: 34 additions & 0 deletions src/subcommand/commit_subcommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#include <git2.h>
#include <unistd.h>

#include "commit_subcommand.hpp"
#include "../wrapper/index_wrapper.hpp"
#include "../wrapper/repository_wrapper.hpp"


commit_subcommand::commit_subcommand(const libgit2_object&, CLI::App& app)
{
auto *sub = app.add_subcommand("commit", "Record changes to the repository");

sub->add_option("commit_message", m_commit_message, "Commit message");

sub->add_flag("-m,--message", m_commit_message_flag, "");

sub->callback([this]() { this->run(); });
};


void commit_subcommand::run()
{
auto directory = get_current_git_path();
auto bare = false;
auto repo = repository_wrapper::init(directory, bare);
auto author_committer_signatures = signature_wrapper::get_default_signature_from_env(repo);

if (!m_commit_message_flag)
{
throw std::runtime_error("Please provide a message using the -m flag.");
}

repo.create_commit(author_committer_signatures, m_commit_message);
}
17 changes: 17 additions & 0 deletions src/subcommand/commit_subcommand.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include <CLI/CLI.hpp>

#include "../utils/common.hpp"

class commit_subcommand
{
public:

explicit commit_subcommand(const libgit2_object&, CLI::App& app);
void run();

private:
bool m_commit_message_flag = true; // TODO: change to false when a message can be provided if the "-m" flag is not provided
std::string m_commit_message;
};
61 changes: 61 additions & 0 deletions src/subcommand/reset_subcommand.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include "reset_subcommand.hpp"
// #include "../wrapper/index_wrapper.hpp"
#include "../wrapper/repository_wrapper.hpp"
#include <stdexcept>

enum class reset_type
{
GIT_RESET_SOFT = 1,
GIT_RESET_MIXED = 2,
GIT_RESET_HARD = 3
};

reset_subcommand::reset_subcommand(const libgit2_object&, CLI::App& app)
{
auto *sub = app.add_subcommand("reset", "Reset current HEAD to the specified state");

sub->add_option("<commit>", m_commit, "The ID of the commit that will become HEAD");

sub->add_flag("--soft", m_soft_flag, "");
sub->add_flag("--mixed", m_mixed_flag, "");
sub->add_flag("--hard", m_hard_flag, "");

sub->callback([this]() { this->run(); });
};


void reset_subcommand::run()
{
auto directory = get_current_git_path();
auto bare = false;
auto repo = repository_wrapper::init(directory, bare);

auto target = repo.revparse_single(m_commit);
if (!target)
{
throw std::runtime_error("Target revision not found.");
}

git_checkout_options options;
git_checkout_options_init(&options, GIT_CHECKOUT_OPTIONS_VERSION);

git_reset_t reset_type;
if (m_soft_flag)
{
reset_type = GIT_RESET_SOFT;
}
if (m_mixed_flag)
{
reset_type = GIT_RESET_MIXED;
}
if (m_hard_flag)
{
reset_type = GIT_RESET_HARD;
if (m_commit.empty())
{
m_commit = "HEAD";
}
}

repo.reset(target.value(), reset_type, options);
}
19 changes: 19 additions & 0 deletions src/subcommand/reset_subcommand.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include <CLI/CLI.hpp>

#include "../utils/common.hpp"

class reset_subcommand
{
public:

explicit reset_subcommand(const libgit2_object&, CLI::App& app);
void run();

private:
std::string m_commit;
bool m_soft_flag = false;
bool m_mixed_flag = false;
bool m_hard_flag = false;
};
1 change: 0 additions & 1 deletion src/wrapper/commit_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,3 @@ const git_oid& commit_wrapper::oid() const
{
return *git_commit_id(p_resource);
}

1 change: 1 addition & 0 deletions src/wrapper/commit_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <git2.h>

#include "../wrapper/repository_wrapper.hpp"
#include "../wrapper/wrapper_base.hpp"

class commit_wrapper : public wrapper_base<git_commit>
Expand Down
12 changes: 12 additions & 0 deletions src/wrapper/index_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,17 @@ void index_wrapper::add_impl(std::vector<std::string> patterns)
{
git_strarray_wrapper array{patterns};
throw_if_error(git_index_add_all(*this, array, 0, NULL, NULL));
// throw_if_error(git_index_write(*this));
}

void index_wrapper::write()
{
throw_if_error(git_index_write(*this));
}

git_oid index_wrapper::write_tree()
{
git_oid tree_id;
throw_if_error(git_index_write_tree(&tree_id, *this));
return tree_id;
}
3 changes: 3 additions & 0 deletions src/wrapper/index_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ class index_wrapper : public wrapper_base<git_index>

static index_wrapper init(repository_wrapper& rw);

void write();
git_oid write_tree();

void add_entries(std::vector<std::string> patterns);
void add_all();

Expand Down
5 changes: 5 additions & 0 deletions src/wrapper/object_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ const git_oid& object_wrapper::oid() const
{
return *git_object_id(*this);
}

object_wrapper::operator git_commit*() const noexcept
{
return reinterpret_cast<git_commit*>(p_resource);
}
2 changes: 2 additions & 0 deletions src/wrapper/object_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class object_wrapper : public wrapper_base<git_object>

const git_oid& oid() const;

operator git_commit*() const noexcept;

private:

object_wrapper(git_object* obj);
Expand Down
38 changes: 38 additions & 0 deletions src/wrapper/repository_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#include "../utils/git_exception.hpp"
#include "../wrapper/index_wrapper.hpp"
#include "../wrapper/object_wrapper.hpp"
#include "../wrapper/repository_wrapper.hpp"

repository_wrapper::~repository_wrapper()
Expand Down Expand Up @@ -107,6 +109,35 @@ commit_wrapper repository_wrapper::find_commit(const git_oid& id) const
return commit_wrapper(commit);
}

void repository_wrapper::create_commit(const signature_wrapper::author_committer_signatures& author_committer_signatures,
const std::string& message)
{
const char* message_encoding = "UTF-8";
git_oid commit_id;

std::string update_ref = "HEAD";
auto parent = revparse_single(update_ref);
std::size_t parent_count = 0;
const git_commit* parents[1] = {nullptr};
if (parent)
{
parent_count = 1;
parents[0] = *parent;
}

git_tree* tree;
index_wrapper index = this->make_index();
git_oid tree_id = index.write_tree();
index.write();

throw_if_error(git_tree_lookup(&tree, *this, &tree_id));

throw_if_error(git_commit_create(&commit_id, *this, update_ref.c_str(), author_committer_signatures.first, author_committer_signatures.second,
message_encoding, message.c_str(), tree, parent_count, parents));

git_tree_free(tree);
}

annotated_commit_wrapper repository_wrapper::find_annotated_commit(const git_oid& id) const
{
git_annotated_commit* commit;
Expand All @@ -130,3 +161,10 @@ void repository_wrapper::set_head_detached(const annotated_commit_wrapper& commi
{
throw_if_error(git_repository_set_head_detached_from_annotated(*this, commit));
}

void repository_wrapper::reset(const object_wrapper& target, git_reset_t reset_type, const git_checkout_options& checkout_options)
{
// TODO: gerer l'index

throw_if_error(git_reset(*this, target, reset_type, &checkout_options));
}
5 changes: 4 additions & 1 deletion src/wrapper/repository_wrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "../wrapper/index_wrapper.hpp"
#include "../wrapper/object_wrapper.hpp"
#include "../wrapper/refs_wrapper.hpp"
#include "../wrapper/signature_wrapper.hpp"
#include "../wrapper/wrapper_base.hpp"

class repository_wrapper : public wrapper_base<git_repository>
Expand Down Expand Up @@ -50,6 +51,7 @@ class repository_wrapper : public wrapper_base<git_repository>
// Commits
commit_wrapper find_commit(std::string_view ref_name = "HEAD") const;
commit_wrapper find_commit(const git_oid& id) const;
void create_commit(const signature_wrapper::author_committer_signatures&, const std::string&);

// Annotated commits
annotated_commit_wrapper find_annotated_commit(const git_oid& id) const;
Expand All @@ -60,9 +62,10 @@ class repository_wrapper : public wrapper_base<git_repository>
// Objects
std::optional<object_wrapper> revparse_single(std::string_view spec) const;

// Set head
// Head manipulations
void set_head(std::string_view ref_name);
void set_head_detached(const annotated_commit_wrapper& commit);
void reset(const object_wrapper& target, git_reset_t reset_type, const git_checkout_options& checkout_options);

private:

Expand Down
17 changes: 17 additions & 0 deletions src/wrapper/signature_wrapper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "../wrapper/repository_wrapper.hpp"
#include "../wrapper/signature_wrapper.hpp"
#include "../utils/git_exception.hpp"

signature_wrapper::~signature_wrapper()
{
git_signature_free(p_resource);
p_resource=nullptr;
}

signature_wrapper::author_committer_signatures signature_wrapper::get_default_signature_from_env(repository_wrapper& rw)
{
signature_wrapper author;
signature_wrapper committer;
throw_if_error(git_signature_default_from_env(&(author.p_resource), &(committer.p_resource), rw));
return {std::move(author), std::move(committer)};
}
26 changes: 26 additions & 0 deletions src/wrapper/signature_wrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include <utility>

#include <git2.h>

#include "../wrapper/wrapper_base.hpp"

class repository_wrapper;

class signature_wrapper : public wrapper_base<git_signature>
{
public:
using author_committer_signatures = std::pair<signature_wrapper, signature_wrapper>;

~signature_wrapper();

signature_wrapper(signature_wrapper&&) = default;
signature_wrapper& operator=(signature_wrapper&&) = default;

static author_committer_signatures get_default_signature_from_env(repository_wrapper&);

private:

signature_wrapper() = default;
};
2 changes: 1 addition & 1 deletion test/data/status_data/embedded_git/HEAD
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ref: refs/heads/main
ref: refs/heads/commit_test_branch
Binary file modified test/data/status_data/embedded_git/index
Binary file not shown.
16 changes: 16 additions & 0 deletions test/data/status_data/embedded_git/logs/HEAD
Original file line number Diff line number Diff line change
@@ -1,2 +1,18 @@
0000000000000000000000000000000000000000 75743dcbd85064226c77a0b862af817838ae0b2e Sandrine Pataut <[email protected]> 1750769952 +0200 commit (initial): first commit
75743dcbd85064226c77a0b862af817838ae0b2e ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1750771272 +0200 commit: Second commit
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from main to bla
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from bla to main
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from main to bla
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from bla to main
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from main to bla
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from bla to main
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from main to bla
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887403 +0200 checkout: moving from bla to main
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887505 +0200 checkout: moving from main to commit_test_branch
ee8c4cf874c4f1e3ba755f929fe7811018adee3d cba545ef5cc4ddf12a9744b6a49b20dda1ef1d5c Sandrine Pataut <[email protected]> 1753887505 +0200 commit: test commit
cba545ef5cc4ddf12a9744b6a49b20dda1ef1d5c ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887505 +0200 reset: moving to ee8c4cf874c4f1e3ba755f929fe7811018adee3d
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887505 +0200 checkout: moving from commit_test_branch to main
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753887505 +0200 checkout: moving from main to commit_test_branch
ee8c4cf874c4f1e3ba755f929fe7811018adee3d 75743dcbd85064226c77a0b862af817838ae0b2e Sandrine Pataut <[email protected]> 1753888486 +0200 reset: moving to 75743dcbd85064226c77a0b862af817838ae0b2e
75743dcbd85064226c77a0b862af817838ae0b2e ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753888486 +0200 checkout: moving from commit_test_branch to main
ee8c4cf874c4f1e3ba755f929fe7811018adee3d ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753888486 +0200 checkout: moving from main to commit_test_branch
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
0000000000000000000000000000000000000000 ee8c4cf874c4f1e3ba755f929fe7811018adee3d Sandrine Pataut <[email protected]> 1753888486 +0200 branch: Created from ee8c4cf874c4f1e3ba755f929fe7811018adee3d
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ee8c4cf874c4f1e3ba755f929fe7811018adee3d
Loading
Loading