From: =?UTF-8?q?Max=20=F0=9F=91=A8=F0=9F=8F=BD=E2=80=8D=F0=9F=92=BB=20Copl?= =?UTF-8?q?an?= <mchcopl@xxxxxxxxx> Note to reviewer: I hate the name `--header-or`! Please help me come up with a better name. Summary: This change adds a new option to `git log` that allows users to search for commits that match either the author or the commit message. This is useful for finding commits that were either authored or co-authored by a specific person. Currently, the best way to find a commit either authored or co-authored by a specific person is to use ```sh echo \ $(git log --author=Torvalds --pretty="%cd,%H\n" --date=iso-strict) \ $(git log --grep="Co-authored-by: .*Torvalds" --pretty="%cd,%H\n" --date=iso-strict) \ | sort -n --reverse \ | awk -F, '{print $2}' \ | tr '\n' '\t' \ | xargs git show --stat --stdin ``` This is a bit of a pain, so this change adds a new option to `git log`. Now finding either authors or co-authors is as simple as ```sh git log --author=Torvalds --grep=Torvalds --header-or ``` Test plan: 1. create commit authored by A and co-authored-by B 2. create commit authored by B 3. run `git log --author=B --grep="Co-authored-by: B" --header-or` 4. expect to see both commits Signed-off-by: Max 👨🏽💻 Coplan <mchcopl@xxxxxxxxx> --- feat(log): add option to search for header or body to git log Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-1710%2Fvegerot%2Fheader-or-v1 Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-1710/vegerot/header-or-v1 Pull-Request: https://github.com/gitgitgadget/git/pull/1710 grep.c | 2 +- grep.h | 1 + revision.c | 3 +++ t/t7810-grep.sh | 11 +++++++++++ 4 files changed, 16 insertions(+), 1 deletion(-) diff --git a/grep.c b/grep.c index ac34bfeafb3..79ba4810b83 100644 --- a/grep.c +++ b/grep.c @@ -797,7 +797,7 @@ void compile_grep_patterns(struct grep_opt *opt) if (opt->no_body_match && opt->pattern_expression) opt->pattern_expression = grep_not_expr(opt->pattern_expression); - if (!header_expr) + if (!header_expr || opt->header_or) return; if (!opt->pattern_expression) diff --git a/grep.h b/grep.h index 926c0875c42..8cbc4a46194 100644 --- a/grep.h +++ b/grep.h @@ -147,6 +147,7 @@ struct grep_opt { int count; int word_regexp; int all_match; + int header_or; int no_body_match; int body_hit; #define GREP_BINARY_DEFAULT 0 diff --git a/revision.c b/revision.c index 7e45f765d9f..0858050ece3 100644 --- a/revision.c +++ b/revision.c @@ -2646,6 +2646,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->grep_filter.pattern_type_option = GREP_PATTERN_TYPE_PCRE; } else if (!strcmp(arg, "--all-match")) { revs->grep_filter.all_match = 1; + // @@@ must-fix: find a better name + } else if (!strcmp(arg, "--header-or")) { + revs->grep_filter.header_or = 1; } else if (!strcmp(arg, "--invert-grep")) { revs->grep_filter.no_body_match = 1; } else if ((argcount = parse_long_opt("encoding", argv, &optarg))) { diff --git a/t/t7810-grep.sh b/t/t7810-grep.sh index 875dcfd98f3..d539b5e88f5 100755 --- a/t/t7810-grep.sh +++ b/t/t7810-grep.sh @@ -961,6 +961,17 @@ test_expect_success 'log --grep --author uses intersection' ' test_cmp expect actual ' +test_expect_success 'log --grep --author --header-or uses union' ' + # grep matches only third and fourth + # author matches only initial and third + git log --author="A U Thor" --grep=r --header-or --format=%s >actual && + { + echo fourth && echo third + } >expect && + test_cmp expect actual +' + + test_expect_success 'log --grep --grep --author takes union of greps and intersects with author' ' # grep matches initial and second but not third # author matches only initial and third base-commit: 7774cfed6261ce2900c84e55906da708c711d601 -- gitgitgadget