git2wrap

C++20 wrapper for libgit2
git clone git://git.dimitrijedobrota.com/git2wrap.git
Log | Files | Refs | README | LICENSE | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit fba7c8793dbe2129753c41bc22592bae14cad7ce
parent 2a59455cc6610c767f3282ec599c234a0b2ea97c
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Mon, 6 Jan 2025 09:42:38 +0100

Consistency improvements

Diffstat:
M CMakeLists.txt | + -
M include/git2wrap/branch.hpp | +++++++++++++++++++++++++++ -
M include/git2wrap/reference.hpp | ++++++++ --
M include/git2wrap/repository.hpp | ++++++ ------------------------------
M source/branch.cpp | +++++++++++++++++++++++++++++++++
M source/reference.cpp | +++++++ --
M source/repository.cpp | ++++ --------------------------------------

7 files changed, 86 insertions(+), 74 deletions(-)


diff --git a/ CMakeLists.txt b/ CMakeLists.txt

@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)


project(
git2wrap
VERSION 0.1.4
VERSION 0.1.5
DESCRIPTION "C++ 20 wrapper for libgit2"
HOMEPAGE_URL "https://git.dimitrijedobrota.com/git2wrap.git"
LANGUAGES CXX

diff --git a/ include/git2wrap/branch.hpp b/ include/git2wrap/branch.hpp

@@ -15,7 +15,9 @@ public:

git_branch_t type = git_branch_t(0));

git_branch_t get_type() const { return m_type; }
git_reference* get_reference() const { return m_ref.get(); }

git_reference* get_reference() { return m_ref.get(); }
const git_reference* get_reference() const { return m_ref.get(); }

const std::string& get_name();

@@ -26,4 +28,28 @@ private:

std::string m_name;
};

class branch_iterator
{
public:
explicit branch_iterator(git_branch_iterator* iter = nullptr);

git_branch_iterator* get() { return m_iter.get(); }
const git_branch_iterator* get() const { return m_iter.get(); }

branch& operator*() { return m_branch; }
branch* operator->() { return &m_branch; }
branch_iterator& operator++();

friend bool operator==(const branch_iterator& lhs,
const branch_iterator& rhs);

friend bool operator!=(const branch_iterator& lhs,
const branch_iterator& rhs);

private:
using delete_f = std::function<void(git_branch_iterator*)>;
std::unique_ptr<git_branch_iterator, delete_f> m_iter;
branch m_branch;
};

} // namespace git2wrap

diff --git a/ include/git2wrap/reference.hpp b/ include/git2wrap/reference.hpp

@@ -14,11 +14,17 @@ class GIT2WRAP_EXPORT reference

{
public:
explicit reference(git_reference* ref = nullptr);
explicit operator bool() const { return m_ref != nullptr; }

git_reference* get() const;
git_reference* get() { return m_ref.get(); }
const git_reference* get() const { return m_ref.get(); }

friend bool operator==(const reference& lhs, const reference& rhs);
friend bool operator!=(const reference& lhs, const reference& rhs);

private:
std::unique_ptr<git_reference, std::function<void(git_reference*)>> m_ref;
using delete_f = std::function<void(git_reference*)>;
std::unique_ptr<git_reference, delete_f> m_ref;
};

} // namespace git2wrap

diff --git a/ include/git2wrap/repository.hpp b/ include/git2wrap/repository.hpp

@@ -18,6 +18,9 @@ public:

repository(const char* path, unsigned is_bare);
repository(const char* path, init_options* opts);

git_repository* get() { return m_repo.get(); }
const git_repository* get() const { return m_repo.get(); }

static repository clone(const char* url,
const char* local_path,
const clone_options* options);

@@ -27,39 +30,12 @@ public:

unsigned flags,
const char* ceiling_dirs);

