summaryrefslogtreecommitdiff
path: root/gitstatus/src/repo.h
diff options
context:
space:
mode:
Diffstat (limited to 'gitstatus/src/repo.h')
-rw-r--r--gitstatus/src/repo.h126
1 files changed, 126 insertions, 0 deletions
diff --git a/gitstatus/src/repo.h b/gitstatus/src/repo.h
new file mode 100644
index 00000000..f243f86e
--- /dev/null
+++ b/gitstatus/src/repo.h
@@ -0,0 +1,126 @@
+// Copyright 2019 Roman Perepelitsa.
+//
+// This file is part of GitStatus.
+//
+// GitStatus is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GitStatus is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with GitStatus. If not, see <https://www.gnu.org/licenses/>.
+
+#ifndef ROMKATV_GITSTATUS_REPO_H_
+#define ROMKATV_GITSTATUS_REPO_H_
+
+#include <stddef.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <git2.h>
+
+#include <algorithm>
+#include <atomic>
+#include <condition_variable>
+#include <cstddef>
+#include <cstring>
+#include <functional>
+#include <future>
+#include <memory>
+#include <mutex>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "check.h"
+#include "index.h"
+#include "options.h"
+#include "string_cmp.h"
+#include "tag_db.h"
+#include "time.h"
+
+namespace gitstatus {
+
+struct IndexStats {
+ size_t index_size = 0;
+ size_t num_staged = 0;
+ size_t num_unstaged = 0;
+ size_t num_conflicted = 0;
+ size_t num_untracked = 0;
+ size_t num_staged_new = 0;
+ size_t num_staged_deleted = 0;
+ size_t num_unstaged_deleted = 0;
+ size_t num_skip_worktree = 0;
+ size_t num_assume_unchanged = 0;
+};
+
+class Repo {
+ public:
+ explicit Repo(git_repository* repo, Limits lim);
+ Repo(Repo&& other) = delete;
+ ~Repo();
+
+ git_repository* repo() const { return repo_; }
+
+ // Head can be null, in which case has_staged will be false.
+ IndexStats GetIndexStats(const git_oid* head, git_config* cfg);
+
+ // Returns the last tag in lexicographical order whose target is equal to the given, or an
+ // empty string. Target can be null, in which case the tag is empty.
+ std::future<std::string> GetTagName(const git_oid* target);
+
+ private:
+ struct Shard {
+ bool Contains(Str<> str, StringView path) const;
+ std::string start_s;
+ std::string end_s;
+ size_t start_i;
+ size_t end_i;
+ };
+
+ void UpdateShards();
+
+ int OnDelta(const char* type, const git_diff_delta& d, std::atomic<size_t>& c1, size_t m1,
+ const std::atomic<size_t>& c2, size_t m2);
+
+ void StartStagedScan(const git_oid* head);
+ void StartDirtyScan(const std::vector<const char*>& paths);
+
+ void DecInflight();
+ void RunAsync(std::function<void()> f);
+ void Wait();
+
+ Limits lim_;
+ git_repository* const repo_;
+ git_index* git_index_ = nullptr;
+ std::vector<Shard> shards_;
+ git_oid head_ = {};
+ TagDb tag_db_;
+
+ std::unique_ptr<Index> index_;
+
+ std::mutex mutex_;
+ std::condition_variable cv_;
+ std::atomic<size_t> inflight_{0};
+ std::atomic<bool> error_{false};
+ std::atomic<size_t> staged_{0};
+ std::atomic<size_t> unstaged_{0};
+ std::atomic<size_t> conflicted_{0};
+ std::atomic<size_t> untracked_{0};
+ std::atomic<size_t> staged_new_{0};
+ std::atomic<size_t> staged_deleted_{0};
+ std::atomic<size_t> unstaged_deleted_{0};
+ std::atomic<size_t> skip_worktree_{0};
+ std::atomic<size_t> assume_unchanged_{0};
+ std::atomic<Tribool> untracked_cache_{Tribool::kUnknown};
+};
+
+} // namespace gitstatus
+
+#endif // ROMKATV_GITSTATUS_REPO_H_