SlHelpers
Loading...
Searching...
No Matches
Repo.h
1// SPDX-License-Identifier: GPL-2.0-only
2
3#pragma once
4
5#include <filesystem>
6#include <optional>
7#include <string>
8#include <variant>
9#include <vector>
10
11#include <git2.h>
12
13#include "../helpers/LastError.h"
14#include "../helpers/Unique.h"
15
16#include "DefaultFetchCallbacks.h"
17
18namespace SlGit {
19
20class Blob;
21class Commit;
22class Diff;
23class Index;
24class Object;
25class Reference;
26class Remote;
27class RevWalk;
28class Signature;
29class Tag;
30class Tree;
31class TreeBuilder;
32class TreeEntry;
33
45class Repo {
46 using GitTy = git_repository;
47 using Holder = SlHelpers::UniqueHolder<GitTy>;
48public:
49 Repo() = delete;
50
60 static std::optional<Repo> init(const std::filesystem::path &path, bool bare = false,
61 const std::string &originUrl = "") noexcept;
62
75 static std::optional<Repo> clone(const std::filesystem::path &path, const std::string &url,
77 const std::string &branch = "",
78 const unsigned int &depth = 0,
79 bool tags = true) noexcept;
91 static std::optional<Repo> clone(const std::filesystem::path &path, const std::string &url,
92 const std::string &branch = "",
93 const unsigned int &depth = 0,
94 bool tags = true) noexcept {
96 return clone(path, url, fc, branch, depth, tags);
97 }
98
104 static std::optional<Repo> open(const std::filesystem::path &path = ".") noexcept;
105
114 static bool update(const std::filesystem::path &path, const std::string &remote = "origin");
115
117 bool checkout(const std::string &branch) const noexcept;
119 bool checkout(const Reference &reference) const noexcept;
121 bool checkoutTree(const Tree &tree, unsigned int strategy = GIT_CHECKOUT_SAFE) const noexcept;
130 std::optional<std::string> catFile(const std::string &branch,
131 const std::string &file) const noexcept;
132
134 std::variant<Blob, Commit, Tag, Tree, std::monostate>
135 revparseSingle(const std::string &rev) const noexcept;
136
138 std::optional<Blob> blobCreateFromWorkDir(const std::filesystem::path &file) const noexcept;
140 std::optional<Blob> blobCreateFromDisk(const std::filesystem::path &file) const noexcept;
142 std::optional<Blob> blobCreateFromBuffer(const std::string &buf) const noexcept;
144 std::optional<Blob> blobLookup(const git_oid &oid) const noexcept;
146 std::optional<Blob> blobLookup(const TreeEntry &tentry) const noexcept;
148 std::optional<Blob> blobRevparseSingle(const std::string &rev) const noexcept;
149
151 std::optional<Commit> commitLookup(const git_oid &oid) const noexcept;
153 std::optional<Commit> commitCreate(const Signature &author, const Signature &committer,
154 const std::string &msg, const Tree &tree,
155 const std::vector<const Commit *> &parents = {}) const noexcept;
157 std::optional<Commit> commitCreateCheckout(const Signature &author,
158 const Signature &committer,
159 const std::string &msg, const Tree &tree,
160 unsigned int strategy = GIT_CHECKOUT_SAFE,
161 const std::vector<const Commit *> &parents = {}) const noexcept;
163 std::optional<Commit> commitHead() const noexcept;
165 std::optional<Commit> commitRevparseSingle(const std::string &rev) const noexcept;
166
169 std::optional<Diff> diff(const Commit &commit1, const Commit &commit2,
170 const git_diff_options *opts = nullptr) const noexcept;
173 std::optional<Diff> diff(const Tree &tree1, const Tree &tree2,
174 const git_diff_options *opts = nullptr) const noexcept;
177 std::optional<Diff> diffCached(const Commit &commit, const Index &index,
178 const git_diff_options *opts = nullptr) const noexcept;
181 std::optional<Diff> diffCached(const Tree &tree, const Index &index,
182 const git_diff_options *opts = nullptr) const noexcept;
184 std::optional<Diff> diffCached(const Commit &commit,
185 const git_diff_options *opts = nullptr) const noexcept;
187 std::optional<Diff> diffCached(const Tree &tree,
188 const git_diff_options *opts = nullptr) const noexcept;
191 std::optional<Diff> diffWorkdir(const Index &index,
192 const git_diff_options *opts = nullptr) const noexcept;
194 std::optional<Diff> diffWorkdir(const Commit &commit,
195 const git_diff_options *opts = nullptr) const noexcept;
197 std::optional<Diff> diffWorkdir(const Tree &tree,
198 const git_diff_options *opts = nullptr) const noexcept;
199
201 std::optional<Index> index() const noexcept;
202
204 std::optional<Remote> remoteCreate(const std::string &name,
205 const std::string &url) const noexcept;
207 std::optional<Remote> remoteLookup(const std::string &name) const noexcept;
208
210 std::optional<Reference> refLookup(const std::string &name) const noexcept;
212 std::optional<Reference> refDWIM(const std::string &name) const noexcept;
213
215 std::optional<Reference> refCreateDirect(const std::string &name, const git_oid &oid,
216 bool force = false) const noexcept;
218 std::optional<Reference> refCreateSymbolic(const std::string &name,
219 const std::string &target,
220 bool force = false) const noexcept;
221
223 std::optional<RevWalk> revWalkCreate() const noexcept;
224
226 std::optional<Tag> tagCreate(const std::string &tagName, const Object &target,
227 const Signature &tagger, const std::string &message,
228 bool force = false) const noexcept;
230 std::optional<Tag> tagLookup(const git_oid &oid) const noexcept;
232 std::optional<Tag> tagLookup(const TreeEntry &tentry) const noexcept;
234 std::optional<Tag> tagRevparseSingle(const std::string &rev) const noexcept;
235
237 std::optional<Tree> treeLookup(const git_oid &oid) const noexcept;
239 std::optional<Tree> treeLookup(const TreeEntry &tentry) const noexcept;
241 std::optional<Tree> treeRevparseSingle(const std::string &rev) const noexcept;
242
244 std::optional<TreeBuilder> treeBuilderCreate(const Tree *source = nullptr) const noexcept;
245
247 std::filesystem::path path() const noexcept { return git_repository_path(repo()); }
249 std::filesystem::path workDir() const noexcept { return git_repository_workdir(repo()); }
250
252 static auto &lastError() noexcept { return m_lastError.lastError(); }
254 static auto lastClass() noexcept { return m_lastError.get<0>(); }
256 static auto lastErrno() noexcept { return m_lastError.get<1>(); }
257
259 GitTy *repo() const noexcept { return m_repo.get(); }
261 operator GitTy *() const noexcept { return repo(); }
262private:
263 explicit Repo(GitTy *repo) noexcept : m_repo(repo) {}
264
265 friend class Diff;
266 friend class Index;
267 friend class PathSpec;
268 friend class Remote;
269 friend class RevWalk;
270 friend class Signature;
271 friend class Tag;
272 friend class Tree;
273 friend class TreeBuilder;
274
275 static std::pair<std::string, int> lastGitError() noexcept;
276
277 static int setLastError(int ret) {
278 if (ret) {
279 auto le = lastGitError();
280 m_lastError.reset().setError(std::move(le.first));
281 m_lastError.set<0>(le.second);
282 m_lastError.set<1>(ret);
283 }
284
285 return ret;
286 }
287
288 template<class Class, typename FunTy, typename... Args>
289 static std::optional<Class> MakeGit(const FunTy &fun, Args&&... args)
290 {
291 typename Class::GitTy *gitEntry;
292 if (setLastError(fun(&gitEntry, std::forward<Args>(args)...)))
293 return std::nullopt;
294 return Class(gitEntry);
295 }
296
297 template<class Class, typename FunTy, typename... Args>
298 static std::optional<Class> MakeGitRepo(const Repo &repo, const FunTy &fun, Args&&... args)
299 {
300 typename Class::GitTy *gitEntry;
301 if (setLastError(fun(&gitEntry, std::forward<Args>(args)...)))
302 return std::nullopt;
303 return Class(repo, gitEntry);
304 }
305
306 static void checkoutProgress(const char *path, size_t completed_steps, size_t total_steps,
307 void *payload);
308
309 Holder m_repo;
310 static thread_local SlHelpers::LastErrorStr<int, int> m_lastError;
311};
312
313}
Blob is a representation of a git blob.
Definition Blob.h:16
Commit is a representation of a git commit.
Definition Commit.h:21
The default FetchCallbacks implementation.
Definition DefaultFetchCallbacks.h:15
Diff is a representation of a git diff.
Definition Diff.h:21
Callbacks invoked from Repo::clone() or Remote::fetchRefspecs().
Definition FetchCallbacks.h:17
Index is a representation of a git index.
Definition Index.h:78
Git Object class – base for Blob, Commit, Tag, Tree.
Definition Object.h:20
Reference is a representation of a git reference.
Definition Misc.h:18
Remote is a representation of a git remote.
Definition Remote.h:21
The most important Git class.
Definition Repo.h:45
GitTy * repo() const noexcept
Get the underlying libgit2 pointer.
Definition Repo.h:259
std::optional< Blob > blobCreateFromWorkDir(const std::filesystem::path &file) const noexcept
Create a new Blob from file in workdir.
std::optional< Index > index() const noexcept
Get repository's index.
std::optional< Diff > diffCached(const Commit &commit, const Index &index, const git_diff_options *opts=nullptr) const noexcept
Create a new Diff of a commit and index.
std::optional< Commit > commitHead() const noexcept
Get a Commit corresponding to HEAD.
std::optional< Reference > refCreateSymbolic(const std::string &name, const std::string &target, bool force=false) const noexcept
Create a new symbolic Reference to target called name.
static std::optional< Repo > open(const std::filesystem::path &path=".") noexcept
Open an existing repository.
static auto lastClass() noexcept
Return the last error class (from git_last_error()).
Definition Repo.h:254
std::filesystem::path path() const noexcept
Get the path to .git.
Definition Repo.h:247
std::optional< Commit > commitLookup(const git_oid &oid) const noexcept
Get a Commit corresponding to oid.
std::optional< Remote > remoteLookup(const std::string &name) const noexcept
Get a Remote called name.
static std::optional< Repo > clone(const std::filesystem::path &path, const std::string &url, FetchCallbacks &fc, const std::string &branch="", const unsigned int &depth=0, bool tags=true) noexcept
clone Clone (and open) an existing repository
bool checkoutTree(const Tree &tree, unsigned int strategy=GIT_CHECKOUT_SAFE) const noexcept
Update index and files to match tree.
std::optional< Diff > diff(const Commit &commit1, const Commit &commit2, const git_diff_options *opts=nullptr) const noexcept
Create a new Diff of commit1 and commit2.
std::optional< Commit > commitCreate(const Signature &author, const Signature &committer, const std::string &msg, const Tree &tree, const std::vector< const Commit * > &parents={}) const noexcept
Create a new Commit.
std::optional< RevWalk > revWalkCreate() const noexcept
Create a new RevWalk.
std::optional< Tag > tagLookup(const git_oid &oid) const noexcept
Get a Tag corresponding to oid.
std::optional< Tag > tagRevparseSingle(const std::string &rev) const noexcept
Parse rev as tag.
std::optional< Blob > blobCreateFromBuffer(const std::string &buf) const noexcept
Create a new Blob from string buf.
bool checkout(const std::string &branch) const noexcept
Checkout a branch.
std::optional< Reference > refDWIM(const std::string &name) const noexcept
Get a Reference called name (like master).
std::optional< Tree > treeRevparseSingle(const std::string &rev) const noexcept
Parse rev as tree.
std::optional< Reference > refLookup(const std::string &name) const noexcept
Get a Reference called exactly name (like refs/heads/master).
std::optional< Blob > blobCreateFromDisk(const std::filesystem::path &file) const noexcept
Create a new Blob from file.
std::optional< Tag > tagCreate(const std::string &tagName, const Object &target, const Signature &tagger, const std::string &message, bool force=false) const noexcept
Create a new Tag called tagName, pointing at target.
std::optional< Tree > treeLookup(const git_oid &oid) const noexcept
Get a Tree corresponding to oid.
std::optional< Reference > refCreateDirect(const std::string &name, const git_oid &oid, bool force=false) const noexcept
Create a new direct Reference to oid called name.
static std::optional< Repo > init(const std::filesystem::path &path, bool bare=false, const std::string &originUrl="") noexcept
init Init an empty repository
std::optional< Blob > blobLookup(const git_oid &oid) const noexcept
Get a Blob corresponding to oid.
std::optional< Diff > diffWorkdir(const Index &index, const git_diff_options *opts=nullptr) const noexcept
Create a new Diff of an index and workdir.
static auto lastErrno() noexcept
Return the last error number (returned from git_* functions).
Definition Repo.h:256
static bool update(const std::filesystem::path &path, const std::string &remote="origin")
Update/fetch remote remote in repository at path.
std::optional< Commit > commitRevparseSingle(const std::string &rev) const noexcept
Parse rev as commit.
std::filesystem::path workDir() const noexcept
Get the path to sources.
Definition Repo.h:249
static auto & lastError() noexcept
Return the last error string if some (from git_last_error()).
Definition Repo.h:252
std::variant< Blob, Commit, Tag, Tree, std::monostate > revparseSingle(const std::string &rev) const noexcept
Parse rev as either blob, commit, tag, or tree.
std::optional< std::string > catFile(const std::string &branch, const std::string &file) const noexcept
Cat a file in a branch.
std::optional< Remote > remoteCreate(const std::string &name, const std::string &url) const noexcept
Create a new Remote called name located at url.
std::optional< Commit > commitCreateCheckout(const Signature &author, const Signature &committer, const std::string &msg, const Tree &tree, unsigned int strategy=GIT_CHECKOUT_SAFE, const std::vector< const Commit * > &parents={}) const noexcept
Create a new Commit and move to it.
std::optional< TreeBuilder > treeBuilderCreate(const Tree *source=nullptr) const noexcept
Create a new TreeBuilder.
std::optional< Blob > blobRevparseSingle(const std::string &rev) const noexcept
Parse rev as blob.
RevWalk is a representation of a git revwalk.
Definition Misc.h:55
Signature is a representation of a git signature.
Definition Misc.h:120
Tag is a representation of a git tag.
Definition Tag.h:23
The TreeEntry represents a libgit2's tree builder.
Definition Tree.h:64
The TreeEntry represents one git tree entry.
Definition Tree.h:107
Tree is a representation of a git tree.
Definition Tree.h:27
void set(Arg &&val) noexcept
Set n-th error member.
Definition LastError.h:34
void setError(T &&str)
Store a string into this error.
Definition LastError.h:66
LastErrorStr & reset() noexcept
Wipe out everything.
Definition LastError.h:55
Wrapper around std::unique_ptr for easier re-definition of free.
Definition Unique.h:41