diff: allow lowercase letter to specify what change class to exclude
[gitweb.git] / diff.c
diff --git a/diff.c b/diff.c
index 3d37b567781ef1231ef1aa1bd7a89d4d58875a2e..2d0b5e33f93065172f3a85a22ac8ed643089a53e 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -3532,13 +3532,40 @@ static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt)
        int i, optch;
 
        prepare_filter_bits();
+
+       /*
+        * If there is a negation e.g. 'd' in the input, and we haven't
+        * initialized the filter field with another --diff-filter, start
+        * from full set of bits, except for AON.
+        */
+       if (!opt->filter) {
+               for (i = 0; (optch = optarg[i]) != '\0'; i++) {
+                       if (optch < 'a' || 'z' < optch)
+                               continue;
+                       opt->filter = (1 << (ARRAY_SIZE(diff_status_letters) - 1)) - 1;
+                       opt->filter &= ~filter_bit[DIFF_STATUS_FILTER_AON];
+                       break;
+               }
+       }
+
        for (i = 0; (optch = optarg[i]) != '\0'; i++) {
                unsigned int bit;
+               int negate;
+
+               if ('a' <= optch && optch <= 'z') {
+                       negate = 1;
+                       optch = toupper(optch);
+               } else {
+                       negate = 0;
+               }
 
                bit = (0 <= optch && optch <= 'Z') ? filter_bit[optch] : 0;
                if (!bit)
                        return optarg[i];
-               opt->filter |= bit;
+               if (negate)
+                       opt->filter &= ~bit;
+               else
+                       opt->filter |= bit;
        }
        return 0;
 }