Skip to content

Commit

Permalink
feat(log): add option to search for header or body to git log
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
vegerot committed Apr 5, 2024
1 parent 7774cfe commit dc6b566
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 1 deletion.
2 changes: 1 addition & 1 deletion grep.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
1 change: 1 addition & 0 deletions grep.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions revision.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))) {
Expand Down
11 changes: 11 additions & 0 deletions t/t7810-grep.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit dc6b566

Please sign in to comment.