Message ID | Y/hw1YVgCYWX2yNK@coredump.intra.peff.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | fsck index files from all worktrees | expand |
On Fri, Feb 24, 2023 at 03:09:58AM -0500, Jeff King wrote: > + for (p = get_worktrees(); *p; p++) { > + struct worktree *wt = *p; > + struct index_state istate = > + INDEX_STATE_INIT(the_repository); > + > + if (read_index_from(&istate, > + worktree_git_path(wt, "index"), > + get_worktree_git_dir(wt)) > 0) > + fsck_index(&istate); > + discard_index(&istate); > + } I didn't realize that get_worktrees() returns an allocated array, so this is a small leak. I'll squash this in locally: diff --git a/builtin/fsck.c b/builtin/fsck.c index ddd13cb2b3..c11cb2a95f 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -984,12 +984,13 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) } if (keep_cache_objects) { - struct worktree **p; + struct worktree **worktrees, **p; verify_index_checksum = 1; verify_ce_order = 1; - for (p = get_worktrees(); *p; p++) { + worktrees = get_worktrees(); + for (p = worktrees; *p; p++) { struct worktree *wt = *p; struct index_state istate = INDEX_STATE_INIT(the_repository); @@ -1000,7 +1001,7 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) fsck_index(&istate); discard_index(&istate); } - + free_worktrees(worktrees); } check_connectivity(); but I'll hold off for other comments before sending a re-roll. -Peff
diff --git a/builtin/fsck.c b/builtin/fsck.c index fa101e0db2..ddd13cb2b3 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -984,10 +984,23 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) } if (keep_cache_objects) { + struct worktree **p; + verify_index_checksum = 1; verify_ce_order = 1; - repo_read_index(the_repository); - fsck_index(the_repository->index); + + for (p = get_worktrees(); *p; p++) { + struct worktree *wt = *p; + struct index_state istate = + INDEX_STATE_INIT(the_repository); + + if (read_index_from(&istate, + worktree_git_path(wt, "index"), + get_worktree_git_dir(wt)) > 0) + fsck_index(&istate); + discard_index(&istate); + } + } check_connectivity(); diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index fdb886dfe4..3b70ad9e22 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -1023,4 +1023,16 @@ test_expect_success 'fsck error on gitattributes with excessive size' ' test_cmp expected actual ' +test_expect_success 'fsck detects problems in worktree index' ' + test_when_finished "git worktree remove -f wt" && + git worktree add wt && + + echo "this will be removed to break the worktree index" >wt/file && + git -C wt add file && + blob=$(git -C wt rev-parse :file) && + remove_object $blob && + + test_must_fail git fsck +' + test_done
We check the index file for the main worktree, but completely ignore the index files in other worktrees. These should be checked, too, as they are part of the repository state (and in particular, errors in those index files may cause repo-wide operations like "git gc" to complain). Reported-by: Johannes Sixt <j6t@kdbg.org> Signed-off-by: Jeff King <peff@peff.net> --- I mostly cargo-culted the loop from add_index_objects_to_pending(), which is how they get included in git-prune, git-repack, etc. I'm not sure if we should be reporting something if we get a negative return. Last time I dug into this, I think I found that the index-reading code could not actually return an error (it dies instead). If we get zero, there are no entries to check. But I'm not sure if we'd still have extensions? So maybe this ought to be ignoring the return value from read_index_from() entirely. builtin/fsck.c | 17 +++++++++++++++-- t/t1450-fsck.sh | 12 ++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-)