struct branch_iterator
{
explicit branch_iterator(git_branch_iterator* iter);
branch_iterator() = default;

branch_iterator(const branch_iterator&) = delete;
branch_iterator& operator=(const branch_iterator&) = delete;

branch_iterator(branch_iterator&&) = default;
branch_iterator& operator=(branch_iterator&&) = default;

~branch_iterator();

branch& operator*() { return m_branch; }
branch* operator->() { return &m_branch; }
branch_iterator& operator++();

friend bool operator==(const branch_iterator& lhs,
const branch_iterator& rhs);

friend bool operator!=(const branch_iterator& lhs,
const branch_iterator& rhs);

private:
git_branch_iterator* m_iter = nullptr;
branch m_branch;
};

branch_iterator branch_begin(git_branch_t list_flags) const;
branch_iterator branch_begin(git_branch_t list_flags);
branch_iterator branch_end() const;

private:
std::unique_ptr<git_repository, std::function<void(git_repository*)>> m_repo;
using delete_f = std::function<void(git_repository*)>;
std::unique_ptr<git_repository, delete_f> m_repo;
};

} // namespace git2wrap

diff --git a/ source/branch.cpp b/ source/branch.cpp

@@ -25,4 +25,37 @@ const std::string& branch::get_name()

return m_name = name;
}

branch_iterator::branch_iterator(git_branch_iterator* iter)
: m_iter(iter, git_branch_iterator_free)
{
if (iter != nullptr) {
++*this;
}
}

branch_iterator& branch_iterator::operator++()
{
git_reference* ref = nullptr;
git_branch_t type = {};

if (auto err = git_branch_next(&ref, &type, get())) {
if (err != GIT_ITEROVER) {
throw error(err, git_error_last(), __FILE__, __LINE__);
}
}

m_branch = branch(ref, type);
return *this;
}

bool operator==(const branch_iterator& lhs, const branch_iterator& rhs)
{
return lhs.m_branch.get_reference() == rhs.m_branch.get_reference();
}

bool operator!=(const branch_iterator& lhs, const branch_iterator& rhs)
{
return !(lhs == rhs);
}

} // namespace git2wrap

diff --git a/ source/reference.cpp b/ source/reference.cpp

@@ -8,9 +8,14 @@ reference::reference(git_reference* ref)

{
}

git_reference* reference::get() const
bool operator==(const reference& lhs, const reference& rhs)
{
return m_ref.get();
return git_reference_cmp(lhs.get(), rhs.get()) == 0;
}

bool operator!=(const reference& lhs, const reference& rhs)
{
return git_reference_cmp(lhs.get(), rhs.get()) != 0;
}

} // namespace git2wrap

diff --git a/ source/repository.cpp b/ source/repository.cpp

@@ -69,54 +69,20 @@ repository repository::open(const char* path,

return repository(repo);
}

repository::branch_iterator::branch_iterator(git_branch_iterator* iter)
: m_iter(iter)
branch_iterator repository::branch_end() const // NOLINT
{
++*this;
return branch_iterator();
}

repository::branch_iterator::~branch_iterator()
{
git_branch_iterator_free(m_iter);
m_iter = nullptr;
}

repository::branch_iterator& repository::branch_iterator::operator++()
{
git_reference* ref = nullptr;
git_branch_t type = {};

if (auto err = git_branch_next(&ref, &type, m_iter)) {
if (err != GIT_ITEROVER) {
throw error(err, git_error_last(), __FILE__, __LINE__);
}
}

m_branch = branch(ref, type);
return *this;
}

repository::branch_iterator repository::branch_begin(
git_branch_t list_flags) const
branch_iterator repository::branch_begin(git_branch_t list_flags)
{
git_branch_iterator* iter = nullptr;

if (auto err = git_branch_iterator_new(&iter, m_repo.get(), list_flags)) {
if (auto err = git_branch_iterator_new(&iter, get(), list_flags)) {
throw error(err, git_error_last(), __FILE__, __LINE__);
}

return branch_iterator(iter);
}

repository::branch_iterator repository::branch_end() const // NOLINT
{
return {};
}

bool operator!=(const repository::branch_iterator& lhs,
const repository::branch_iterator& rhs)
{
return lhs.m_branch.get_reference() != rhs.m_branch.get_reference();
}

} // namespace git2wrap