From 22a400a1cd24fdb3da9d2cfc7b11fd796f1ee3ad Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Fri, 20 Feb 2009 14:55:49 +0100 Subject: [PATCH] Teach the '--exclude' option to 'diff --no-index' With this patch, it is possible to exclude files based on basename patterns. Example: $ git diff --no-index -x Makefile -x Makefile.am a/ b/ In this example, the recursive diff between a/ and b/ will be shown modulo changes in files named 'Makefile' or 'Makefile.am'. Signed-off-by: Johannes Schindelin --- diff-no-index.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------ diff.c | 10 ++++++++++ diff.h | 6 ++++++ 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/diff-no-index.c b/diff-no-index.c index aae8e7accc..7b05face51 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -16,7 +16,42 @@ #include "builtin.h" #include "string-list.h" -static int read_directory(const char *path, struct string_list *list) +void add_basename_exclude(const char *exclude, struct diff_options *opts) +{ + if (!opts->basename_excludes) { + opts->basename_excludes = + xcalloc(sizeof(struct string_list), 1); + opts->basename_excludes->strdup_strings = 1; + } + + string_list_append(exclude, opts->basename_excludes); +} + +int basename_is_excluded(const char *basename, struct diff_options *options) +{ + int i; + + if (!options->basename_excludes) + return 0; + + for (i = 0; i < options->basename_excludes->nr; i++) + if (!fnmatch(options->basename_excludes->items[i].string, + basename, 0)) + return 1; + return 0; +} + +void free_basename_excludes(struct diff_options *options) +{ + if (!options->basename_excludes) + return; + string_list_clear(options->basename_excludes, 0); + free(options->basename_excludes); + options->basename_excludes = NULL; +} + +static int read_directory(const char *path, struct string_list *list, + struct diff_options *options) { DIR *dir; struct dirent *e; @@ -25,7 +60,8 @@ static int read_directory(const char *path, struct string_list *list) return error("Could not open directory %s", path); while ((e = readdir(dir))) - if (strcmp(".", e->d_name) && strcmp("..", e->d_name)) + if (strcmp(".", e->d_name) && strcmp("..", e->d_name) && + !basename_is_excluded(e->d_name, options)) string_list_insert(e->d_name, list); closedir(dir); @@ -67,9 +103,9 @@ static int queue_diff(struct diff_options *o, struct string_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1}; int len1 = 0, len2 = 0, i1, i2, ret = 0; - if (name1 && read_directory(name1, &p1)) + if (name1 && read_directory(name1, &p1, o)) return -1; - if (name2 && read_directory(name2, &p2)) { + if (name2 && read_directory(name2, &p2, o)) { string_list_clear(&p1, 0); return -1; } @@ -181,10 +217,12 @@ void diff_no_index(struct rev_info *revs, i++; break; } - if (!strcmp(argv[i], "--no-index")) - no_index = 1; if (argv[i][0] != '-') break; + if (!strcmp(argv[i], "--no-index")) + no_index = 1; + if (!strcmp(argv[i], "-x")) + i++; } if (!no_index && !nongit) { diff --git a/diff.c b/diff.c index 21dd05f5e3..06e42c96ce 100644 --- a/diff.c +++ b/diff.c @@ -2896,6 +2896,14 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) else if (!prefixcmp(arg, "--output=")) { options->file = fopen(arg + strlen("--output="), "w"); options->close_file = 1; + } + else if (!prefixcmp(arg, "--exclude=")) + add_basename_exclude( arg + strlen("--exclude="), options); + else if (!strcmp(arg, "-x")) { + if (ac < 2) + die ("-x needs a parameter"); + add_basename_exclude(av[1], options); + return 2; } else return 0; return 1; @@ -3561,6 +3569,8 @@ free_queue: else DIFF_OPT_CLR(options, HAS_CHANGES); } + + free_basename_excludes(options); } static void diffcore_apply_filter(const char *filter) diff --git a/diff.h b/diff.h index 2ef3341fb0..145fa943b2 100644 --- a/diff.h +++ b/diff.h @@ -120,6 +120,7 @@ struct diff_options { add_remove_fn_t add_remove; diff_format_fn_t format_callback; void *format_callback_data; + struct string_list *basename_excludes; }; enum color_diff { @@ -277,4 +278,9 @@ extern void diff_no_index(struct rev_info *, int, const char **, int, const char extern int index_differs_from(const char *def, int diff_flags); +extern int basename_is_excluded(const char *path, struct diff_options *options); +extern void add_basename_exclude(const char *exclude, + struct diff_options *options); +extern void free_basename_excludes(struct diff_options *options); + #endif /* DIFF_H */ -- 2.11.4.GIT