Merge branch 'cj/log-invert-grep'
authorJunio C Hamano <gitster@pobox.com>
Wed, 11 Feb 2015 21:42:39 +0000 (13:42 -0800)
committerJunio C Hamano <gitster@pobox.com>
Wed, 11 Feb 2015 21:42:39 +0000 (13:42 -0800)
"git log --invert-grep --grep=WIP" will show only commits that do
not have the string "WIP" in their messages.

* cj/log-invert-grep:
log: teach --invert-grep option

Documentation/rev-list-options.txt
contrib/completion/git-completion.bash
revision.c
revision.h
t/t4202-log.sh
index 2984f407a9f3084235fd0207a82ea44a424942ed..0f3d460d34a6285687792c22c66a24921f17baa7 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 8cfee95f88006269e4227f98701b9af8587af0bd..c21190d7510c173482b7784f9e8c4bf0b56cb1e1 100644 (file)
@@ -1425,7 +1425,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 86406a26a2d4599ea401d1faa9a817cadb3b7bcd..4bc851c070e40fbdc7aedf5edc9db78f808f328e 100644 (file)
@@ -2017,6 +2017,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);
@@ -2915,7 +2917,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 033a24460e71b723f95ef91f4b6f0dbfd8c2c390..17ebafc4c76de4ac74f5b977101af1aedd1a1ae9 100644 (file)
@@ -169,6 +169,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 &&