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`
This commit is contained in:
commit
9a160990ef
@ -628,11 +628,8 @@ ifndef::git-format-patch[]
|
|||||||
Also, these upper-case letters can be downcased to exclude. E.g.
|
Also, these upper-case letters can be downcased to exclude. E.g.
|
||||||
`--diff-filter=ad` excludes added and deleted paths.
|
`--diff-filter=ad` excludes added and deleted paths.
|
||||||
+
|
+
|
||||||
Note that not all diffs can feature all types. For instance, diffs
|
Note that not all diffs can feature all types. For instance, copied and
|
||||||
from the index to the working tree can never have Added entries
|
renamed entries cannot appear if detection for those types is disabled.
|
||||||
(because the set of paths included in the diff is limited by what is in
|
|
||||||
the index). Similarly, copied and renamed entries cannot appear if
|
|
||||||
detection for those types is disabled.
|
|
||||||
|
|
||||||
-S<string>::
|
-S<string>::
|
||||||
Look for differences that change the number of occurrences of
|
Look for differences that change the number of occurrences of
|
||||||
|
97
diff.c
97
diff.c
@ -4613,6 +4613,43 @@ void repo_diff_setup(struct repository *r, struct diff_options *options)
|
|||||||
prep_parse_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)
|
void diff_setup_done(struct diff_options *options)
|
||||||
{
|
{
|
||||||
unsigned check_mask = DIFF_FORMAT_NAME |
|
unsigned check_mask = DIFF_FORMAT_NAME |
|
||||||
@ -4726,6 +4763,12 @@ void diff_setup_done(struct diff_options *options)
|
|||||||
if (!options->use_color || external_diff())
|
if (!options->use_color || external_diff())
|
||||||
options->color_moved = 0;
|
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);
|
FREE_AND_NULL(options->parseopts);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4817,43 +4860,6 @@ static int parse_dirstat_opt(struct diff_options *options, const char *params)
|
|||||||
return 1;
|
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,
|
static int diff_opt_diff_filter(const struct option *option,
|
||||||
const char *optarg, int unset)
|
const char *optarg, int unset)
|
||||||
{
|
{
|
||||||
@ -4863,21 +4869,6 @@ static int diff_opt_diff_filter(const struct option *option,
|
|||||||
BUG_ON_OPT_NEG(unset);
|
BUG_ON_OPT_NEG(unset);
|
||||||
prepare_filter_bits();
|
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++) {
|
for (i = 0; (optch = optarg[i]) != '\0'; i++) {
|
||||||
unsigned int bit;
|
unsigned int bit;
|
||||||
int negate;
|
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"),
|
return error(_("unknown change class '%c' in --diff-filter=%s"),
|
||||||
optarg[i], optarg);
|
optarg[i], optarg);
|
||||||
if (negate)
|
if (negate)
|
||||||
opt->filter &= ~bit;
|
opt->filter_not |= bit;
|
||||||
else
|
else
|
||||||
opt->filter |= bit;
|
opt->filter |= bit;
|
||||||
}
|
}
|
||||||
|
2
diff.h
2
diff.h
@ -283,7 +283,7 @@ struct diff_options {
|
|||||||
struct diff_flags flags;
|
struct diff_flags flags;
|
||||||
|
|
||||||
/* diff-filter bits */
|
/* diff-filter bits */
|
||||||
unsigned int filter;
|
unsigned int filter, filter_not;
|
||||||
|
|
||||||
int use_color;
|
int use_color;
|
||||||
|
|
||||||
|
@ -142,6 +142,19 @@ test_expect_success 'diff-filter=R' '
|
|||||||
|
|
||||||
'
|
'
|
||||||
|
|
||||||
|
test_expect_success 'multiple --diff-filter bits' '
|
||||||
|
|
||||||
|
git log -M --pretty="format:%s" --diff-filter=R HEAD >expect &&
|
||||||
|
git log -M --pretty="format:%s" --diff-filter=Ra HEAD >actual &&
|
||||||
|
test_cmp expect actual &&
|
||||||
|
git log -M --pretty="format:%s" --diff-filter=aR HEAD >actual &&
|
||||||
|
test_cmp expect actual &&
|
||||||
|
git log -M --pretty="format:%s" \
|
||||||
|
--diff-filter=a --diff-filter=R HEAD >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
|
||||||
|
'
|
||||||
|
|
||||||
test_expect_success 'diff-filter=C' '
|
test_expect_success 'diff-filter=C' '
|
||||||
|
|
||||||
git log -C -C --pretty="format:%s" --diff-filter=C HEAD >actual &&
|
git log -C -C --pretty="format:%s" --diff-filter=C HEAD >actual &&
|
||||||
|
Loading…
x
Reference in New Issue
Block a user