From cd070aa6dca56c1331d12a512abc43f04791df0d Mon Sep 17 00:00:00 2001 From: Shaoxuan Yuan Date: Wed, 10 Aug 2022 16:30:21 +0800 Subject: [PATCH 1/3] builtin/grep.c: add --sparse option Add a --sparse option to `git-grep`. This option is mainly used to: If searching in the index (using --cached): With --sparse, proceed the action when the current cache_entry is marked with SKIP_WORKTREE bit (the default is to skip this kind of entry). Before this patch, --cached itself can realize this action. Adding --sparse here grants the user finer control over sparse entries. If the user only wants to peak into the index without caring about sparse entries, --cached should suffice; if the user wants to peak into the index _and_ care about sparse entries, combining --sparse with --cached can address this need. Suggested-by: Victoria Dye Signed-off-by: Shaoxuan Yuan --- builtin/grep.c | 10 +++++++++- t/t7817-grep-sparse-checkout.sh | 12 ++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index e6bcdf860cc96a..61402e808463b6 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -96,6 +96,8 @@ static pthread_cond_t cond_result; static int skip_first_line; +static int grep_sparse = 0; + static void add_work(struct grep_opt *opt, struct grep_source *gs) { if (opt->binary != GREP_BINARY_TEXT) @@ -525,7 +527,11 @@ static int grep_cache(struct grep_opt *opt, for (nr = 0; nr < repo->index->cache_nr; nr++) { const struct cache_entry *ce = repo->index->cache[nr]; - if (!cached && ce_skip_worktree(ce)) + /* + * If ce is a SKIP_WORKTREE entry, look into it when both + * --sparse and --cached are given. + */ + if (!(grep_sparse && cached) && ce_skip_worktree(ce)) continue; strbuf_setlen(&name, name_base_len); @@ -963,6 +969,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix) PARSE_OPT_NOCOMPLETE), OPT_INTEGER('m', "max-count", &opt.max_count, N_("maximum number of results per file")), + OPT_BOOL(0, "sparse", &grep_sparse, + N_("search sparse contents and expand sparse index")), OPT_END() }; grep_prefix = prefix; diff --git a/t/t7817-grep-sparse-checkout.sh b/t/t7817-grep-sparse-checkout.sh index eb595645657fad..ca71f526eb3193 100755 --- a/t/t7817-grep-sparse-checkout.sh +++ b/t/t7817-grep-sparse-checkout.sh @@ -118,13 +118,13 @@ test_expect_success 'grep searches unmerged file despite not matching sparsity p test_cmp expect actual ' -test_expect_success 'grep --cached searches entries with the SKIP_WORKTREE bit' ' +test_expect_success 'grep --cached and --sparse searches entries with the SKIP_WORKTREE bit' ' cat >expect <<-EOF && a:text b:text dir/c:text EOF - git grep --cached "text" >actual && + git grep --cached --sparse "text" >actual && test_cmp expect actual ' @@ -143,7 +143,7 @@ test_expect_success 'grep --recurse-submodules honors sparse checkout in submodu test_cmp expect actual ' -test_expect_success 'grep --recurse-submodules --cached searches entries with the SKIP_WORKTREE bit' ' +test_expect_success 'grep --recurse-submodules --cached and --sparse searches entries with the SKIP_WORKTREE bit' ' cat >expect <<-EOF && a:text b:text @@ -152,7 +152,7 @@ test_expect_success 'grep --recurse-submodules --cached searches entries with th sub/B/b:text sub2/a:text EOF - git grep --recurse-submodules --cached "text" >actual && + git grep --recurse-submodules --cached --sparse "text" >actual && test_cmp expect actual ' @@ -166,7 +166,7 @@ test_expect_success 'working tree grep does not search the index with CE_VALID a test_cmp expect actual ' -test_expect_success 'grep --cached searches index entries with both CE_VALID and SKIP_WORKTREE' ' +test_expect_success 'grep --cached and --sparse searches index entries with both CE_VALID and SKIP_WORKTREE' ' cat >expect <<-EOF && a:text b:text @@ -174,7 +174,7 @@ test_expect_success 'grep --cached searches index entries with both CE_VALID and EOF test_when_finished "git update-index --no-assume-unchanged b" && git update-index --assume-unchanged b && - git grep --cached text >actual && + git grep --cached --sparse text >actual && test_cmp expect actual ' From e7ff200df52bd8edc6c35c21dca4db6975b3b365 Mon Sep 17 00:00:00 2001 From: Shaoxuan Yuan Date: Wed, 10 Aug 2022 18:26:45 +0800 Subject: [PATCH 2/3] builtin/grep.c: enable sparse-index and remove ensure_full_index() This patch only turns on sparse-index, without actually modifying any functionalities. This change is preparing for the next patch[es], where sparse-index should be on. Signed-off-by: Shaoxuan Yuan --- builtin/grep.c | 5 +++-- t/t1092-sparse-checkout-compatibility.sh | 17 +++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/builtin/grep.c b/builtin/grep.c index 61402e808463b6..2fbd3ebd549c77 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -519,11 +519,12 @@ static int grep_cache(struct grep_opt *opt, strbuf_addstr(&name, repo->submodule_prefix); } + prepare_repo_settings(the_repository); + the_repository->settings.command_requires_full_index = 0; + if (repo_read_index(repo) < 0) die(_("index file corrupt")); - /* TODO: audit for interaction with sparse-index. */ - ensure_full_index(repo->index); for (nr = 0; nr < repo->index->cache_nr; nr++) { const struct cache_entry *ce = repo->index->cache[nr]; diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 763c6cc684687a..7d1223c315d053 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -1853,4 +1853,21 @@ test_expect_success 'mv directory from out-of-cone to in-cone' ' grep -e "H deep/0/1" actual ' +test_expect_failure 'grep expands index using --sparse' ' + init_repos && + + # With --sparse and --cached, do not ignore sparse entries and + # expand the index. + test_all_match git grep --sparse --cached a +' + +test_expect_success 'grep is not expanded' ' + init_repos && + + ensure_not_expanded grep a && + ensure_not_expanded grep a -- deep/* && + # grep does not match anything per se, so ! is used + ensure_not_expanded ! grep a -- folder1/* +' + test_done From 1c6b2523e1c6ed521ee73b7558dab565c11d94df Mon Sep 17 00:00:00 2001 From: Shaoxuan Yuan Date: Wed, 10 Aug 2022 18:36:39 +0800 Subject: [PATCH 3/3] builtin/grep.c: expands index when using --sparse Originally, `git-grep` always expands a sparse-index. Change it to only expands the index when using --sparse switch and the pathspec needs a expanded index. Signed-off-by: Shaoxuan Yuan --- builtin/grep.c | 3 +++ t/t1092-sparse-checkout-compatibility.sh | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/builtin/grep.c b/builtin/grep.c index 2fbd3ebd549c77..86008514869b3a 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -525,6 +525,9 @@ static int grep_cache(struct grep_opt *opt, if (repo_read_index(repo) < 0) die(_("index file corrupt")); + if (grep_sparse) + ensure_full_index(repo->index); + for (nr = 0; nr < repo->index->cache_nr; nr++) { const struct cache_entry *ce = repo->index->cache[nr]; diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 7d1223c315d053..795a74588d0048 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -1853,7 +1853,7 @@ test_expect_success 'mv directory from out-of-cone to in-cone' ' grep -e "H deep/0/1" actual ' -test_expect_failure 'grep expands index using --sparse' ' +test_expect_success 'grep expands index using --sparse' ' init_repos && # With --sparse and --cached, do not ignore sparse entries and