SlHelpers
Index.h
1 // SPDX-License-Identifier: GPL-2.0-only
2 
3 #pragma once
4 
5 #include <filesystem>
6 #include <functional>
7 #include <optional>
8 #include <string>
9 #include <vector>
10 
11 #include <git2.h>
12 
13 #include "../helpers/Unique.h"
14 #include "Repo.h"
15 
16 namespace SlGit {
17 
18 class Tree;
19 
24  using GitTy = git_index_iterator;
26 
27  friend class Index;
28  friend class Repo;
29 public:
32  increment();
33  return *this;
34  }
35  IndexIterator operator++(int) = delete;
36 
37  IndexIterator &operator--() = delete;
38  IndexIterator operator--(int) = delete;
39 
41  bool operator ==(const IndexIterator &other) const noexcept {
42  return m_current == other.m_current;
43  }
45  bool operator !=(const IndexIterator &other) const noexcept {
46  return !(*this == other);
47  }
49  const git_index_entry &operator *() const noexcept { return *m_current; }
51  const git_index_entry *operator ->() const noexcept { return m_current; }
52 
54  std::string path() const noexcept { return m_current->path; }
56  std::string_view pathSV() const noexcept { return m_current->path; }
57 
59  GitTy *iterator() const noexcept { return m_iterator.get(); }
61  operator GitTy *() const noexcept { return iterator(); }
62 private:
63  IndexIterator() noexcept : m_current(nullptr) {}
64  explicit IndexIterator(GitTy *iterator) noexcept : m_iterator(iterator) { increment(); }
65 
66  void increment() {
67  if (git_index_iterator_next(&m_current, iterator()))
68  m_current = nullptr;
69  }
70 
71  Holder m_iterator;
72  const git_index_entry *m_current;
73 };
74 
78 class Index {
79  using GitTy = git_index;
81 
82  friend class Repo;
83 public:
85  using MatchCB = std::function<int(const std::filesystem::path &, const std::string &)>;
86 
87  Index() = delete;
88 
90  static std::optional<Index> open(const std::filesystem::path &path) noexcept;
92  static std::optional<Index> create() noexcept;
93 
95  bool read(bool force = true) const noexcept {
96  return !Repo::setLastError(git_index_read(index(), force));
97  }
99  bool write() const noexcept { return !Repo::setLastError(git_index_write(index())); }
101  bool readTree(const Tree &tree) const noexcept;
103  std::optional<Tree> writeTree(const Repo &repo) const noexcept;
104 
106  size_t entrycount() const noexcept { return git_index_entrycount(index()); }
108  const git_index_entry *entryByIndex(size_t idx) const noexcept {
109  return git_index_get_byindex(index(), idx);
110  }
112  const git_index_entry *entryByPath(const std::filesystem::path &path,
113  git_index_stage_t stage = GIT_INDEX_STAGE_NORMAL) const noexcept {
114  return git_index_get_bypath(index(), path.c_str(), stage);
115  }
116 
118  bool addByPath(const std::filesystem::path &path) const noexcept {
119  return !Repo::setLastError(git_index_add_bypath(index(), path.c_str()));
120  }
122  bool removeByPath(const std::filesystem::path &path) const noexcept {
123  return !Repo::setLastError(git_index_remove_bypath(index(), path.c_str()));
124  }
125 
133  int addAll(const std::vector<std::string> &paths, unsigned int flags,
134  const MatchCB *cb = nullptr) const;
141  int removeAll(const std::vector<std::string> &paths, const MatchCB *cb = nullptr) const;
148  int updateAll(const std::vector<std::string> &paths, const MatchCB *cb = nullptr) const;
149 
151  bool hasConflicts() const noexcept { return git_index_has_conflicts(index()); }
152 
154  IndexIterator begin() noexcept { return cbegin(); }
156  IndexIterator end() noexcept { return IndexIterator(); }
157 
159  IndexIterator cbegin() const noexcept;
161  IndexIterator cend() const noexcept { return IndexIterator(); }
162 
164  GitTy *index() const noexcept { return m_index.get(); }
166  operator GitTy *() const noexcept { return index(); }
167 private:
168  explicit Index(GitTy *index) noexcept : m_index(index) { }
169 
170  static int matchCB(const char *path, const char *matched_pathspec, void *payload);
171 
172  Holder m_index;
173 };
174 
175 }
Definition: Blob.h:11
Iterator returned from Index::begin()
Definition: Index.h:23
size_t entrycount() const noexcept
Get count of entries in this Index.
Definition: Index.h:106
IndexIterator cend() const noexcept
Get the end iterator for this Index.
Definition: Index.h:161
GitTy * index() const noexcept
Get the stored pointer to libgit2&#39;s git_index.
Definition: Index.h:164
Index is a representation of a git index.
Definition: Index.h:78
bool operator!=(const IndexIterator &other) const noexcept
Compare with other.
Definition: Index.h:45
bool operator==(const IndexIterator &other) const noexcept
Compare with other.
Definition: Index.h:41
static std::optional< Index > open(const std::filesystem::path &path) noexcept
Load an index at into a new Index.
static std::optional< Index > create() noexcept
Create a new Index.
bool write() const noexcept
Write this Index to disk.
Definition: Index.h:99
std::string path() const noexcept
Get path from this IndexIterator (as a string)
Definition: Index.h:54
const git_index_entry * entryByPath(const std::filesystem::path &path, git_index_stage_t stage=GIT_INDEX_STAGE_NORMAL) const noexcept
Get entry corresponding to path (and stage)
Definition: Index.h:112
int addAll(const std::vector< std::string > &paths, unsigned int flags, const MatchCB *cb=nullptr) const
Add all paths into this Index.
IndexIterator cbegin() const noexcept
Get the begin iterator for this Index.
const git_index_entry * entryByIndex(size_t idx) const noexcept
Get an entry on the idx-th position.
Definition: Index.h:108
The most important Git class.
Definition: Repo.h:45
const git_index_entry * operator->() const noexcept
Get entry from this IndexIterator.
Definition: Index.h:51
const git_index_entry & operator*() const noexcept
Get entry from this IndexIterator.
Definition: Index.h:49
std::string_view pathSV() const noexcept
Get path from this IndexIterator (as a string_view)
Definition: Index.h:56
Tree is a representation of a git tree.
Definition: Tree.h:27
bool hasConflicts() const noexcept
Returns true if this index has some conflicts.
Definition: Index.h:151
IndexIterator end() noexcept
Get the end iterator for this Index.
Definition: Index.h:156
IndexIterator & operator++()
Move to the next entry.
Definition: Index.h:31
bool removeByPath(const std::filesystem::path &path) const noexcept
Remove path from this Index.
Definition: Index.h:122
bool readTree(const Tree &tree) const noexcept
Read tree into this Index.
bool read(bool force=true) const noexcept
Read the index from the disk into this Index.
Definition: Index.h:95
bool addByPath(const std::filesystem::path &path) const noexcept
Add path to this Index.
Definition: Index.h:118
int updateAll(const std::vector< std::string > &paths, const MatchCB *cb=nullptr) const
Update all paths in this Index.
std::function< int(const std::filesystem::path &, const std::string &)> MatchCB
A callback for addAll(), removeAll(), updateAll()
Definition: Index.h:85
int removeAll(const std::vector< std::string > &paths, const MatchCB *cb=nullptr) const
Remove all paths from this Index.
GitTy * iterator() const noexcept
Get the stored pointer to libgit2&#39;s git_index_entry.
Definition: Index.h:59
IndexIterator begin() noexcept
Get the begin iterator for this Index.
Definition: Index.h:154
std::optional< Tree > writeTree(const Repo &repo) const noexcept
Write this Index as a Tree.