Skip to content

Commit

Permalink
log: teach --invert-grep option
Browse files Browse the repository at this point in the history
"git log --grep=<string>" shows only commits with messages that
match the given string, but sometimes it is useful to be able to
show only commits that do *not* have certain messages (e.g. "show
me ones that are not FIXUP commits").

Originally, we had the invert-grep flag in grep_opt, but because
"git grep --invert-grep" does not make sense except in conjunction
with "--files-with-matches", which is already covered by
"--files-without-matches", it was moved it to revisions structure.
To have the flag there expresses the function to the feature better.

When the newly inserted two tests run, the history would have commits
with messages "initial", "second", "third", "fourth", "fifth", "sixth"
and "Second", committed in this order.  The commits that does not match
either "th" or "Sec" is "second" and "initial". For the case insensitive
case only "initial" matches.

Signed-off-by: Christoph Junghans <ottxor@gentoo.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Christoph Junghans authored and Junio C Hamano committed Jan 13, 2015
1 parent 3c84ac8 commit 22dfa8a
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 2 deletions.
4 changes: 4 additions & 0 deletions Documentation/rev-list-options.txt
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ if it is part of the log message.
Limit the commits output to ones that match all given `--grep`,
instead of ones that match at least one.

--invert-grep::
Limit the commits output to ones with log message that do not
match the pattern specified with `--grep=<pattern>`.

-i::
--regexp-ignore-case::
Match the regular expression limiting patterns without regard to letter
Expand Down
2 changes: 1 addition & 1 deletion contrib/completion/git-completion.bash
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ __git_log_gitk_options="
# Options that go well for log and shortlog (not gitk)
__git_log_shortlog_options="
--author= --committer= --grep=
--all-match
--all-match --invert-grep
"

__git_log_pretty_formats="oneline short medium full fuller email raw format:"
Expand Down
4 changes: 3 additions & 1 deletion revision.c
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
grep_set_pattern_type_option(GREP_PATTERN_TYPE_PCRE, &revs->grep_filter);
} else if (!strcmp(arg, "--all-match")) {
revs->grep_filter.all_match = 1;
} else if (!strcmp(arg, "--invert-grep")) {
revs->invert_grep = 1;
} else if ((argcount = parse_long_opt("encoding", argv, &optarg))) {
if (strcmp(optarg, "none"))
git_log_output_encoding = xstrdup(optarg);
Expand Down Expand Up @@ -2848,7 +2850,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
(char *)message, strlen(message));
strbuf_release(&buf);
unuse_commit_buffer(commit, message);
return retval;
return opt->invert_grep ? !retval : retval;
}

static inline int want_ancestry(const struct rev_info *revs)
Expand Down
2 changes: 2 additions & 0 deletions revision.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@ struct rev_info {

/* Filter by commit log message */
struct grep_opt grep_filter;
/* Negate the match of grep_filter */
int invert_grep;

/* Display history graph */
struct git_graph *graph;
Expand Down
15 changes: 15 additions & 0 deletions t/t4202-log.sh
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,21 @@ test_expect_success 'log --grep' '
test_cmp expect actual
'

cat > expect << EOF
second
initial
EOF
test_expect_success 'log --invert-grep --grep' '
git log --pretty="tformat:%s" --invert-grep --grep=th --grep=Sec >actual &&
test_cmp expect actual
'

test_expect_success 'log --invert-grep --grep -i' '
echo initial >expect &&
git log --pretty="tformat:%s" --invert-grep -i --grep=th --grep=Sec >actual &&
test_cmp expect actual
'

test_expect_success 'log --grep option parsing' '
echo second >expect &&
git log -1 --pretty="tformat:%s" --grep sec >actual &&
Expand Down

0 comments on commit 22dfa8a

Please sign in to comment.