Skip to content

Commit b977235

Browse files
committed
add commit subcommand
1 parent dbd11b0 commit b977235

11 files changed

+160
-1
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ set(GIT2CPP_SRC
4747
${GIT2CPP_SOURCE_DIR}/subcommand/checkout_subcommand.hpp
4848
${GIT2CPP_SOURCE_DIR}/subcommand/clone_subcommand.cpp
4949
${GIT2CPP_SOURCE_DIR}/subcommand/clone_subcommand.hpp
50+
${GIT2CPP_SOURCE_DIR}/subcommand/commit_subcommand.cpp
51+
${GIT2CPP_SOURCE_DIR}/subcommand/commit_subcommand.hpp
5052
${GIT2CPP_SOURCE_DIR}/subcommand/init_subcommand.cpp
5153
${GIT2CPP_SOURCE_DIR}/subcommand/init_subcommand.hpp
5254
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.cpp
@@ -69,6 +71,8 @@ set(GIT2CPP_SRC
6971
${GIT2CPP_SOURCE_DIR}/wrapper/refs_wrapper.hpp
7072
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.cpp
7173
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.hpp
74+
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.cpp
75+
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.hpp
7276
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.cpp
7377
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.hpp
7478
${GIT2CPP_SOURCE_DIR}/wrapper/wrapper_base.hpp
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#include <git2.h>
2+
#include <unistd.h>
3+
4+
#include "commit_subcommand.hpp"
5+
#include "../wrapper/index_wrapper.hpp"
6+
#include "../wrapper/repository_wrapper.hpp"
7+
8+
9+
commit_subcommand::commit_subcommand(const libgit2_object&, CLI::App& app)
10+
{
11+
auto *sub = app.add_subcommand("commit", "Record changes to the repository");
12+
13+
sub->add_option("message", m_message, "Commit message");
14+
15+
sub->add_flag("-m,--message", m_message_flag, "");
16+
17+
sub->callback([this]() { this->run(); });
18+
};
19+
20+
21+
void commit_subcommand::run()
22+
{
23+
auto directory = get_current_git_path();
24+
auto bare = false;
25+
auto repo = repository_wrapper::init(directory, bare);
26+
auto author_committer_signatures = signature_wrapper::get_default_signature_from_env(repo);
27+
28+
if (!m_message_flag)
29+
{
30+
std::cout << "Please provide a message using the -m flag." << std::endl;
31+
}
32+
else
33+
{
34+
repo.create_commit(author_committer_signatures, m_message);
35+
}
36+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include <CLI/CLI.hpp>
4+
5+
#include "../utils/common.hpp"
6+
7+
class commit_subcommand
8+
{
9+
public:
10+
11+
explicit commit_subcommand(const libgit2_object&, CLI::App& app);
12+
void run();
13+
14+
private:
15+
bool m_message_flag = true; // TODO: change to false when a message can be provided if the "-m" flag is not provided
16+
std::string m_message;
17+
};

src/wrapper/commit_wrapper.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,3 @@ const git_oid& commit_wrapper::oid() const
2020
{
2121
return *git_commit_id(p_resource);
2222
}
23-

src/wrapper/commit_wrapper.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <git2.h>
44

5+
#include "../wrapper/repository_wrapper.hpp"
56
#include "../wrapper/wrapper_base.hpp"
67

78
class commit_wrapper : public wrapper_base<git_commit>

src/wrapper/object_wrapper.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ class object_wrapper : public wrapper_base<git_object>
1717

1818
const git_oid& oid() const;
1919

20+
operator git_commit*() const noexcept;
21+
2022
private:
2123

2224
object_wrapper(git_object* obj);

src/wrapper/repository_wrapper.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ commit_wrapper repository_wrapper::find_commit(const git_oid& id) const
107107
return commit_wrapper(commit);
108108
}
109109

110+
void repository_wrapper::create_commit(const signature_wrapper::author_committer_signatures& author_committer_signatures,
111+
const std::string& message)
112+
{
113+
git_oid* commit_id;
114+
const char* update_ref = "ḦEAD";
115+
auto parent = revparse_single(update_ref);
116+
std::size_t parent_count = 0;
117+
const git_commit* parents[1] = {nullptr};
118+
if (parent)
119+
{
120+
parent_count = 1;
121+
parents[0] = *parent;
122+
}
123+
const char* message_encoding = "UTF-8";
124+
const git_tree* tree;
125+
throw_if_error(git_commit_create(commit_id, *this, update_ref, author_committer_signatures.first, author_committer_signatures.second,
126+
message_encoding, message.c_str(), tree, parent_count, parents));
127+
}
128+
110129
annotated_commit_wrapper repository_wrapper::find_annotated_commit(const git_oid& id) const
111130
{
112131
git_annotated_commit* commit;

src/wrapper/repository_wrapper.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "../wrapper/index_wrapper.hpp"
1414
#include "../wrapper/object_wrapper.hpp"
1515
#include "../wrapper/refs_wrapper.hpp"
16+
#include "../wrapper/signature_wrapper.hpp"
1617
#include "../wrapper/wrapper_base.hpp"
1718

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

5456
// Annotated commits
5557
annotated_commit_wrapper find_annotated_commit(const git_oid& id) const;

src/wrapper/signature_wrapper.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#include "../wrapper/repository_wrapper.hpp"
2+
#include "../wrapper/signature_wrapper.hpp"
3+
#include "../utils/git_exception.hpp"
4+
5+
signature_wrapper::~signature_wrapper()
6+
{
7+
git_signature_free(p_resource);
8+
p_resource=nullptr;
9+
}
10+
11+
signature_wrapper::author_committer_signatures signature_wrapper::get_default_signature_from_env(repository_wrapper& rw)
12+
{
13+
signature_wrapper author;
14+
signature_wrapper committer;
15+
throw_if_error(git_signature_default_from_env(&(author.p_resource), &(committer.p_resource), rw));
16+
return {std::move(author), std::move(committer)};
17+
}

src/wrapper/signature_wrapper.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#include <utility>
4+
5+
#include <git2.h>
6+
7+
#include "../wrapper/wrapper_base.hpp"
8+
9+
class repository_wrapper;
10+
11+
class signature_wrapper : public wrapper_base<git_signature>
12+
{
13+
public:
14+
using author_committer_signatures = std::pair<signature_wrapper, signature_wrapper>;
15+
16+
~signature_wrapper();
17+
18+
signature_wrapper(signature_wrapper&&) = default;
19+
signature_wrapper& operator=(signature_wrapper&&) = default;
20+
21+
static author_committer_signatures get_default_signature_from_env(repository_wrapper&);
22+
23+
private:
24+
25+
signature_wrapper() = default;
26+
};

0 commit comments

Comments
 (0)