]> git.ipfire.org Git - thirdparty/git.git/commitdiff
log: teach --invert-grep option
authorChristoph Junghans <ottxor@gentoo.org>
Tue, 13 Jan 2015 01:33:32 +0000 (18:33 -0700)
committerJunio C Hamano <gitster@pobox.com>
Tue, 13 Jan 2015 18:20:32 +0000 (10:20 -0800)
"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>
Documentation/rev-list-options.txt
contrib/completion/git-completion.bash
revision.c
revision.h
t/t4202-log.sh

index deb8cca9173ccbaf8c15ade3f8b3312fb6bdcbad..05aa997fd1037d9a26cb5cf6ab05874293f1a3ef 100644 (file)
@@ -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
index 06bf262087768d98450cb589eb8f8fcc51ed2f74..53857f0bbf608ca9c8d24e5c8dce328de7c825cc 100644 (file)
@@ -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:"
index 615535c98453336323a437530132f27824b51ac2..84b33a33ca1100e39220f68b637cfebdab640a60 100644 (file)
@@ -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);
@@ -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)
index a6205307cf3bb2364b8642b0a4857c5b0ae9b5a9..b0b82e766eba38e4881757e841229e5d8b1c3744 100644 (file)
@@ -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;
index 99ab7ca21f2673e646232d9c07f77c8ed2f5f998..5f2b290d2b803a4af971a1c03021e97a16951847 100755 (executable)
@@ -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 &&