{"thread":{"id":"15938","subject":"Excluding files from git-diff","startedAt":"2008-10-17T14:53:13Z","lastAt":"2008-10-18T16:58:34Z","messageCount":12,"participants":["Erik Hahn","Raphael Zimmerer","Johannes Schindelin","Michael J Gruber","Christian Jaeger","Eric Raible","Anders Melchiorsen","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"93298","messageId":"20081017145313.GA23471@eriks","threadId":"15938","inReplyTo":null,"subject":"Excluding files from git-diff","fromName":"Erik Hahn","fromEmail":"erik_hahn@gmx.de","sentAt":"2008-10-17T14:53:13Z","receivedAt":"2008-10-17T14:53:13Z","isPatch":false,"sender":{"key":"erik_hahn@gmx.de","avatar":null},"body":"I'm currently working on a script whose developer does not use\ngit. Hence, when I mail him the patch, I don't want to include the\n.gitignore file. Is it possible to exclude a file from git-diff (except\nnot adding it to git, of course?)\n\n\t-Erik\n\n-- \nhackerkey://v4sw5hw2ln3pr5ck0ma2u7LwXm4l7Gi2e2t4b7Ken4/7a16s0r1p-5.62/-6.56g5OR\n"},{"id":"93300","messageId":"20081017150851.GA20860@rdrz.de","threadId":"15938","inReplyTo":"20081017145313.GA23471@eriks","subject":"Re: Excluding files from git-diff","fromName":"Raphael Zimmerer","fromEmail":"killekulla@rdrz.de","sentAt":"2008-10-17T15:08:51Z","receivedAt":"2008-10-17T15:08:51Z","isPatch":false,"sender":{"key":"killekulla@rdrz.de","avatar":"https://avatars.githubusercontent.com/u/35472983?v=4"},"body":"On Fri, Oct 17, 2008 at 04:53:13PM +0200, Erik Hahn wrote:\n> I'm currently working on a script whose developer does not use\n> git. Hence, when I mail him the patch, I don't want to include the\n> .gitignore file. Is it possible to exclude a file from git-diff (except\n> not adding it to git, of course?)\n\nJust add the content of .gitignore to .git/info/exclude, and remove\n.gitignore from the repository.\n\nRaphael\n"},{"id":"93301","messageId":"alpine.DEB.1.00.0810171708270.4180@racer","threadId":"15938","inReplyTo":"20081017145313.GA23471@eriks","subject":"Re: Excluding files from git-diff","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-10-17T15:08:53Z","receivedAt":"2008-10-17T15:08:53Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Fri, 17 Oct 2008, Erik Hahn wrote:\n\n> I'm currently working on a script whose developer does not use git. \n> Hence, when I mail him the patch, I don't want to include the .gitignore \n> file. Is it possible to exclude a file from git-diff (except not adding \n> it to git, of course?)\n\nYou can specify everything else:\n\n\tgit diff -- *\n\nHth,\nDscho\n"},{"id":"93302","messageId":"48F8ACC2.1010903@drmicha.warpmail.net","threadId":"15938","inReplyTo":"20081017145313.GA23471@eriks","subject":"Re: Excluding files from git-diff","fromName":"Michael J Gruber","fromEmail":"git@drmicha.warpmail.net","sentAt":"2008-10-17T15:18:26Z","receivedAt":"2008-10-17T15:18:26Z","isPatch":false,"sender":{"key":"git@grubix.eu","avatar":"https://avatars.githubusercontent.com/u/233215?v=4"},"body":"Erik Hahn venit, vidit, dixit 17.10.2008 16:53:\n> I'm currently working on a script whose developer does not use\n> git. Hence, when I mail him the patch, I don't want to include the\n> .gitignore file. Is it possible to exclude a file from git-diff (except\n> not adding it to git, of course?)\n\nAm I right in assuming that by \"script\" you mean a manuscript consisting\nof several files, rather than a single script (programme in scripting\nlanguage)? In any case:\n\ngit diff commit1 commit2 file\n\ngives you the diff for \"file\" between those commits, so if you're really\ninterested in one file that's the way to go; you can also specify more\nthan one file here.\n\nOn the other hand, your .gitignore probably doesn't change that often,\nso that it shouldn't show up in the diff after that anyways. Or put it\nin .git/info/excludes.\n\nCheers,\nMichael\n"},{"id":"93305","messageId":"48F8BDA7.50901@pflanze.mine.nu","threadId":"15938","inReplyTo":"48F8ACC2.1010903@drmicha.warpmail.net","subject":"Re: Excluding files from git-diff","fromName":"Christian Jaeger","fromEmail":"christian@pflanze.mine.nu","sentAt":"2008-10-17T16:30:31Z","receivedAt":"2008-10-17T16:30:31Z","isPatch":false,"sender":{"key":"christian@pflanze.mine.nu","avatar":null},"body":"Michael J Gruber wrote:\n> your .gitignore probably doesn't change that often,\n> so that it shouldn't show up in the diff after that anyways. Or put it\n> in .git/info/excludes.\n\nFor me, adding entries to that file does not make \"git diff\" or \"gitk\" \nor even \"git ls-files\" ignore files matching the entries. Only \"git \nls-files --others --exclude-from=.git/info/exclude\" will exclude them. \nAnd \"git diff \" and gitk don't seem to know the --exclude-from option.\n\nIs there a way to really invert the patterns given to \"git diff\" or \nalike? I.e. instead of saying \"git diff -- * .somedotfile \n.someothernongitignoredotfile\" one could just say something like \"git \ndiff --invert-matches -- .gitignore\"? And even better, could one \nconfigure some such so that it has effect on all tools by default?\n\n(That would help working around the clutter problem from the \"Separating \ngenerated files?\" thread; i.e. in some cases this could be good enough \nto not require splitting a project into multiple repositories. (Although \nI'm all the same currently working on a \n\"intergit-find-matching-commit-in\" script, since there may be more good \nreasons than only the clutter to split projects.))\n\nChristian.\n"},{"id":"93306","messageId":"loom.20081017T173145-53@post.gmane.org","threadId":"15938","inReplyTo":"48F8BDA7.50901@pflanze.mine.nu","subject":"Re: Excluding files from git-diff","fromName":"Eric Raible","fromEmail":"raible@gmail.com","sentAt":"2008-10-17T17:33:43Z","receivedAt":"2008-10-17T17:33:43Z","isPatch":false,"sender":{"key":"raible@gmail.com","avatar":null},"body":"Christian Jaeger <christian <at> pflanze.mine.nu> writes:\n\n> \n> Michael J Gruber wrote:\n> > Or put it\n> > in .git/info/excludes.\n> \n> Only \"git ls-files --others --exclude-from=.git/info/exclude\" will exclude\n\nCould it be a simple as \"excludes\" vs \"exclude\"?\n\n- Eric\n"},{"id":"93318","messageId":"48F9220F.5060009@cup.kalibalik.dk","threadId":"15938","inReplyTo":"20081017145313.GA23471@eriks","subject":"Re: Excluding files from git-diff","fromName":"Anders Melchiorsen","fromEmail":"mail@cup.kalibalik.dk","sentAt":"2008-10-17T23:38:55Z","receivedAt":"2008-10-17T23:38:55Z","isPatch":false,"sender":{"key":"mail@cup.kalibalik.dk","avatar":null},"body":"Erik Hahn wrote:\n> I'm currently working on a script whose developer does not use\n> git. Hence, when I mail him the patch, I don't want to include the\n> .gitignore file. Is it possible to exclude a file from git-diff (except\n> not adding it to git, of course?)\n>   \n\n\nI don't think that this is what you are asking about, but it's a neat \ntrick anyway :-).\n\nTo permanently exclude files from git diff, set up a custom diff driver \nin ~/.gitconfig:\n\n[diff \"nodiff\"]\n    command = /bin/true\n\nand then mention the files that should use this driver in \n.git/info/attributes:\n\n.gitignore diff=nodiff\n"},{"id":"93338","messageId":"48F95D09.9070704@pflanze.mine.nu","threadId":"15938","inReplyTo":"loom.20081017T173145-53@post.gmane.org","subject":"Re: Excluding files from git-diff","fromName":"Christian Jaeger","fromEmail":"christian@pflanze.mine.nu","sentAt":"2008-10-18T03:50:33Z","receivedAt":"2008-10-18T03:50:33Z","isPatch":false,"sender":{"key":"christian@pflanze.mine.nu","avatar":null},"body":"Eric Raible wrote:\n> Christian Jaeger <christian <at> pflanze.mine.nu> writes:\n>\n>   \n>> Michael J Gruber wrote:\n>>     \n>>> Or put it\n>>> in .git/info/excludes.\n>>>       \n>> Only \"git ls-files --others --exclude-from=.git/info/exclude\" will exclude\n>>     \n>\n> Could it be a simple as \"excludes\" vs \"exclude\"?\n>   \n\nNope.\n\nln -s exclude .git/info/excludes\ngit ls-files # still shows files matching the excludes\ngit ls-files --exclude-from=.git/info/exclude # does not show\ngit ls-files --exclude-from=.git/info/excludes # does not show\n\nChristian.\n"},{"id":"93374","messageId":"20081018155912.GA20387@coredump.intra.peff.net","threadId":"15938","inReplyTo":"48F8BDA7.50901@pflanze.mine.nu","subject":"Re: Excluding files from git-diff","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-10-18T15:59:13Z","receivedAt":"2008-10-18T15:59:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Oct 17, 2008 at 06:30:31PM +0200, Christian Jaeger wrote:\n\n> For me, adding entries to that file does not make \"git diff\" or \"gitk\" or \n> even \"git ls-files\" ignore files matching the entries. Only \"git ls-files \n> --others --exclude-from=.git/info/exclude\" will exclude them. And \"git \n> diff \" and gitk don't seem to know the --exclude-from option.\n\nWhat you are seeing is:\n\n  - ls-files is plumbing, and does not do any exclusion by default. So\n    you need to use the --exclude-from option, or more easily,\n    --exclude-standard (which pulls in .git/info/excludes, .gitignore,\n    and user-level excludes).\n\n  - porcelain _does_ do exclusion. However, exclusion does not mean \"if\n    this file is tracked by git, don't include it in the diff.\" It\n    merely means \"if this file is untracked, pretend like it is not\n    there.\" So a diff displayed by \"git diff\" isn't affected by\n    exclusions anyway.\n\n> Is there a way to really invert the patterns given to \"git diff\" or  \n> alike? I.e. instead of saying \"git diff -- * .somedotfile  \n> .someothernongitignoredotfile\" one could just say something like \"git  \n> diff --invert-matches -- .gitignore\"? And even better, could one  \n> configure some such so that it has effect on all tools by default?\n\nNo, I don't think there is a way to do that currently. I would probably\ngenerate the file list with a shell snippet:\n\n  git diff -- `git ls-files | grep -v .gitignore`\n\nbut obviously that is a lot more typing if this is something you are\ndoing frequently.\n\n-Peff\n"},{"id":"93376","messageId":"48FA0A17.9050506@pflanze.mine.nu","threadId":"15938","inReplyTo":"20081018155912.GA20387@coredump.intra.peff.net","subject":"Re: Excluding files from git-diff","fromName":"Christian Jaeger","fromEmail":"christian@pflanze.mine.nu","sentAt":"2008-10-18T16:08:55Z","receivedAt":"2008-10-18T16:08:55Z","isPatch":false,"sender":{"key":"christian@pflanze.mine.nu","avatar":null},"body":"Jeff King wrote:\n> No, I don't think there is a way to do that currently. I would probably\n> generate the file list with a shell snippet:\n>\n>   git diff -- `git ls-files | grep -v .gitignore`\n>\n> but obviously that is a lot more typing if this is something you are\n> doing frequently.\n\nThe problem with this is that it won't show files that aren't there \nanymore but have been previously; in general, for that to work (also \nwith git log, for example), the list of files would need to include all \npaths which have ever existed and which are not to be excluded. Even \nthen, I'm not sure whether there are corner case where it would not work \n(when files are being renamed, for example?).\n\nIf I/we (after finishing my intergit-find-matching-commit-in experiment) \nfinally decide that tracking generated files in the same repository is \nthe right thing to do, then I guess the only way to ignore those cleanly \nwould be to add an inverse match feature to the Git core.\n\nChristian.\n"},{"id":"93377","messageId":"20081018161424.GC20185@coredump.intra.peff.net","threadId":"15938","inReplyTo":"48FA0A17.9050506@pflanze.mine.nu","subject":"Re: Excluding files from git-diff","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-10-18T16:14:24Z","receivedAt":"2008-10-18T16:14:24Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 18, 2008 at 06:08:55PM +0200, Christian Jaeger wrote:\n\n> The problem with this is that it won't show files that aren't there  \n> anymore but have been previously; in general, for that to work (also with \n\nYes, you're right. You really do want to be telling git not \"here is the\nlist of files I care about\" but \"I really care about anything _except_\nthis set\".\n\nAnd I don't think that is currently possible, so a patch would be\nnecessary (and I think is justified, since there is no other way to do\nit).\n\nThe most flexible thing would be the ability to say \"I want these paths\n(or all paths), and exclude these paths\" (sort of like we already do for\ncommits). But defining a good command-line syntax for that would\nprobably be painful, and I really think the only sane use case is \"I\nwant all paths except for these\". In which case your \"--invert-match\"\nseems like a good route.\n\n-Peff\n"},{"id":"93378","messageId":"20081018165834.GA28364@coredump.intra.peff.net","threadId":"15938","inReplyTo":"20081018161424.GC20185@coredump.intra.peff.net","subject":"Re: Excluding files from git-diff","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2008-10-18T16:58:34Z","receivedAt":"2008-10-18T16:58:34Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Sat, Oct 18, 2008 at 12:14:24PM -0400, Jeff King wrote:\n\n> The most flexible thing would be the ability to say \"I want these paths\n> (or all paths), and exclude these paths\" (sort of like we already do for\n> commits). But defining a good command-line syntax for that would\n> probably be painful, and I really think the only sane use case is \"I\n> want all paths except for these\". In which case your \"--invert-match\"\n> seems like a good route.\n\nI looked at this a little, so here's as far as I got, in case it helps\nyou in writing a patch.\n\nThere are actually two ways the limiter is used:\n\n 1. diff will show only a subset of the paths, as contained in a\n    diff_options.paths variable\n\n 2. the revision walker will prune based based on changes in particular\n    paths (e.g., \"git log --invert-path -- .gitignore\" should show only\n    commits that touch something besides .gitignore)\n\nThe code to handle '1' might look something like the patch below, but\nthis doesn't deal at all with revision pruning.\n\n---\ndiff --git a/diff.c b/diff.c\nindex 1c6be89..a72f593 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -2646,6 +2646,8 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)\n \t\tDIFF_OPT_CLR(options, ALLOW_EXTERNAL);\n \telse if (!strcmp(arg, \"--ignore-submodules\"))\n \t\tDIFF_OPT_SET(options, IGNORE_SUBMODULES);\n+\telse if (!strcmp(arg, \"--invert-path\"))\n+\t\tDIFF_OPT_SET(options, INVERT_PATH);\n \n \t/* misc options */\n \telse if (!strcmp(arg, \"-z\"))\ndiff --git a/diff.h b/diff.h\nindex a49d865..43f3bff 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -65,6 +65,7 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,\n #define DIFF_OPT_IGNORE_SUBMODULES   (1 << 18)\n #define DIFF_OPT_DIRSTAT_CUMULATIVE  (1 << 19)\n #define DIFF_OPT_DIRSTAT_BY_FILE     (1 << 20)\n+#define DIFF_OPT_INVERT_PATH         (1 << 21)\n #define DIFF_OPT_TST(opts, flag)    ((opts)->flags & DIFF_OPT_##flag)\n #define DIFF_OPT_SET(opts, flag)    ((opts)->flags |= DIFF_OPT_##flag)\n #define DIFF_OPT_CLR(opts, flag)    ((opts)->flags &= ~DIFF_OPT_##flag)\ndiff --git a/tree-diff.c b/tree-diff.c\nindex 9f67af6..ef78d91 100644\n--- a/tree-diff.c\n+++ b/tree-diff.c\n@@ -91,7 +91,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const\n  *  - zero for no\n  *  - negative for \"no, and no subsequent entries will be either\"\n  */\n-static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)\n+static int tree_entry_interesting_internal(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)\n {\n \tconst char *path;\n \tconst unsigned char *sha1;\n@@ -190,6 +190,17 @@ static int tree_entry_interesting(struct tree_desc *desc, const char *base, int\n \treturn never_interesting; /* No matches */\n }\n \n+static int tree_entry_interesting(struct tree_desc *desc, const char *base, int baselen, struct diff_options *opt)\n+{\n+\tint r = tree_entry_interesting_internal(desc, base, baselen, opt);\n+\tif (!DIFF_OPT_TST(opt, INVERT_PATH))\n+\t\treturn r;\n+\treturn r  < 0 ?     2 :\n+\t       r == 0 ?     1 :\n+\t       r == 1 ?     0 :\n+\t       /* r > 1 */ -1;\n+}\n+\n /* A whole sub-tree went away or appeared */\n static void show_tree(struct diff_options *opt, const char *prefix, struct tree_desc *desc, const char *base, int baselen)\n {\n"}]}