git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v3 2/2] [RPC] grep: introduce --scope option

From
ZheNing Hu via GitGitGadget <gitgitgadget@gmail.com>
Date
Nov 29, 2022, 12:00 UTC
Message-ID
<1d1b66188f5c221ecdc165e0dae82932a65a3fbb.1669723221.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1398.v3.git.1669723221.gitgitgadget@gmail.com>
From: ZheNing Hu <adlternative@gmail.com>

Because we may want to restrict grep's file scope to sparse specification, Apply the --scope option we implemented in diff to grep as well.

`--scope=sparse` mean that the search file scope restrict to sparse specification when we grep something in commit history, and `--scope=all` mean that the search file scope will be full-tree.

Note that `--scope` option only oly takes effect when "git grep <tree>" is specified.

Signed-off-by: ZheNing Hu <adlternative@gmail.com>
---
 Documentation/git-grep.txt       | 24 ++++++++++++++++++++++++
 builtin/grep.c                   | 10 ++++++++++
 grep.h                           |  2 ++
 t/t1090-sparse-checkout-scope.sh | 27 +++++++++++++++++++++++++++
 4 files changed, 63 insertions(+)
diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index dabdbe8471d..b556f657306 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -28,6 +28,7 @@ SYNOPSIS
 	   [-f <file>] [-e] <pattern>
 	   [--and|--or|--not|(|)|-e <pattern>...]
 	   [--recurse-submodules] [--parent-basename <basename>]
+	   [--scope=(sparse|all)]
 	   [ [--[no-]exclude-standard] [--cached | --no-index | --untracked] | <tree>...]
 	   [--] [<pathspec>...]
 
@@ -296,6 +297,29 @@ question doesn't support them.
 	Do not output matched lines; instead, exit with status 0 when
 	there is a match and with non-zero status when there isn't.
 
+--scope=(sparse|all)::
+	Restrict or not restrict grep path scope in sparse specification.
+	The variants are as follows:
+
++
+--
+`sparse`;;
+	When grep in commit history, restrict the scope of file path
+	to the sparse specification. See sparse specification in
+	link:technical/sparse-checkout.html [the sparse-checkout design
+	document] for more information.
+`all`;;
+	When grep in commit history, the file path scope is full-tree.
+	This is consistent with the current default behavior.
+--
++
+
+Note that `--scope` option only take effect if git command specify `<tree>`.
+
+The behavior of this `--scope` option is experimental and may change
+in the future. See link:technical/sparse-checkout.html [the sparse-checkout
+design document] for more information.
+
 <tree>...::
 	Instead of searching tracked files in the working tree, search
 	blobs in the given trees.
diff --git a/builtin/grep.c b/builtin/grep.c
index f7821c5fbba..8f7944fb924 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -640,6 +640,15 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec,
 		}
 
 		strbuf_add(base, entry.path, te_len);
+		if (opt->scope == SPARSE_SCOPE_SPARSE &&
+			base->len != tn_len &&
+			!path_in_sparse_patterns(base->buf + tn_len,
+					S_ISDIR(entry.mode) ||
+					S_ISGITLINK(entry.mode))) {
+			strbuf_setlen(base, old_baselen);
+			continue;
+		}
+
 
 		if (S_ISREG(entry.mode)) {
 			hit |= grep_oid(opt, &entry.oid, base->buf, tn_len,
@@ -999,6 +1008,7 @@ 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_SPARSE_SCOPE(&opt.scope),
 		OPT_END()
 	};
 	grep_prefix = prefix;
diff --git a/grep.h b/grep.h
index 6075f997e68..05010d4b166 100644
--- a/grep.h
+++ b/grep.h
@@ -22,6 +22,7 @@ typedef int pcre2_general_context;
 #endif
 #include "thread-utils.h"
 #include "userdiff.h"
+#include "cache.h"
 
 struct repository;
 
@@ -175,6 +176,7 @@ struct grep_opt {
 
 	void (*output)(struct grep_opt *opt, const void *data, size_t size);
 	void *output_priv;
+	enum sparse_scope scope;
 };
 
 #define GREP_OPT_INIT { \
diff --git a/t/t1090-sparse-checkout-scope.sh b/t/t1090-sparse-checkout-scope.sh
index e6ec8e8c1e4..c8f68fc7afa 100755
--- a/t/t1090-sparse-checkout-scope.sh
+++ b/t/t1090-sparse-checkout-scope.sh
@@ -382,4 +382,31 @@ M	in
 	test_cmp expected actual
 '
 
+# git grep TREE
+
+test_expect_success 'git grep --scope=all' '
+	reset_sparse_checkout_state &&
+	cat >expected <<-EOF &&
+HEAD~:in/1
+HEAD~:out1/1
+HEAD~:out1/2
+HEAD~:out1/3
+HEAD~:out1/4
+HEAD~:out1/5
+HEAD~:out1/6
+HEAD~:out2/1
+	EOF
+	git -C repo grep --name-only --scope=all 1 HEAD~ >actual &&
+	test_cmp expected actual
+'
+
+test_expect_success 'git grep --scope=sparse' '
+	reset_sparse_checkout_state &&
+	cat >expected <<-EOF &&
+HEAD~:in/1
+	EOF
+	git -C repo grep --name-only --scope=sparse 1 HEAD~ >actual &&
+	test_cmp expected actual
+'
+
 test_done
-- 
gitgitgadget
Previous: ZheNing Hu via GitGitGadgetNext: ZheNing Hu via GitGitGadget
Message 10 of 11 in “[RFC] diff: introduce scope option”
  1. [RFC] diff: introduce scope optionZheNing Hu via GitGitGadget, Oct 31, 2022
  2. Taylor BlauNov 1, 2022
  3. ZheNing HuNov 1, 2022
  4. Elijah NewrenNov 1, 2022
  5. ZheNing HuNov 6, 2022
  6. Elijah NewrenNov 6, 2022
  7. ZheNing HuNov 14, 2022
  8. [RFC] diff: introduce --scope optionZheNing Hu via GitGitGadget, Nov 25, 2022
  9. 0/2 [RFC] diff: introduce scope optionZheNing Hu via GitGitGadget, Nov 29, 2022
  10. 2/2 [RPC] grep: introduce --scope optionZheNing Hu via GitGitGadget, Nov 29, 2022
  11. 1/2 [RFC] diff: introduce --scope optionZheNing Hu via GitGitGadget, Nov 29, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.