diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt
index 00ccf687441..db0979ac498 100644
--- a/Documentation/rev-list-options.txt
+++ b/Documentation/rev-list-options.txt
@@ -71,6 +71,14 @@ endif::git-rev-list[]
 	Limit the commits output to ones that match all given `--grep`,
 	instead of ones that match at least one.
 
+--match-header-or-grep::
+	Limit the commits output to ones that match either header patterns
+	(`--author`, `--committer`, or `--grep-reflog`) or `--grep`, instead
+	of ones that match both the header and grep patterns
++
+For example, `--author=me --grep=Co-authored-by: me` limits to commits either
+authored or co-authored by me.
+
 --invert-grep::
 	Limit the commits output to ones with a log message that do not
 	match the pattern specified with `--grep=<pattern>`.
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 75193ded4bd..30fc6ed08bd 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -2170,7 +2170,7 @@ __git_log_gitk_options="
 # Options that go well for log and shortlog (not gitk)
 __git_log_shortlog_options="
 	--author= --committer= --grep=
-	--all-match --invert-grep
+	--all-match --invert-grep --match-header-or-grep
 "
 # Options accepted by log and show
 __git_log_show_options="
diff --git a/grep.c b/grep.c
index ac34bfeafb3..72cf599660a 100644
--- a/grep.c
+++ b/grep.c
@@ -802,7 +802,7 @@ void compile_grep_patterns(struct grep_opt *opt)
 
 	if (!opt->pattern_expression)
 		opt->pattern_expression = header_expr;
-	else if (opt->all_match)
+	else if (opt->all_match || opt->match_header_or_grep)
 		opt->pattern_expression = grep_splice_or(header_expr,
 							 opt->pattern_expression);
 	else
@@ -1829,7 +1829,7 @@ int grep_source(struct grep_opt *opt, struct grep_source *gs)
 	opt->body_hit = 0;
 	grep_source_1(opt, gs, 1);
 
-	if (opt->all_match && !chk_hit_marker(opt->pattern_expression))
+	if (!opt->match_header_or_grep && opt->all_match && !chk_hit_marker(opt->pattern_expression))
 		return 0;
 	if (opt->no_body_match && opt->body_hit)
 		return 0;
diff --git a/grep.h b/grep.h
index 926c0875c42..861584dba98 100644
--- a/grep.h
+++ b/grep.h
@@ -147,6 +147,7 @@ struct grep_opt {
 	int count;
 	int word_regexp;
 	int all_match;
+	int match_header_or_grep;
 	int no_body_match;
 	int body_hit;
 #define GREP_BINARY_DEFAULT	0
diff --git a/revision.c b/revision.c
index 7e45f765d9f..786c229f56d 100644
--- a/revision.c
+++ b/revision.c
@@ -2646,6 +2646,8 @@ 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;
+	} else if (!strcmp(arg, "--match-header-or-grep")) {
+		revs->grep_filter.match_header_or_grep = 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..c78ce150f4d 100755
--- a/t/t7810-grep.sh
+++ b/t/t7810-grep.sh
@@ -961,6 +961,14 @@ test_expect_success 'log --grep --author uses intersection' '
 	test_cmp expect actual
 '
 
+test_expect_success 'log --grep --author --match-header-or-grep uses union' '
+	# grep matches only third and fourth
+	# author matches only initial and third
+	git log --author="A U Thor" --grep=r --match-header-or-grep --format=%s >actual &&
+	test_write_lines fourth third initial >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
@@ -971,7 +979,23 @@ test_expect_success 'log --grep --grep --author takes union of greps and interse
 	test_cmp expect actual
 '
 
-test_expect_success 'log ---all-match -grep --author --author still takes union of authors and intersects with grep' '
+test_expect_success 'log --author --grep --grep --match-header-or-grep takes union of greps and author' '
+	# grep matches initial and second but not third
+	# author matches only initial and third
+	git log --author="A U Thor" --grep=second --grep=initial --match-header-or-grep --format=%s >actual &&
+	test_write_lines third second initial >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'log --author --grep --grep --all-match --match-header-or-grep still takes union of greps and author' '
+	# grep matches initial and second but not third
+	# author matches only initial and third
+	git log --author="A U Thor" --grep=second --grep=initial --all-match --match-header-or-grep --format=%s >actual &&
+	test_write_lines third second initial >expect &&
+	test_cmp expect actual
+'
+
+test_expect_success 'log --all-match --grep --author --author still takes union of authors and intersects with grep' '
 	# grep matches only initial and third
 	# author matches all but second
 	git log --all-match --author="Thor" --author="Night" --grep=i --format=%s >actual &&
