From ef5809842b162bbb7eaaa983b744aafe3a9a308f Mon Sep 17 00:00:00 2001 From: puqeko Date: Sun, 28 Jan 2024 13:27:36 +1300 Subject: [PATCH 1/2] Don't error on unreadable index Treat an unreadable index as if option to ignore index computations was passed. Instead of reporting no-repo, basic repo info will be reported. --- src/repo.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/repo.cc b/src/repo.cc index a81594a..b592a8f 100644 --- a/src/repo.cc +++ b/src/repo.cc @@ -152,7 +152,7 @@ IndexStats Repo::GetIndexStats(const git_oid* head, git_config* cfg) { index_.reset(); } } else { - VERIFY(!git_repository_index(&git_index_, repo_)) << GitError(); + if (git_repository_index(&git_index_, repo_))) return; // Query an attribute (doesn't matter which) to initialize repo's attribute // cache. It's a workaround for synchronization bugs (data races) in libgit2 // that result from lazy cache initialization without synchronization. From edc983d2e6631e8c00f080340dd5a38fcb7de974 Mon Sep 17 00:00:00 2001 From: puqeko Date: Sun, 28 Jan 2024 13:32:11 +1300 Subject: [PATCH 2/2] Report if index was read in response Add 30th entry to response which is 1 if index computations are disabled OR the index cannot be read, 0 otherwise. The requester, knowing the requests contents, can determine if the index could not be read while still receiving repository information that is avaliable. --- gitstatus.plugin.sh | 2 ++ gitstatus.plugin.zsh | 4 +++- src/gitstatus.cc | 5 ++++- src/options.cc | 2 ++ src/repo.cc | 8 ++++++-- src/repo.h | 1 + 6 files changed, 18 insertions(+), 4 deletions(-) diff --git a/gitstatus.plugin.sh b/gitstatus.plugin.sh index bfe16dc..c1a49f7 100644 --- a/gitstatus.plugin.sh +++ b/gitstatus.plugin.sh @@ -352,6 +352,7 @@ function gitstatus_stop() { # Non-negative integer. # VCS_STATUS_NUM_ASSUME_UNCHANGED The number of files in the index with assume-unchanged bit set. # Non-negative integer. +# VCS_STATUS_INDEX_DISABLED Either the -p option was set or the index could not be read. # # The point of reporting -1 via VCS_STATUS_HAS_* is to allow the command to skip scanning files in # large repos. See -m flag of gitstatus_start. @@ -418,6 +419,7 @@ function gitstatus_query() { VCS_STATUS_NUM_ASSUME_UNCHANGED="${resp[26]:-0}" VCS_STATUS_COMMIT_ENCODING="${resp[27]-}" VCS_STATUS_COMMIT_SUMMARY="${resp[28]-}" + VCS_STATUS_INDEX_DISABLED="${resp[29]-}" VCS_STATUS_HAS_STAGED=$((VCS_STATUS_NUM_STAGED > 0)) if (( _GITSTATUS_DIRTY_MAX_INDEX_SIZE >= 0 && VCS_STATUS_INDEX_SIZE > _GITSTATUS_DIRTY_MAX_INDEX_SIZE_ )); then diff --git a/gitstatus.plugin.zsh b/gitstatus.plugin.zsh index b74396d..813fe08 100644 --- a/gitstatus.plugin.zsh +++ b/gitstatus.plugin.zsh @@ -43,6 +43,7 @@ # VCS_STATUS_STASHES=0 # VCS_STATUS_TAG='' # VCS_STATUS_WORKDIR=/home/romka/powerlevel10k +# VCS_STATUS_INDEX_DISABLED=0 [[ -o 'interactive' ]] || 'return' @@ -347,7 +348,8 @@ function _gitstatus_process_response"${1:-}"() { VCS_STATUS_NUM_SKIP_WORKTREE \ VCS_STATUS_NUM_ASSUME_UNCHANGED \ VCS_STATUS_COMMIT_ENCODING \ - VCS_STATUS_COMMIT_SUMMARY in "${(@)resp[3,29]}"; do + VCS_STATUS_COMMIT_SUMMARY \ + VCS_STATUS_INDEX_DISABLED in "${(@)resp[3,30]}"; do done typeset -gi VCS_STATUS_{INDEX_SIZE,NUM_STAGED,NUM_UNSTAGED,NUM_CONFLICTED,NUM_UNTRACKED,COMMITS_AHEAD,COMMITS_BEHIND,STASHES,NUM_UNSTAGED_DELETED,NUM_STAGED_NEW,NUM_STAGED_DELETED,PUSH_COMMITS_AHEAD,PUSH_COMMITS_BEHIND,NUM_SKIP_WORKTREE,NUM_ASSUME_UNCHANGED} typeset -gi VCS_STATUS_HAS_STAGED=$((VCS_STATUS_NUM_STAGED > 0)) diff --git a/src/gitstatus.cc b/src/gitstatus.cc index 81399ea..d5e4ee7 100644 --- a/src/gitstatus.cc +++ b/src/gitstatus.cc @@ -106,7 +106,7 @@ void ProcessRequest(const Options& opts, RepoCache& cache, Request req) { // Repository state, A.K.A. action. For example, "merge". resp.Print(RepoState(repo->repo())); - IndexStats stats; + IndexStats stats {.disabled = true}; // Look for staged, unstaged and untracked. This is where most of the time is spent. if (req.diff) stats = repo->GetIndexStats(head_target, cfg); @@ -176,6 +176,9 @@ void ProcessRequest(const Options& opts, RepoCache& cache, Request req) { resp.Print(msg.encoding); resp.Print(msg.summary); + // 1 if index computation disabled by req or we could not read the index, 0 otherwise + resp.Print(stats.disabled); + resp.Dump("with git status"); } diff --git a/src/options.cc b/src/options.cc index b7abe5d..9359a41 100644 --- a/src/options.cc +++ b/src/options.cc @@ -184,6 +184,7 @@ void PrintUsage() { << " 27. Number of files in the index with assume-unchanged bit set.\n" << " 28. Encoding of the HEAD's commit message. Empty value means UTF-8.\n" << " 29. The first paragraph of the HEAD's commit message as one line.\n" + << " 30. 1 if index was not read, 0 otherwise.\n" << "\n" << "Note: Renamed files are reported as deleted plus new.\n" << "\n" @@ -228,6 +229,7 @@ void PrintUsage() { << " '0'\n" << " ''\n" << " 'add a build server for darwin-arm64'\n" + << " '0'\n" << "\n" << "EXIT STATUS\n" << "\n" diff --git a/src/repo.cc b/src/repo.cc index b592a8f..a7cf67d 100644 --- a/src/repo.cc +++ b/src/repo.cc @@ -152,7 +152,10 @@ IndexStats Repo::GetIndexStats(const git_oid* head, git_config* cfg) { index_.reset(); } } else { - if (git_repository_index(&git_index_, repo_))) return; + if (git_repository_index(&git_index_, repo_)) { + // Can't read index, proceed as if index computations are disabled + return {.disabled = true}; + } // Query an attribute (doesn't matter which) to initialize repo's attribute // cache. It's a workaround for synchronization bugs (data races) in libgit2 // that result from lazy cache initialization without synchronization. @@ -239,7 +242,8 @@ IndexStats Repo::GetIndexStats(const git_oid* head, git_config* cfg) { .num_staged_deleted = std::min(Load(staged_deleted_), num_staged), .num_unstaged_deleted = std::min(Load(unstaged_deleted_), num_unstaged), .num_skip_worktree = Load(skip_worktree_), - .num_assume_unchanged = Load(assume_unchanged_)}; + .num_assume_unchanged = Load(assume_unchanged_), + .disabled = false}; } int Repo::OnDelta(const char* type, const git_diff_delta& d, std::atomic& c1, size_t m1, diff --git a/src/repo.h b/src/repo.h index f243f86..e938ffb 100644 --- a/src/repo.h +++ b/src/repo.h @@ -58,6 +58,7 @@ struct IndexStats { size_t num_unstaged_deleted = 0; size_t num_skip_worktree = 0; size_t num_assume_unchanged = 0; + bool disabled = false; }; class Repo {