git/list[1] front-page[2] threads[3] people[4] search[5] about
 

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)
 {
Previous: Jeff KingNext: Anders Melchiorsen
Message 11 of 12 in “Excluding files from git-diff”
  1. Erik HahnOct 17, 2008
  2. Raphael ZimmererOct 17, 2008
  3. Johannes SchindelinOct 17, 2008
  4. Michael J GruberOct 17, 2008
  5. Christian JaegerOct 17, 2008
  6. Eric RaibleOct 17, 2008
  7. Christian JaegerOct 18, 2008
  8. Jeff KingOct 18, 2008
  9. Christian JaegerOct 18, 2008
  10. Jeff KingOct 18, 2008
  11. Jeff KingOct 18, 2008
  12. Anders MelchiorsenOct 17, 2008

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.