diff --git a/diff.c b/diff.c index 3d37b56778..2d0b5e33f9 100644 --- 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; }