diff options
Diffstat (limited to 'gitstatus/src/repo.h')
-rw-r--r-- | gitstatus/src/repo.h | 126 |
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_ |