Re: Excluding files from git-diff
- From
Jeff King <peff@peff.net>
- Date
- Oct 18, 2008, 16:58 UTC
- Message-ID
- <20081018165834.GA28364@coredump.intra.peff.net>
- In-Reply-To
- <20081018161424.GC20185@coredump.intra.peff.net>
On Sat, Oct 18, 2008 at 12:14:24PM -0400, Jeff King wrote:
Show 6 quoted lines
> 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) {