Skip to content

Commit c2b35cb

Browse files
authored
Add commit and reset subcommand (#29)
* add commit subcommand * add reset subcommand * write index * fix * small fix * test commit * update test * remove test file * fix test * add branch to test * edit branch name * remove mook test file * test commit * edit file path * address review comments * edit option * remove extra space
1 parent c578198 commit c2b35cb

28 files changed

+314
-4
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,12 @@ 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
54+
${GIT2CPP_SOURCE_DIR}/subcommand/reset_subcommand.cpp
55+
${GIT2CPP_SOURCE_DIR}/subcommand/reset_subcommand.hpp
5256
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.cpp
5357
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.hpp
5458
${GIT2CPP_SOURCE_DIR}/utils/common.cpp
@@ -70,6 +74,8 @@ set(GIT2CPP_SRC
7074
${GIT2CPP_SOURCE_DIR}/wrapper/refs_wrapper.hpp
7175
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.cpp
7276
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.hpp
77+
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.cpp
78+
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.hpp
7379
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.cpp
7480
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.hpp
7581
${GIT2CPP_SOURCE_DIR}/wrapper/wrapper_base.hpp

src/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
#include "subcommand/branch_subcommand.hpp"
99
#include "subcommand/checkout_subcommand.hpp"
1010
#include "subcommand/clone_subcommand.hpp"
11+
#include "subcommand/commit_subcommand.hpp"
1112
#include "subcommand/init_subcommand.hpp"
13+
#include "subcommand/reset_subcommand.hpp"
1214
#include "subcommand/status_subcommand.hpp"
1315

1416
int main(int argc, char** argv)
@@ -29,6 +31,8 @@ int main(int argc, char** argv)
2931
branch_subcommand branch(lg2_obj, app);
3032
checkout_subcommand checkout(lg2_obj, app);
3133
clone_subcommand clone(lg2_obj, app);
34+
commit_subcommand commit(lg2_obj, app);
35+
reset_subcommand reset(lg2_obj, app);
3236

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

src/subcommand/add_subcommand.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ void add_subcommand::run()
3131
if (m_all_flag)
3232
{
3333
index.add_all();
34+
index.write();
3435
}
3536
else
3637
{
3738
index.add_entries(m_add_files);
39+
index.write();
3840
}
3941
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
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("-m,--message", m_commit_message, "Commit message");
14+
15+
sub->callback([this]() { this->run(); });
16+
};
17+
18+
19+
void commit_subcommand::run()
20+
{
21+
auto directory = get_current_git_path();
22+
auto bare = false;
23+
auto repo = repository_wrapper::init(directory, bare);
24+
auto author_committer_signatures = signature_wrapper::get_default_signature_from_env(repo);
25+
26+
if (m_commit_message.empty())
27+
{
28+
std::cout << "Please enter a commit message:" << std::endl;
29+
std::getline(std::cin, m_commit_message);
30+
if (m_commit_message.empty())
31+
{
32+
throw std::runtime_error("Aborting, no commit message specified.");
33+
}
34+
}
35+
36+
repo.create_commit(author_committer_signatures, m_commit_message);
37+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
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+
std::string m_commit_message;
16+
};
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#include "reset_subcommand.hpp"
2+
// #include "../wrapper/index_wrapper.hpp"
3+
#include "../wrapper/repository_wrapper.hpp"
4+
#include <stdexcept>
5+
6+
enum class reset_type
7+
{
8+
GIT_RESET_SOFT = 1,
9+
GIT_RESET_MIXED = 2,
10+
GIT_RESET_HARD = 3
11+
};
12+
13+
reset_subcommand::reset_subcommand(const libgit2_object&, CLI::App& app)
14+
{
15+
auto *sub = app.add_subcommand("reset", "Reset current HEAD to the specified state");
16+
17+
sub->add_option("<commit>", m_commit, "The ID of the commit that will become HEAD");
18+
19+
sub->add_flag("--soft", m_soft_flag, "");
20+
sub->add_flag("--mixed", m_mixed_flag, "");
21+
sub->add_flag("--hard", m_hard_flag, "");
22+
23+
sub->callback([this]() { this->run(); });
24+
};
25+
26+
27+
void reset_subcommand::run()
28+
{
29+
auto directory = get_current_git_path();
30+
auto bare = false;
31+
auto repo = repository_wrapper::init(directory, bare);
32+
33+
auto target = repo.revparse_single(m_commit);
34+
if (!target)
35+
{
36+
throw std::runtime_error("Target revision not found.");
37+
}
38+
39+
git_checkout_options options;
40+
git_checkout_options_init(&options, GIT_CHECKOUT_OPTIONS_VERSION);
41+
42+
git_reset_t reset_type;
43+
if (m_soft_flag)
44+
{
45+
reset_type = GIT_RESET_SOFT;
46+
}
47+
if (m_mixed_flag)
48+
{
49+
reset_type = GIT_RESET_MIXED;
50+
}
51+
if (m_hard_flag)
52+
{
53+
reset_type = GIT_RESET_HARD;
54+
if (m_commit.empty())
55+
{
56+
m_commit = "HEAD";
57+
}
58+
}
59+
60+
repo.reset(target.value(), reset_type, options);
61+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
#include <CLI/CLI.hpp>
4+
5+
#include "../utils/common.hpp"
6+
7+
class reset_subcommand
8+
{
9+
public:
10+
11+
explicit reset_subcommand(const libgit2_object&, CLI::App& app);
12+
void run();
13+
14+
private:
15+
std::string m_commit;
16+
bool m_soft_flag = false;
17+
bool m_mixed_flag = false;
18+
bool m_hard_flag = false;
19+
};

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/index_wrapper.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,17 @@ void index_wrapper::add_impl(std::vector<std::string> patterns)
3232
{
3333
git_strarray_wrapper array{patterns};
3434
throw_if_error(git_index_add_all(*this, array, 0, NULL, NULL));
35+
// throw_if_error(git_index_write(*this));
36+
}
37+
38+
void index_wrapper::write()
39+
{
3540
throw_if_error(git_index_write(*this));
3641
}
42+
43+
git_oid index_wrapper::write_tree()
44+
{
45+
git_oid tree_id;
46+
throw_if_error(git_index_write_tree(&tree_id, *this));
47+
return tree_id;
48+
}

0 commit comments

Comments
 (0)