Browse Source

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()
maint
Junio C Hamano 12 years ago
parent
commit
01a2a03c56
  1. 8
      diff-lib.c
  2. 7
      diff-no-index.c
  3. 125
      diff.c
  4. 7
      diff.h

8
diff-lib.c

@ -87,10 +87,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option) @@ -87,10 +87,12 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
{
int entries, i;
int diff_unmerged_stage = revs->max_count;
int silent_on_removed = option & DIFF_SILENT_ON_REMOVED;
unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
? CE_MATCH_RACY_IS_DIRTY : 0);

if (option & DIFF_SILENT_ON_REMOVED)
handle_deprecated_show_diff_q(&revs->diffopt);

diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/");

if (diff_unmerged_stage < 0)
@ -137,8 +139,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) @@ -137,8 +139,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
perror(ce->name);
continue;
}
if (silent_on_removed)
continue;
wt_mode = 0;
}
dpath->mode = wt_mode;
@ -204,8 +204,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option) @@ -204,8 +204,6 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
perror(ce->name);
continue;
}
if (silent_on_removed)
continue;
diff_addremove(&revs->diffopt, '-', ce->ce_mode,
ce->sha1, !is_null_sha1(ce->sha1),
ce->name, 0);

7
diff-no-index.c

@ -187,7 +187,7 @@ void diff_no_index(struct rev_info *revs, @@ -187,7 +187,7 @@ void diff_no_index(struct rev_info *revs,
{
int i, prefixlen;
int no_index = 0;
unsigned options = 0;
unsigned deprecated_show_diff_q_option_used = 0;
const char *paths[2];

/* Were we asked to do --no-index explicitly? */
@ -225,7 +225,7 @@ void diff_no_index(struct rev_info *revs, @@ -225,7 +225,7 @@ void diff_no_index(struct rev_info *revs,
if (!strcmp(argv[i], "--no-index"))
i++;
else if (!strcmp(argv[i], "-q")) {
options |= DIFF_SILENT_ON_REMOVED;
deprecated_show_diff_q_option_used = 1;
i++;
}
else if (!strcmp(argv[i], "--"))
@ -260,6 +260,9 @@ void diff_no_index(struct rev_info *revs, @@ -260,6 +260,9 @@ void diff_no_index(struct rev_info *revs,
revs->max_count = -2;
diff_setup_done(&revs->diffopt);

if (deprecated_show_diff_q_option_used)
handle_deprecated_show_diff_q(&revs->diffopt);

setup_diff_pager(&revs->diffopt);
DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);


125
diff.c

@ -3503,6 +3503,88 @@ static int parse_submodule_opt(struct diff_options *options, const char *value) @@ -3503,6 +3503,88 @@ static int parse_submodule_opt(struct diff_options *options, const char *value)
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;
@ -3732,7 +3814,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) @@ -3732,7 +3814,10 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
return argcount;
}
else if ((argcount = parse_long_opt("diff-filter", av, &optarg))) {
options->filter = optarg;
int offending = parse_diff_filter_opt(optarg, options);
if (offending)
die("unknown change class '%c' in --diff-filter=%s",
offending, optarg);
return argcount;
}
else if (!strcmp(arg, "--abbrev"))
@ -4524,27 +4609,32 @@ free_queue: @@ -4524,27 +4609,32 @@ free_queue:
}
}

static void diffcore_apply_filter(const char *filter)
static int match_filter(const struct diff_options *options, const struct diff_filepair *p)
{
return (((p->status == DIFF_STATUS_MODIFIED) &&
((p->score &&
filter_bit_tst(DIFF_STATUS_FILTER_BROKEN, options)) ||
(!p->score &&
filter_bit_tst(DIFF_STATUS_MODIFIED, options)))) ||
((p->status != DIFF_STATUS_MODIFIED) &&
filter_bit_tst(p->status, options)));
}

static void diffcore_apply_filter(struct diff_options *options)
{
int i;
struct diff_queue_struct *q = &diff_queued_diff;
struct diff_queue_struct outq;

DIFF_QUEUE_CLEAR(&outq);

if (!filter)
if (!options->filter)
return;

if (strchr(filter, DIFF_STATUS_FILTER_AON)) {
if (filter_bit_tst(DIFF_STATUS_FILTER_AON, options)) {
int found;
for (i = found = 0; !found && i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];
if (((p->status == DIFF_STATUS_MODIFIED) &&
((p->score &&
strchr(filter, DIFF_STATUS_FILTER_BROKEN)) ||
(!p->score &&
strchr(filter, DIFF_STATUS_MODIFIED)))) ||
((p->status != DIFF_STATUS_MODIFIED) &&
strchr(filter, p->status)))
if (match_filter(options, q->queue[i]))
found++;
}
if (found)
@ -4562,14 +4652,7 @@ static void diffcore_apply_filter(const char *filter) @@ -4562,14 +4652,7 @@ static void diffcore_apply_filter(const char *filter)
/* Only the matching ones */
for (i = 0; i < q->nr; i++) {
struct diff_filepair *p = q->queue[i];

if (((p->status == DIFF_STATUS_MODIFIED) &&
((p->score &&
strchr(filter, DIFF_STATUS_FILTER_BROKEN)) ||
(!p->score &&
strchr(filter, DIFF_STATUS_MODIFIED)))) ||
((p->status != DIFF_STATUS_MODIFIED) &&
strchr(filter, p->status)))
if (match_filter(options, p))
diff_q(&outq, p);
else
diff_free_filepair(p);
@ -4676,7 +4759,7 @@ void diffcore_std(struct diff_options *options) @@ -4676,7 +4759,7 @@ void diffcore_std(struct diff_options *options)
if (!options->found_follow)
/* See try_to_follow_renames() in tree-diff.c */
diff_resolve_rename_copy();
diffcore_apply_filter(options->filter);
diffcore_apply_filter(options);

if (diff_queued_diff.nr && !DIFF_OPT_TST(options, DIFF_FROM_CONTENTS))
DIFF_OPT_SET(options, HAS_CHANGES);

7
diff.h

@ -103,12 +103,15 @@ enum diff_words_type { @@ -103,12 +103,15 @@ enum diff_words_type {
};

struct diff_options {
const char *filter;
const char *orderfile;
const char *pickaxe;
const char *single_follow;
const char *a_prefix, *b_prefix;
unsigned flags;

/* diff-filter bits */
unsigned int filter;

int use_color;
int context;
int interhunkcontext;
@ -338,6 +341,8 @@ extern int parse_rename_score(const char **cp_p); @@ -338,6 +341,8 @@ extern int parse_rename_score(const char **cp_p);

extern long parse_algorithm_value(const char *value);

extern void handle_deprecated_show_diff_q(struct diff_options *);

extern int print_stat_summary(FILE *fp, int files,
int insertions, int deletions);
extern void setup_diff_pager(struct diff_options *);

Loading…
Cancel
Save