Skip to content

Commit 2f4d8e6

Browse files
authored
Add rev-list (#69)
* Add rev-list * Add revwalk wrapper * Small fix in log and status
1 parent 1cd32b6 commit 2f4d8e6

13 files changed

+239
-54
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ set(GIT2CPP_SRC
6464
${GIT2CPP_SOURCE_DIR}/subcommand/remote_subcommand.hpp
6565
${GIT2CPP_SOURCE_DIR}/subcommand/reset_subcommand.cpp
6666
${GIT2CPP_SOURCE_DIR}/subcommand/reset_subcommand.hpp
67+
${GIT2CPP_SOURCE_DIR}/subcommand/revlist_subcommand.cpp
68+
${GIT2CPP_SOURCE_DIR}/subcommand/revlist_subcommand.hpp
6769
${GIT2CPP_SOURCE_DIR}/subcommand/revparse_subcommand.cpp
6870
${GIT2CPP_SOURCE_DIR}/subcommand/revparse_subcommand.hpp
6971
${GIT2CPP_SOURCE_DIR}/subcommand/status_subcommand.cpp
@@ -96,6 +98,8 @@ set(GIT2CPP_SRC
9698
${GIT2CPP_SOURCE_DIR}/wrapper/remote_wrapper.hpp
9799
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.cpp
98100
${GIT2CPP_SOURCE_DIR}/wrapper/repository_wrapper.hpp
101+
${GIT2CPP_SOURCE_DIR}/wrapper/revwalk_wrapper.cpp
102+
${GIT2CPP_SOURCE_DIR}/wrapper/revwalk_wrapper.hpp
99103
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.cpp
100104
${GIT2CPP_SOURCE_DIR}/wrapper/signature_wrapper.hpp
101105
${GIT2CPP_SOURCE_DIR}/wrapper/status_wrapper.cpp

src/main.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "subcommand/reset_subcommand.hpp"
2020
#include "subcommand/status_subcommand.hpp"
2121
#include "subcommand/revparse_subcommand.hpp"
22+
#include "subcommand/revlist_subcommand.hpp"
2223

2324
int main(int argc, char** argv)
2425
{
@@ -45,7 +46,8 @@ int main(int argc, char** argv)
4546
merge_subcommand merge(lg2_obj, app);
4647
push_subcommand push(lg2_obj, app);
4748
remote_subcommand remote(lg2_obj, app);
48-
revparse_subcommand rev(lg2_obj, app);
49+
revparse_subcommand revparse(lg2_obj, app);
50+
revlist_subcommand revlist(lg2_obj, app);
4951

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

src/subcommand/log_subcommand.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,22 +87,25 @@ void log_subcommand::run()
8787
auto repo = repository_wrapper::open(directory);
8888
// auto branch_name = repo.head().short_name();
8989

90-
git_revwalk* walker;
91-
git_revwalk_new(&walker, repo);
92-
git_revwalk_push_head(walker);
90+
if (repo.is_head_unborn())
91+
{
92+
std::cout << "fatal: your current branch 'main' does not have any commits yet" << std::endl;
93+
return;
94+
}
95+
96+
revwalk_wrapper walker = repo.new_walker();
97+
walker.push_head();
9398

9499
terminal_pager pager;
95100

96101
std::size_t i=0;
97102
git_oid commit_oid;
98-
while (!git_revwalk_next(&commit_oid, walker) && i<m_max_count_flag)
103+
while (!walker.next(commit_oid) && i<m_max_count_flag)
99104
{
100105
commit_wrapper commit = repo.find_commit(commit_oid);
101106
print_commit(commit, m_format_flag);
102107
++i;
103108
}
104109

105-
git_revwalk_free(walker);
106-
107110
pager.show();
108111
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "revlist_subcommand.hpp"
2+
#include "../wrapper/repository_wrapper.hpp"
3+
#include "../wrapper/revwalk_wrapper.hpp"
4+
5+
revlist_subcommand::revlist_subcommand(const libgit2_object&, CLI::App& app)
6+
{
7+
auto* sub = app.add_subcommand("rev-list", "Lists commit objects in reverse chronological order");
8+
9+
sub->add_option("<commit>", m_commit, "");
10+
sub->add_option("-n,--max-count", m_max_count_flag, "Limit the output to <number> commits.");
11+
12+
sub->callback([this]() { this->run(); });
13+
}
14+
15+
void revlist_subcommand::run()
16+
{
17+
if (m_commit.empty())
18+
{
19+
throw std::runtime_error("usage: git rev-list [<options>] <commit>... [--] [<path>...]"); // TODO: add help info
20+
}
21+
22+
auto directory = get_current_git_path();
23+
auto repo = repository_wrapper::open(directory);
24+
git_oid start_commit_oid;
25+
int not_sha1 = git_oid_fromstrp(&start_commit_oid, m_commit.c_str());
26+
if (not_sha1)
27+
{
28+
commit_wrapper start_commit = repo.find_commit(m_commit);
29+
start_commit_oid = start_commit.oid();
30+
}
31+
32+
revwalk_wrapper walker = repo.new_walker();
33+
walker.push(start_commit_oid);
34+
35+
std::size_t i=0;
36+
git_oid commit_oid;
37+
char buf[GIT_OID_SHA1_HEXSIZE + 1];
38+
while (!walker.next(commit_oid) && i<m_max_count_flag)
39+
{
40+
git_oid_fmt(buf, &commit_oid);
41+
buf[GIT_OID_SHA1_HEXSIZE] = '\0';
42+
std::cout << buf << std::endl;
43+
++i;
44+
}
45+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include <CLI/CLI.hpp>
4+
#include <string>
5+
6+
#include "../utils/common.hpp"
7+
8+
class revlist_subcommand
9+
{
10+
public:
11+
12+
explicit revlist_subcommand(const libgit2_object&, CLI::App& app);
13+
void run();
14+
15+
private:
16+
17+
std::string m_commit;
18+
int m_max_count_flag=std::numeric_limits<int>::max();
19+
20+
};

src/subcommand/status_subcommand.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ void status_subcommand::run()
194194
{
195195
std::cout << "On branch " << branch_name << "\n" << std::endl;
196196

197+
if (repo.is_head_unborn())
198+
{
199+
std::cout << "No commits yet\n" << std::endl;
200+
}
201+
197202
if (sl.has_unmerged_header())
198203
{
199204
std::cout << "You have unmerged paths.\n (fix conflicts and run \"git commit\")\n (use \"git merge --abort\" to abort the merge)\n" << std::endl;
@@ -274,6 +279,9 @@ void status_subcommand::run()
274279
// TODO: check if this message should be displayed even if there are untracked files
275280
if (!(sl.has_tobecommited_header() | sl.has_notstagged_header() | sl.has_unmerged_header() | sl.has_untracked_header()))
276281
{
277-
std::cout << treeclean_message << std::endl;
282+
if (is_long)
283+
{
284+
std::cout << treeclean_message << std::endl;
285+
}
278286
}
279287
}

src/wrapper/repository_wrapper.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
11
#include <iostream>
22

3-
#include "../utils/git_exception.hpp"
4-
#include "../wrapper/index_wrapper.hpp"
5-
#include "../wrapper/object_wrapper.hpp"
6-
#include "../wrapper/commit_wrapper.hpp"
7-
#include "../wrapper/remote_wrapper.hpp"
8-
#include <git2/repository.h>
9-
#include <git2/remote.h>
103
#include "../wrapper/repository_wrapper.hpp"
114

125
repository_wrapper::~repository_wrapper()
@@ -56,6 +49,13 @@ bool repository_wrapper::is_shallow() const
5649
return git_repository_is_shallow(*this);
5750
}
5851

52+
revwalk_wrapper repository_wrapper::new_walker()
53+
{
54+
git_revwalk* walker;
55+
throw_if_error(git_revwalk_new(&walker, *this));
56+
return revwalk_wrapper(walker);
57+
}
58+
5959
// Head
6060

6161
bool repository_wrapper::is_head_unborn() const

src/wrapper/repository_wrapper.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "../wrapper/object_wrapper.hpp"
1515
#include "../wrapper/refs_wrapper.hpp"
1616
#include "../wrapper/remote_wrapper.hpp"
17+
#include "../wrapper/revwalk_wrapper.hpp"
1718
#include "../wrapper/signature_wrapper.hpp"
1819
#include "../wrapper/wrapper_base.hpp"
1920

@@ -36,6 +37,8 @@ class repository_wrapper : public wrapper_base<git_repository>
3637
bool is_bare() const;
3738
bool is_shallow() const;
3839

40+
revwalk_wrapper new_walker();
41+
3942
// Head
4043
bool is_head_unborn() const;
4144
reference_wrapper head() const;

src/wrapper/revwalk_wrapper.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include <git2/index.h>
2+
#include <git2/types.h>
3+
4+
#include "revwalk_wrapper.hpp"
5+
#include "../utils/git_exception.hpp"
6+
7+
revwalk_wrapper::revwalk_wrapper(git_revwalk* walker)
8+
: base_type(walker)
9+
{
10+
}
11+
12+
revwalk_wrapper::~revwalk_wrapper()
13+
{
14+
git_revwalk_free(p_resource);
15+
p_resource=nullptr;
16+
}
17+
18+
void revwalk_wrapper::push_head()
19+
{
20+
throw_if_error(git_revwalk_push_head(*this));
21+
}
22+
23+
void revwalk_wrapper::push(git_oid& commit_oid)
24+
{
25+
throw_if_error(git_revwalk_push(*this, &commit_oid));
26+
}
27+
28+
int revwalk_wrapper::next(git_oid& commit_oid)
29+
{
30+
return git_revwalk_next(&commit_oid, *this);
31+
}

src/wrapper/revwalk_wrapper.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#pragma once
2+
3+
#include <git2.h>
4+
#include <git2/types.h>
5+
6+
#include "../wrapper/wrapper_base.hpp"
7+
#include "../wrapper/commit_wrapper.hpp"
8+
9+
class revwalk_wrapper : public wrapper_base<git_revwalk>
10+
{
11+
public:
12+
13+
using base_type = wrapper_base<git_revwalk>;
14+
15+
~revwalk_wrapper();
16+
17+
revwalk_wrapper(revwalk_wrapper&&) noexcept = default;
18+
revwalk_wrapper& operator=(revwalk_wrapper&&) noexcept = default;
19+
20+
void push_head();
21+
void push(git_oid& commit_oid);
22+
int next(git_oid& commit_oid);
23+
24+
private:
25+
26+
revwalk_wrapper(git_revwalk* walker);
27+
28+
friend class repository_wrapper;
29+
};

0 commit comments

Comments
 (0)