src/git_repo.h
browsing at commit = d2d178cea97e3d1912849cb39f9d24332cce0d5d
#pragma once
#include <cstdint>
#include <ctime>
#include <stdexcept>
#include <string>
#include <vector>
struct git_repository;
// Thrown for any libgit2 failure or invalid lookup. Handlers translate this
// into an HTTP error response.
class GitError : public std::runtime_error {
public:
explicit GitError(const std::string &what) : std::runtime_error(what) {}
};
struct TreeEntry {
std::string name; // last path component
std::string path; // full path relative to repo root
std::string oid; // hex object id
bool is_dir = false; // tree
bool is_submodule = false;
uint64_t size = 0; // blob size in bytes (0 for non-blobs)
};
struct CommitInfo {
std::string oid;
std::string short_oid;
std::string summary;
std::string author_name;
std::string author_email;
std::time_t time = 0;
};
struct BlameLine {
int number = 0; // 1-based line number
std::string short_oid; // commit that last touched the line
std::string author;
std::time_t time = 0;
std::string content; // the line text (without newline)
};
struct TagInfo {
std::string name;
std::string target_oid; // commit the tag resolves to
std::string short_oid;
std::time_t time = 0;
bool annotated = false;
};
struct BranchInfo {
std::string name;
std::string target_oid; // commit the branch points at
std::string short_oid;
std::time_t time = 0;
bool is_default = false; // true for the repository's HEAD branch
};
struct TagDetail {
std::string name;
std::string target_oid;
std::string short_oid;
bool annotated = false;
std::string tagger_name;
std::time_t time = 0;
std::string message;
};
struct FileChange {
char status = '?'; // A, M, D, R, C, T
std::string path;
std::string old_path; // set for renames/copies
};
struct DiffLine {
std::string css; // CSS class: d-add, d-del, d-hunk, d-file, d-ctx
std::string content; // line text (with +/- prefix for code lines)
};
struct CommitDetail {
std::string oid;
std::string short_oid;
std::string author_name;
std::string author_email;
std::time_t time = 0;
std::string message;
std::vector<std::string> parents;
std::string first_parent; // "" for a root commit; used for "before" links
std::vector<FileChange> files;
std::vector<DiffLine> diff;
};
enum class ObjectKind { Blob, Tree, Commit, Tag, Unknown };
struct ObjectView {
ObjectKind kind = ObjectKind::Unknown;
std::string oid;
std::string type_name;
std::string body; // textual summary or blob preview
bool is_binary = false;
std::vector<TreeEntry> entries; // populated for trees
};
// libgit2 process-wide init/shutdown. Construct exactly once in main().
class GitLibrary {
public:
GitLibrary();
~GitLibrary();
GitLibrary(const GitLibrary &) = delete;
GitLibrary &operator=(const GitLibrary &) = delete;
};
// Wraps a single opened repository. Not thread safe: open one per request.
class GitRepo {
public:
explicit GitRepo(const std::string &path);
~GitRepo();
GitRepo(const GitRepo &) = delete;
GitRepo &operator=(const GitRepo &) = delete;
// Short name of the default branch (HEAD), e.g. "main".
std::string default_branch() const;
// Resolve a revision to a full commit oid. Empty id means HEAD.
std::string resolve_commit(const std::string &id) const;
// Directory listing of `path` ("" = root) at the given commit.
std::vector<TreeEntry> list_tree(const std::string &commit_oid,
const std::string &path) const;
// Read a blob located at `path` within the commit tree.
// Returns false if no such path exists.
bool read_file(const std::string &commit_oid, const std::string &path,
std::string &out, bool &is_binary) const;
// First README* file at the root of the commit tree, or "" if none.
std::string find_readme(const std::string &commit_oid) const;
std::vector<BlameLine> blame(const std::string &commit_oid,
const std::string &path) const;
std::vector<CommitInfo> log(const std::string &start_oid, int limit) const;
// All tags, sorted by name.
std::vector<TagInfo> tags() const;
// Names of tags whose target commit is `commit_oid`, sorted by name.
std::vector<std::string> tags_for_commit(const std::string &commit_oid) const;
// Details of a single tag by short name (e.g. "v1.0").
TagDetail tag_detail(const std::string &name) const;
// All local branches, sorted by name.
std::vector<BranchInfo> branches() const;
// Local branches whose history contains `commit_oid`, sorted by name.
std::vector<BranchInfo> branches_for_commit(const std::string &commit_oid) const;
// Commit metadata plus the diff against its first parent.
CommitDetail commit_detail(const std::string &oid) const;
// The commit's diff as a raw unified patch.
std::string commit_patch(const std::string &oid) const;
// Inspect an arbitrary object by (possibly abbreviated) oid.
ObjectView inspect(const std::string &oid) const;
private:
git_repository *repo_ = nullptr;
};