This tells git grep to skip files longer than a specified length,
which is often the result of generators and not actual source files.

Signed-off-by: Marc-Antoine Ruel <mar...@chromium.org>
---
 Documentation/git-grep.txt | 5 +++++
 builtin/grep.c             | 2 ++
 grep.c                     | 4 ++++
 grep.h                     | 1 +
 t/t7810-grep.sh            | 5 +++++
 5 files changed, 17 insertions(+)

diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt
index 18b494731..75081defb 100644
--- a/Documentation/git-grep.txt
+++ b/Documentation/git-grep.txt
@@ -10,6 +10,7 @@ SYNOPSIS
 --------
 [verse]
 'git grep' [-a | --text] [-I] [--textconv] [-i | --ignore-case] [-w | 
--word-regexp]
+          [-M | --max-line-len <num>]
           [-v | --invert-match] [-h|-H] [--full-name]
           [-E | --extended-regexp] [-G | --basic-regexp]
           [-P | --perl-regexp]
@@ -127,6 +128,10 @@ OPTIONS
        beginning of a line, or preceded by a non-word character; end at
        the end of a line or followed by a non-word character).
 
+-M<num>::
+--max-line-len<num>::
+       Match the pattern only for line shorter or equal to this length.
+
 -v::
 --invert-match::
        Select non-matching lines.
diff --git a/builtin/grep.c b/builtin/grep.c
index 5a6cfe6b4..cc5c70be5 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -796,6 +796,8 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
                        N_("case insensitive matching")),
                OPT_BOOL('w', "word-regexp", &opt.word_regexp,
                        N_("match patterns only at word boundaries")),
+               OPT_INTEGER('M', "max-line-len", &opt.max_line_length,
+                       N_("ignore lines longer than <n>")),
                OPT_SET_INT('a', "text", &opt.binary,
                        N_("process binary files as text"), GREP_BINARY_TEXT),
                OPT_SET_INT('I', NULL, &opt.binary,
diff --git a/grep.c b/grep.c
index d0b9b6cdf..881078b82 100644
--- a/grep.c
+++ b/grep.c
@@ -36,6 +36,7 @@ void init_grep_defaults(void)
        opt->relative = 1;
        opt->pathname = 1;
        opt->max_depth = -1;
+       opt->max_line_length = -1;
        opt->pattern_type_option = GREP_PATTERN_TYPE_UNSPECIFIED;
        color_set(opt->color_context, "");
        color_set(opt->color_filename, "");
@@ -151,6 +152,7 @@ void grep_init(struct grep_opt *opt, const char *prefix)
        opt->pattern_type_option = def->pattern_type_option;
        opt->linenum = def->linenum;
        opt->max_depth = def->max_depth;
+       opt->max_line_length = def->max_line_length;
        opt->pathname = def->pathname;
        opt->relative = def->relative;
        opt->output = def->output;
@@ -1273,6 +1275,8 @@ static int match_line(struct grep_opt *opt, char *bol, 
char *eol,
        struct grep_pat *p;
        regmatch_t match;
 
+       if (opt->max_line_length > 0 && eol-bol > opt->max_line_length)
+               return 0;
        if (opt->extended)
                return match_expr(opt, bol, eol, ctx, collect_hits);
 
diff --git a/grep.h b/grep.h
index 399381c90..0e76c0a19 100644
--- a/grep.h
+++ b/grep.h
@@ -151,6 +151,7 @@ struct grep_opt {
        int null_following_name;
        int color;
        int max_depth;
+       int max_line_length;
        int funcname;
        int funcbody;
        int extended_regexp_option;
diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh
index 2a6679c2f..c514bd388 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -766,6 +766,11 @@ test_expect_success 'grep -W shows no trailing empty 
lines' '
        test_cmp expected actual
 '
 
+test_expect_success 'grep skips long lines' '
+       git grep -M18 -W include >actual &&
+       test_cmp expected actual
+'
+
 cat >expected <<EOF
 hello.c=       printf("Hello world.\n");
 hello.c:       return 0;
-- 
2.15.0

Reply via email to