From: Junio C Hamano Date: Mon, 9 Sep 2013 21:28:35 +0000 (-0700) Subject: Merge branch 'jc/diff-filter-negation' X-Git-Tag: v1.8.5-rc0~173 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/01a2a03c56e8d4cd9724b185a48a2a1ea9852f0c Merge branch 'jc/diff-filter-negation' Teach "git diff --diff-filter" to express "I do not want to see these classes of changes" more directly by listing only the unwanted ones in lowercase (e.g. "--diff-filter=d" will show everything but deletion) and deprecate "diff-files -q" which did the same thing as "--diff-filter=d". * jc/diff-filter-negation: diff: deprecate -q option to diff-files diff: allow lowercase letter to specify what change class to exclude diff: reject unknown change class given to --diff-filter diff: preparse --diff-filter string argument diff: factor out match_filter() diff: pass the whole diff_options to diffcore_apply_filter() --- 01a2a03c56e8d4cd9724b185a48a2a1ea9852f0c diff --cc diff.c index 061694b5ea,78819ba151..a04a34d048 --- a/diff.c +++ b/diff.c @@@ -3503,11 -3496,88 +3503,93 @@@ static int parse_submodule_opt(struct d return 1; } + static const char diff_status_letters[] = { + DIFF_STATUS_ADDED, + DIFF_STATUS_COPIED, + DIFF_STATUS_DELETED, + DIFF_STATUS_MODIFIED, + DIFF_STATUS_RENAMED, + DIFF_STATUS_TYPE_CHANGED, + DIFF_STATUS_UNKNOWN, + DIFF_STATUS_UNMERGED, + DIFF_STATUS_FILTER_AON, + DIFF_STATUS_FILTER_BROKEN, + '\0', + }; + + static unsigned int filter_bit['Z' + 1]; + + static void prepare_filter_bits(void) + { + int i; + + if (!filter_bit[DIFF_STATUS_ADDED]) { + for (i = 0; diff_status_letters[i]; i++) + filter_bit[(int) diff_status_letters[i]] = (1 << i); + } + } + + static unsigned filter_bit_tst(char status, const struct diff_options *opt) + { + return opt->filter & filter_bit[(int) status]; + } + + 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]; + if (negate) + opt->filter &= ~bit; + else + opt->filter |= bit; + } + return 0; + } + + /* Used only by "diff-files" and "diff --no-index" */ + void handle_deprecated_show_diff_q(struct diff_options *opt) + { + warning("'diff -q' and 'diff-files -q' are deprecated."); + warning("Use 'diff --diff-filter=d' instead to ignore deleted filepairs."); + parse_diff_filter_opt("d", opt); + } + +static void enable_patch_output(int *fmt) { + *fmt &= ~DIFF_FORMAT_NO_OUTPUT; + *fmt |= DIFF_FORMAT_PATCH; +} + int diff_opt_parse(struct diff_options *options, const char **av, int ac) { const char *arg = av[0];