On Sat, Oct 18, 2008 at 12:14:24PM -0400, Jeff King wrote: > The most flexible thing would be the ability to say "I want these paths > (or all paths), and exclude these paths" (sort of like we already do for > commits). But defining a good command-line syntax for that would > probably be painful, and I really think the only sane use case is "I > want all paths except for these". In which case your "--invert-match" > seems like a good route. I looked at this a little, so here's as far as I got, in case it helps you in writing a patch. There are actually two ways the limiter is used: 1. diff will show only a subset of the paths, as contained in a diff_options.paths variable 2. the revision walker will prune based based on changes in particular paths (e.g., "git log --invert-path -- .gitignore" should show only commits that touch something besides .gitignore) The code to handle '1' might look something like the patch below, but this doesn't deal at all with revision pruning. --- diff --git a/diff.c b/diff.c index 1c6be89..a72f593 100644 --- a/diff.c +++ b/diff.c @@ -2646,6 +2646,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac) DIFF_OPT_CLR(options, ALLOW_EXTERNAL); else if (!strcmp(arg, "--ignore-submodules")) DIFF_OPT_SET(options, IGNORE_SUBMODULES); + else if (!strcmp(arg, "--invert-path")) + DIFF_OPT_SET(options, INVERT_PATH); /* misc options */ else if (!strcmp(arg, "-z")) diff --git a/diff.h b/diff.h index a49d865..43f3bff 100644 --- a/diff.h +++ b/diff.h @@ -65,6 +65,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q, #define DIFF_OPT_IGNORE_SUBMODULES (1 << 18) #define DIFF_OPT_DIRSTAT_CUMULATIVE (1 << 19) #define DIFF_OPT_DIRSTAT_BY_FILE (1 << 20) +#define DIFF_OPT_INVERT_PATH (1 << 21) #define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag) #define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag) #define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag) diff --git a/tree-diff.c b/tree-diff.c index 9f67af6..ef78d91 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -91,7 +91,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const * - zero for no * - negative for "no, and no subsequent entries will be either" */ -static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt) +static int tree_entry_interesting_internal(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt) { const char *path; const unsigned char *sha1; @@ -190,6 +190,17 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int return never_interesting; /* No matches */ } +static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt) +{ + int r = tree_entry_interesting_internal(desc, base, baselen, opt); + if (!DIFF_OPT_TST(opt, INVERT_PATH)) + return r; + return r < 0 ? 2 : + r == 0 ? 1 : + r == 1 ? 0 : + /* r > 1 */ -1; +} + /* A whole sub-tree went away or appeared */ static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen) { -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html