summaryrefslogtreecommitdiff
path: root/diff.c
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2022-02-16 23:14:30 (GMT)
committerJunio C Hamano <gitster@pobox.com>2022-02-16 23:14:30 (GMT)
commit9a160990ef3a16fab8d54752d0d9b981d15b00c5 (patch)
tree8c8fdf47b518062223f49fb1105879c5ba3a06cc /diff.c
parent70ff41ffcf93aed8198368af435b0c53fe55ed05 (diff)
parent75408ca94980c125b3a800003c3e6b7cdcb27d44 (diff)
downloadgit-9a160990ef3a16fab8d54752d0d9b981d15b00c5.zip
git-9a160990ef3a16fab8d54752d0d9b981d15b00c5.tar.gz
git-9a160990ef3a16fab8d54752d0d9b981d15b00c5.tar.bz2
Merge branch 'js/diff-filter-negation-fix'
"git diff --diff-filter=aR" is now parsed correctly. * js/diff-filter-negation-fix: diff-filter: be more careful when looking for negative bits diff.c: move the diff filter bits definitions up a bit docs(diff): lose incorrect claim about `diff-files --diff-filter=A`
Diffstat (limited to 'diff.c')
-rw-r--r--diff.c97
1 files changed, 44 insertions, 53 deletions
diff --git a/diff.c b/diff.c
index 32f0c01..7d5cfd3 100644
--- a/diff.c
+++ b/diff.c
@@ -4613,6 +4613,43 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
prep_parse_options(options);
}
+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];
+}
+
+unsigned diff_filter_bit(char status)
+{
+ prepare_filter_bits();
+ return filter_bit[(int) status];
+}
+
void diff_setup_done(struct diff_options *options)
{
unsigned check_mask = DIFF_FORMAT_NAME |
@@ -4726,6 +4763,12 @@ void diff_setup_done(struct diff_options *options)
if (!options->use_color || external_diff())
options->color_moved = 0;
+ if (options->filter_not) {
+ if (!options->filter)
+ options->filter = ~filter_bit[DIFF_STATUS_FILTER_AON];
+ options->filter &= ~options->filter_not;
+ }
+
FREE_AND_NULL(options->parseopts);
}
@@ -4817,43 +4860,6 @@ static int parse_dirstat_opt(struct diff_options *options, const char *params)
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];
-}
-
-unsigned diff_filter_bit(char status)
-{
- prepare_filter_bits();
- return filter_bit[(int) status];
-}
-
static int diff_opt_diff_filter(const struct option *option,
const char *optarg, int unset)
{
@@ -4863,21 +4869,6 @@ static int diff_opt_diff_filter(const struct option *option,
BUG_ON_OPT_NEG(unset);
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;
@@ -4894,7 +4885,7 @@ static int diff_opt_diff_filter(const struct option *option,
return error(_("unknown change class '%c' in --diff-filter=%s"),
optarg[i], optarg);
if (negate)
- opt->filter &= ~bit;
+ opt->filter_not |= bit;
else
opt->filter |= bit;
}