diff: allow lowercase letter to specify what change class to exclude

In order to express "we do not care about deletions", we had to say "--diff-filter=ACMRTXUB", giving all the possible change class except for the one we do not want, "D". This is cumbersome. As all the change classes are in uppercase, allow their lowercase counterpart to selectively exclude the class from the output. When such a negated change class is in the input, start the filter option with the full bits set. This would allow us to express the old "show-diff -q" with "git diff-files --diff-filter=d". Signed-off-by: Junio C Hamano <gitster@pobox.com>

Junio C Hamano committed Jul 17, 2013 at 16:19 UTC 7f2ea5f0f2fb056314092cce23202096ca70f076
1 file changed +28 -1
diff.c
+28 -1
@@ -3532,13 +3532,40 @@ static int parse_diff_filter_opt(const char *optarg, struct diff_options *opt)
3532 int i, optch;
3533
3534 prepare_filter_bits();
3535 +
3536 + /*
3537 + * If there is a negation e.g. 'd' in the input, and we haven't
3538 + * initialized the filter field with another --diff-filter, start
3539 + * from full set of bits, except for AON.
3540 + */
3541 + if (!opt->filter) {
3542 + for (i = 0; (optch = optarg[i]) != '\0'; i++) {
3543 + if (optch < 'a' || 'z' < optch)
3544 + continue;
3545 + opt->filter = (1 << (ARRAY_SIZE(diff_status_letters) - 1)) - 1;
3546 + opt->filter &= ~filter_bit[DIFF_STATUS_FILTER_AON];
3547 + break;
3548 + }
3549 + }
3550 +
3551 for (i = 0; (optch = optarg[i]) != '\0'; i++) {
3552 unsigned int bit;
3553 + int negate;
3554 +
3555 + if ('a' <= optch && optch <= 'z') {
3556 + negate = 1;
3557 + optch = toupper(optch);
3558 + } else {
3559 + negate = 0;
3560 + }
3561
3562 bit = (0 <= optch && optch <= 'Z') ? filter_bit[optch] : 0;
3563 if (!bit)
3564 return optarg[i];
3541 - opt->filter |= bit;
3565 + if (negate)
3566 + opt->filter &= ~bit;
3567 + else
3568 + opt->filter |= bit;
3569 }
3570 return 0;
3571 }