diff --git a/builtin/fsck.c b/builtin/fsck.c index c11cb2a95f..1b032eebb1 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -731,19 +731,19 @@ static int fsck_head_link(const char *head_ref_name, return 0; } -static int fsck_cache_tree(struct cache_tree *it) +static int fsck_cache_tree(struct cache_tree *it, const char *index_path) { int i; int err = 0; if (verbose) - fprintf_ln(stderr, _("Checking cache tree")); + fprintf_ln(stderr, _("Checking cache tree of %s"), index_path); if (0 <= it->entry_count) { struct object *obj = parse_object(the_repository, &it->oid); if (!obj) { - error(_("%s: invalid sha1 pointer in cache-tree"), - oid_to_hex(&it->oid)); + error(_("%s: invalid sha1 pointer in cache-tree of %s"), + oid_to_hex(&it->oid), index_path); errors_found |= ERROR_REFS; return 1; } @@ -754,11 +754,12 @@ static int fsck_cache_tree(struct cache_tree *it) err |= objerror(obj, _("non-tree in cache-tree")); } for (i = 0; i < it->subtree_nr; i++) - err |= fsck_cache_tree(it->down[i]->cache_tree); + err |= fsck_cache_tree(it->down[i]->cache_tree, index_path); return err; } -static int fsck_resolve_undo(struct index_state *istate) +static int fsck_resolve_undo(struct index_state *istate, + const char *index_path) { struct string_list_item *item; struct string_list *resolve_undo = istate->resolve_undo; @@ -781,8 +782,9 @@ static int fsck_resolve_undo(struct index_state *istate) obj = parse_object(the_repository, &ru->oid[i]); if (!obj) { - error(_("%s: invalid sha1 pointer in resolve-undo"), - oid_to_hex(&ru->oid[i])); + error(_("%s: invalid sha1 pointer in resolve-undo of %s"), + oid_to_hex(&ru->oid[i]), + index_path); errors_found |= ERROR_REFS; continue; } @@ -795,7 +797,8 @@ static int fsck_resolve_undo(struct index_state *istate) return 0; } -static void fsck_index(struct index_state *istate) +static void fsck_index(struct index_state *istate, const char *index_path, + int is_main_index) { unsigned int i; @@ -816,12 +819,14 @@ static void fsck_index(struct index_state *istate) obj = &blob->object; obj->flags |= USED; fsck_put_object_name(&fsck_walk_options, &obj->oid, - ":%s", istate->cache[i]->name); + "%s:%s", + is_main_index ? "" : index_path, + istate->cache[i]->name); mark_object_reachable(obj); } if (istate->cache_tree) - fsck_cache_tree(istate->cache_tree); - fsck_resolve_undo(istate); + fsck_cache_tree(istate->cache_tree, index_path); + fsck_resolve_undo(istate, index_path); } static void mark_object_for_connectivity(const struct object_id *oid) @@ -994,12 +999,19 @@ int cmd_fsck(int argc, const char **argv, const char *prefix) struct worktree *wt = *p; struct index_state istate = INDEX_STATE_INIT(the_repository); + char *path; - if (read_index_from(&istate, - worktree_git_path(wt, "index"), + /* + * Make a copy since the buffer is reusable + * and may get overwritten by other calls + * while we're examining the index. + */ + path = xstrdup(worktree_git_path(wt, "index")); + if (read_index_from(&istate, path, get_worktree_git_dir(wt)) > 0) - fsck_index(&istate); + fsck_index(&istate, path, wt->is_current); discard_index(&istate); + free(path); } free_worktrees(worktrees); } diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index e01a519a69..82c92de7ca 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -1032,7 +1032,25 @@ test_expect_success 'fsck detects problems in worktree index' ' blob=$(git -C wt rev-parse :file) && remove_object $blob && - test_must_fail git fsck + test_must_fail git fsck --name-objects >actual 2>&1 && + cat >expect <<-EOF && + missing blob $blob (.git/worktrees/wt/index:file) + EOF + test_cmp expect actual +' + +test_expect_success 'fsck reports problems in main index without filename' ' + test_when_finished "rm -f .git/index && git read-tree HEAD" && + echo "this object will be removed to break the main index" >file && + git add file && + blob=$(git rev-parse :file) && + remove_object $blob && + + test_must_fail git fsck --name-objects >actual 2>&1 && + cat >expect <<-EOF && + missing blob $blob (:file) + EOF + test_cmp expect actual ' test_done