{"thread":{"id":"355","subject":"[PATCH] add a diff-files command","startedAt":"2005-04-27T21:13:23Z","lastAt":"2005-04-28T17:16:08Z","messageCount":6,"participants":["Nicolas Pitre","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"1911","messageId":"Pine.LNX.4.62.0504271701080.14033@localhost.localdomain","threadId":"355","inReplyTo":null,"subject":"[PATCH] add a diff-files command","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2005-04-27T21:13:23Z","receivedAt":"2005-04-27T21:13:23Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"\nIn the same spirit as diff-tree and diff-cache, here is a diff-files \ncommand that processes differences between the index cache and the \nworking directory content.  It produces lists of files that are either \nchanged (-c), deleted (-d) or outside (-o) from the current cache, or a \ncombination of those, or all of them (-a).\n\nThe -p option can also be used to generate a patch describing the \nchanges directly.\n\nIt also has the ability to accept exclude file patterns with -x and even \na file containing a list of patterns to exclude with -X.  This is \nespecially useful to use the famous dontdiff file when looking for \nuncommitted files in a compiled kernel tree.\n\nSigned-off-by: Nicolas Pitre <nico@cam.org>\n\n--- k/Makefile\n+++ l/Makefile\n@@ -18,7 +18,7 @@ PROG=   update-cache show-diff init-db w\n \tcat-file fsck-cache checkout-cache diff-tree rev-tree show-files \\\n \tcheck-files ls-tree merge-base merge-cache unpack-file git-export \\\n \tdiff-cache convert-cache http-pull rpush rpull rev-list git-mktag \\\n-\tdiff-tree-helper\n+\tdiff-tree-helper diff-files\n \n all: $(PROG)\n \n--- k/diff-files.c\n+++ l/diff-files.c\n@@ -0,0 +1,362 @@\n+/*\n+ * GIT - The information manager from hell\n+ *\n+ * Copyright (C) Linus Torvalds, 2005\n+ */\n+\n+#include <dirent.h>\n+#include <fnmatch.h>\n+#include \"cache.h\"\n+#include \"diff.h\"\n+\n+static const char *diff_files_usage = \"diff-files [-a] [-c] [-d] [-o] [-p | -z]\"\n+\t\t\t\t      \" [-x <pattern>] [-X <file>] [paths...]\";\n+\n+/* What paths are we interested in? */\n+static int nr_paths = 0;\n+static char **paths = NULL;\n+static int *pathlens = NULL;\n+\n+static int nr_excludes;\n+static const char **excludes;\n+static int excludes_alloc;\n+\n+static void add_exclude(const char *string)\n+{\n+\tif (nr_excludes == excludes_alloc) {\n+\t\texcludes_alloc = alloc_nr(excludes_alloc);\n+\t\texcludes = realloc(excludes, excludes_alloc*sizeof(char *));\n+\t}\n+\texcludes[nr_excludes++] = string;\n+}\n+\n+static void add_excludes_from_file(const char *fname)\n+{\n+\tint fd, i;\n+\tlong size;\n+\tchar *buf, *entry;\n+\n+\tfd = open(fname, O_RDONLY);\n+\tif (fd < 0)\n+\t\tgoto err;\n+\tsize = lseek(fd, 0, SEEK_END);\n+\tif (size < 0)\n+\t\tgoto err;\n+\tlseek(fd, 0, SEEK_SET);\n+\tif (size == 0) {\n+\t\tclose(fd);\n+\t\treturn;\n+\t}\n+\tbuf = malloc(size);\n+\tif (!buf) {\n+\t\terrno = ENOMEM;\n+\t\tgoto err;\n+\t}\n+\tif (read(fd, buf, size) != size)\n+\t\tgoto err;\n+\tclose(fd);\n+\n+\tentry = buf;\n+\tfor (i = 0; i < size; i++) {\n+\t\tif (buf[i] == '\\n') {\n+\t\t\tif (entry != buf + i) {\n+\t\t\t\tbuf[i] = 0;\n+\t\t\t\tadd_exclude(entry);\n+\t\t\t}\n+\t\t\tentry = buf + i + 1;\n+\t\t}\n+\t}\n+\treturn;\n+\n+err:\tperror(fname);\n+\texit(1);\n+}\n+\n+/*\n+ * See if name matches our specified paths and is not excluded.\n+ * return value:\n+ *\t-1 if no match\n+ *\t0 if partial match (name is a directory component)\n+ *\t1 = exact match\n+ *\t2 = name is under a specified directory path with no excludes\n+ */\n+static int path_match(const char *name, int namelen)\n+{\n+\tint i, ret;\n+\n+\t/* fast case: no path list and no exclude list */\n+\tif (!nr_paths && !nr_excludes)\n+\t\treturn 2;\n+\n+\tret = (nr_paths) ? -1 : 1;\n+\tfor (i = 0; i < nr_paths; i++) {\n+\t\tint pathlen = pathlens[i];\n+\t\tif (pathlen == namelen &&\n+\t\t    strncmp(paths[i], name, pathlen) == 0) {\n+\t\t\tret = 1;\n+\t\t\tbreak;\n+\t\t} else if (pathlen > namelen && \n+\t\t\t   strncmp(paths[i], name, namelen) == 0 &&\n+\t\t\t   paths[i][namelen] == '/') {\n+\t\t\tret = 0;\n+\t\t\tbreak;\n+\t\t} else if (pathlen < namelen &&\n+\t\t\t   strncmp(paths[i], name, pathlen) == 0 &&\n+\t\t\t   name[pathlen] == '/') {\n+\t\t\tret = (nr_excludes) ? 1 : 2;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\tif (ret >= 0 && nr_excludes) {\n+\t\tconst char *basename = strrchr(name, '/');\n+\t\tbasename = (basename) ? basename+1 : name;\n+\t\tfor (i = 0; i < nr_excludes; i++) {\n+\t\t\tif (fnmatch(excludes[i], basename, 0) == 0) {\n+\t\t\t\tret = -1;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\treturn ret;\n+}\n+\n+static const char **others;\n+static int nr_others;\n+static int others_alloc;\n+\n+static void add_name(const char *pathname, int len)\n+{\n+\tchar *name;\n+\n+\tif (cache_name_pos(pathname, len) >= 0)\n+\t\treturn;\n+\n+\tif (nr_others == others_alloc) {\n+\t\tothers_alloc = alloc_nr(others_alloc);\n+\t\tothers = realloc(others, others_alloc*sizeof(char *));\n+\t}\n+\tname = malloc(len + 1);\n+\tmemcpy(name, pathname, len + 1);\n+\tothers[nr_others++] = name;\n+}\n+\n+/*\n+ * Read a directory tree. We currently ignore anything but\n+ * directories and regular files. That's because git doesn't\n+ * handle them at all yet. Maybe that will change some day.\n+ *\n+ * Also, we currently ignore all names starting with a dot.\n+ * That likely will not change.\n+ */\n+static void read_directory(const char *path, const char *base, int baselen, int match)\n+{\n+\tDIR *dir = opendir(path);\n+\n+\tif (dir) {\n+\t\tstruct dirent *de;\n+\t\tchar fullname[MAXPATHLEN + 1];\n+\t\tmemcpy(fullname, base, baselen);\n+\n+\t\twhile ((de = readdir(dir)) != NULL) {\n+\t\t\tint len;\n+\n+\t\t\tif (de->d_name[0] == '.')\n+\t\t\t\tcontinue;\n+\t\t\tlen = strlen(de->d_name);\n+\t\t\tmemcpy(fullname + baselen, de->d_name, len+1);\n+\t\t\tif (match < 2)\n+\t\t\t\tmatch = path_match(fullname, baselen+len);\n+\t\t\tif (match < 0)\n+\t\t\t\tcontinue;\n+\n+\t\t\tswitch (de->d_type) {\n+\t\t\tstruct stat st;\n+\t\t\tdefault:\n+\t\t\t\tcontinue;\n+\t\t\tcase DT_UNKNOWN:\n+\t\t\t\tif (lstat(fullname, &st))\n+\t\t\t\t\tcontinue;\n+\t\t\t\tif (S_ISREG(st.st_mode))\n+\t\t\t\t\tbreak;\n+\t\t\t\tif (!S_ISDIR(st.st_mode))\n+\t\t\t\t\tcontinue;\n+\t\t\t\t/* fallthrough */\n+\t\t\tcase DT_DIR:\n+\t\t\t\tmemcpy(fullname + baselen + len, \"/\", 2);\n+\t\t\t\tread_directory(fullname, fullname,\n+\t\t\t\t\t       baselen + len + 1, match);\n+\t\t\t\tcontinue;\n+\t\t\tcase DT_REG:\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (match > 0)\n+\t\t\t\tadd_name(fullname, baselen + len);\n+\t\t}\n+\t\tclosedir(dir);\n+\t}\n+}\n+\n+static int cmp_name(const void *p1, const void *p2)\n+{\n+\tconst char *n1 = *(const char **)p1;\n+\tconst char *n2 = *(const char **)p2;\n+\tint l1 = strlen(n1), l2 = strlen(n2);\n+\n+\treturn cache_name_compare(n1, l1, n2, l2);\n+}\n+\n+static int show_changed = 0;\n+static int show_deleted = 0;\n+static int show_others = 0;\n+static int generate_patch = 0;\n+static int line_terminator = '\\n';\n+\n+static const char null_sha1[20];\n+static const char null_sha1_hex[] = \"0000000000000000000000000000000000000000\";\n+\n+static void show_file(int prefix, unsigned int mode,\n+\t\t      const char *sha1, const char *name)\n+{\n+\tif (generate_patch)\n+\t\tdiff_addremove(prefix, mode, sha1, name, NULL);\n+\telse\n+\t\tprintf(\"%c%o\\t%s\\t%s\\t%s%c\", prefix, mode, \"blob\",\n+\t\t       sha1_to_hex(sha1), name, line_terminator);\n+}\n+\n+int main(int argc, char **argv)\n+{\n+\tint i, entries;\n+\n+\tfor (i = 1; i < argc; i++) {\n+\t\tchar *arg = argv[i];\n+\n+\t\tif (*arg != '-')\n+\t\t\tbreak;\n+\n+\t\tif (!strcmp(arg, \"-z\")) {\n+\t\t\tline_terminator = 0;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-a\")) {\n+\t\t\tshow_changed = show_deleted = show_others = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-c\")) {\n+\t\t\tshow_changed = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-d\")) {\n+\t\t\tshow_deleted = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-o\")) {\n+\t\t\tshow_others = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-p\")) {\n+\t\t\tgenerate_patch = 1;\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-x\") && i+1 < argc) {\n+\t\t\targ = argv[++i];\n+\t\t\tadd_exclude(arg);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"-X\") && i+1 < argc) {\n+\t\t\targ = argv[++i];\n+\t\t\tadd_excludes_from_file(arg);\n+\t\t\tcontinue;\n+\t\t}\n+\t\tif (!strcmp(arg, \"--\")) {\n+\t\t\ti++;\n+\t\t\tbreak;\n+\t\t}\n+\n+\t\tusage(diff_files_usage);\n+\t}\n+\n+\t/* default to -c if none of -c, -d nor -o have been specified */\n+\tif (!show_changed && !show_deleted && !show_others)\n+\t\tshow_changed = 1;\n+\n+\tif (i < argc) {\n+\t\tpaths = &argv[i];\n+\t\tnr_paths = argc - i;\n+\t\tpathlens = malloc(nr_paths * sizeof(int));\n+\t\tfor (i=0; i<nr_paths; i++) {\n+\t\t\tpathlens[i] = strlen(paths[i]);\n+\t\t\tif (paths[i][pathlens[i] - 1] == '/')\n+\t\t\t\tpathlens[i]--;\n+\t\t}\n+\t}\n+\n+\tentries = read_cache();\n+\tif (entries < 0) {\n+\t\tperror(\"read_cache\");\n+\t\texit(1);\n+\t}\n+\n+\tif (show_others) {\n+\t\tread_directory(\".\", \"\", 0, 0);\n+\t\tqsort(others, nr_others, sizeof(char *), cmp_name);\n+\t\tfor (i = 0; i < nr_others; i++) {\n+\t\t\tstruct stat st;\n+\t\t\tunsigned int mode;\n+\t\t\tif (stat(others[i], &st) < 0) {\n+\t\t\t\tperror(others[i]);\n+\t\t\t} else {\n+\t\t\t\tmode = S_IFREG | ce_permissions(st.st_mode);\n+\t\t\t\tshow_file('+', mode, null_sha1, others[i]);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tfor (i = 0; i < entries; i++) {\n+\t\tstruct stat st;\n+\t\tunsigned int ce_mode, mode;\n+\t\tstruct cache_entry *ce = active_cache[i];\n+\n+\t\tif (path_match(ce->name, ce_namelen(ce)) < 1)\n+\t\t\tcontinue;\n+\n+\t\tif (show_changed && ce_stage(ce)) {\n+\t\t\tif (generate_patch)\n+\t\t\t\tdiff_unmerge(ce->name);\n+\t\t\telse\n+\t\t\t\tprintf(\"U %s%c\", ce->name, line_terminator);\n+\t\t\tdo {\n+\t\t\t\ti++;\n+\t\t\t} while (i < entries &&\n+\t\t\t\t !strcmp(ce->name, active_cache[i]->name));\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tce_mode = ntohl(ce->ce_mode);\n+\t\tif (stat(ce->name, &st) < 0) {\n+\t\t\tif (errno != ENOENT) {\n+\t\t\t\tperror(ce->name);\n+\t\t\t} else if (show_deleted) {\n+\t\t\t\tshow_file('-', ce_mode, ce->sha1, ce->name);\n+\t\t\t}\n+\t\t\tcontinue;\n+\t\t}\n+\n+\t\tif (!show_changed || !cache_match_stat(ce, &st))\n+\t\t\tcontinue;\n+\n+\t\tmode = S_IFREG | ce_permissions(st.st_mode);\n+\t\tif (generate_patch)\n+\t\t\tdiff_change(ce_mode, mode, ce->sha1,\n+\t\t\t\t    null_sha1, ce->name, NULL);\n+\t\telse\n+\t\t\tprintf(\"*%o->%o\\t%s\\t%s->%s\\t%s%c\",\n+\t\t\t       ce_mode, mode, \"blob\",\n+\t\t\t       sha1_to_hex(ce->sha1), null_sha1_hex,\n+\t\t\t       ce->name, line_terminator);\n+\t}\n+\n+\treturn 0;\n+}\n"},{"id":"1915","messageId":"7vr7gvevpv.fsf@assigned-by-dhcp.cox.net","threadId":"355","inReplyTo":"Pine.LNX.4.62.0504271701080.14033@localhost.localdomain","subject":"Re: [PATCH] add a diff-files command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-04-27T21:49:32Z","receivedAt":"2005-04-27T21:49:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"NP\" == Nicolas Pitre <nico@cam.org> writes:\n\nNP> It also has the ability to accept exclude file patterns with -x and even \nNP> a file containing a list of patterns to exclude with -X.  This is \nNP> especially useful to use the famous dontdiff file when looking for \nNP> uncommitted files in a compiled kernel tree.\n\nI think show-diff with path restriction (if restriction is\nsimple), or piping its output to grep or filterdiff (otherwise),\nwould be enough to do what you do here, so personally I doubt\nthis new command is even useful that much.\n\nThat said, I have a couple of comments.  Other than these I do\nnot see anything majorly wrong (although I haven't even compiled\nit yet ;-).\n\nNP> +static const char *diff_files_usage = \"diff-files [-a] [-c] [-d] [-o] [-p | -z]\"\nNP> +\t\t\t\t      \" [-x <pattern>] [-X <file>] [paths...]\";\nNP> +\n\nIf you are trying to do something similar to show-files by these\n-[acdo] flags, matching these flags in both commands would be\nless confusing to the users and script writers.  Either make\ndiff-files take fully spelled --others etc. that show-files\ntakes, or submit a patch for show-files to match these shorter\nones as well.  I personally prefer the latter.\n\nNP> +/*\nNP> + * Read a directory tree. We currently ignore anything but\nNP> + * directories and regular files. That's because git doesn't\nNP> + * handle them at all yet. Maybe that will change some day.\nNP> + *\nNP> + * Also, we currently ignore all names starting with a dot.\nNP> + * That likely will not change.\nNP> + */\n\nFor that logic, instead of doing de->d_name[0] == '.' and things\nyourself, I'd rather see you lift verify_path() function from\nupdate-cache.c into common library and call it.  Then if the\n\"likely will not change\" part needs to be updated, you do not\nhave to worry about it; updates to verify_path() would take care\nof it for you.\n\n\n"},{"id":"1958","messageId":"Pine.LNX.4.62.0504272031330.14033@localhost.localdomain","threadId":"355","inReplyTo":"7vr7gvevpv.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] add a diff-files command","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2005-04-28T01:02:48Z","receivedAt":"2005-04-28T01:02:48Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Wed, 27 Apr 2005, Junio C Hamano wrote:\n\n> >>>>> \"NP\" == Nicolas Pitre <nico@cam.org> writes:\n> \n> NP> It also has the ability to accept exclude file patterns with -x and even \n> NP> a file containing a list of patterns to exclude with -X.  This is \n> NP> especially useful to use the famous dontdiff file when looking for \n> NP> uncommitted files in a compiled kernel tree.\n> \n> I think show-diff with path restriction (if restriction is\n> simple), or piping its output to grep or filterdiff (otherwise),\n> would be enough to do what you do here, so personally I doubt\n> this new command is even useful that much.\n\nFirst, show-diff doesn't handle files in the work tree which are not \nlisted in the cache.\n\nHave you ever looked at the dontdiff file?  You can get a sample of it \nfrom http://www.moses.uklinux.net/patches/dontdiff to give you an idea.  \nUsing grep or filterdiff is really backward in that case since out of \nall the junk that might appear in the output about 98% will be filtered \naway in most useful cases, which is rather inefficient.\n\nPath restriction is inclusive, while the exclude list is, well, \nexclusive.  They serves separate purposes.  So trust me it _is_ pretty \ndamn useful, unless you always run \"make clean\" on your kernel tree \nbefore checking for potentially uncommitted files then recompile \neverything afterwards which is a hassle.\n\n> That said, I have a couple of comments.  Other than these I do\n> not see anything majorly wrong (although I haven't even compiled\n> it yet ;-).\n> \n> NP> +static const char *diff_files_usage = \"diff-files [-a] [-c] [-d] [-o] [-p | -z]\"\n> NP> +\t\t\t\t      \" [-x <pattern>] [-X <file>] [paths...]\";\n> NP> +\n> \n> If you are trying to do something similar to show-files by these\n> -[acdo] flags, matching these flags in both commands would be\n> less confusing to the users and script writers.  Either make\n> diff-files take fully spelled --others etc. that show-files\n> takes, or submit a patch for show-files to match these shorter\n> ones as well.  I personally prefer the latter.\n\nAgreed.\n\n> NP> +/*\n> NP> + * Read a directory tree. We currently ignore anything but\n> NP> + * directories and regular files. That's because git doesn't\n> NP> + * handle them at all yet. Maybe that will change some day.\n> NP> + *\n> NP> + * Also, we currently ignore all names starting with a dot.\n> NP> + * That likely will not change.\n> NP> + */\n> \n> For that logic, instead of doing de->d_name[0] == '.' and things\n> yourself, I'd rather see you lift verify_path() function from\n> update-cache.c into common library and call it.\n\nSure, but actually I'd prefer for that to be a separate patch since it's \na tangential issue that might affect show-files as well.\n\n\nNicolas\n"},{"id":"2048","messageId":"7vr7gu97xq.fsf@assigned-by-dhcp.cox.net","threadId":"355","inReplyTo":"Pine.LNX.4.62.0504272031330.14033@localhost.localdomain","subject":"Re: [PATCH] add a diff-files command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-04-28T16:34:25Z","receivedAt":"2005-04-28T16:34:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"NP\" == Nicolas Pitre <nico@cam.org> writes:\n\nHaving thought about it more, although I praise your enthusiasm\nto improve git, I suspect your diff-files is a solution to a\nproblem that does not exist.\n\nNP> It also has the ability to accept exclude file patterns with\nNP> -x and even a file containing a list of patterns to exclude\nNP> with -X.  This is especially useful to use the famous\nNP> dontdiff file when looking for uncommitted files in a\nNP> compiled kernel tree.\n\nIf you want to see if working tree has some junk other than\nthose listed in dontdiff, wouldn't this be sufficient?\n\n  $ show-files --others | grep -f dontdiff\n\nNP> First, show-diff doesn't handle files in the work tree which\nNP> are not listed in the cache.\n\nThat's the whole point of git (and show-diff).  If it is not\nlisted in the cache, it does not exist.\n\nNP> ...  So trust me it _is_ pretty damn useful, unless you\nNP> always run \"make clean\" on your kernel tree before checking\nNP> for potentially uncommitted files then recompile everything\nNP> afterwards which is a hassle.\n\nWhy do you need to \"make clean\"?  Is it because otherwise you\nwould get lots of output for things that are listed in dontdiff\nbut not listed in the cache, and the uncommitted but not listed\nin dontdiff file that you care about would get lost in the\nnoise?\n\nEarlier you complained show-diff does _not_ look at what are not\nlisted in the cache.  Now you want to exclude garbage that comes\nout of it because you have tons of stuff that are not listed in\nthe cache, which implies show-diff _does_ look at what are not\nlisted in the cache.  Either you are contradicting yourself or I\nam confused.\n\nThe truth is, as you said earlier, show-diff does not look at\nthem, so I do not understand what problem you are trying to\ndescribe here.\n\nAgain, \"checking for potentially uncommitted\" files is what\nyou use show-files --others for, not show-diff.\n\n"},{"id":"2050","messageId":"Pine.LNX.4.62.0504281238130.14033@localhost.localdomain","threadId":"355","inReplyTo":"7vr7gu97xq.fsf@assigned-by-dhcp.cox.net","subject":"Re: [PATCH] add a diff-files command","fromName":"Nicolas Pitre","fromEmail":"nico@cam.org","sentAt":"2005-04-28T16:56:43Z","receivedAt":"2005-04-28T16:56:43Z","isPatch":true,"sender":{"key":"nico@fluxnic.net","avatar":"https://avatars.githubusercontent.com/u/702790?v=4"},"body":"On Thu, 28 Apr 2005, Junio C Hamano wrote:\n\n> If you want to see if working tree has some junk other than\n> those listed in dontdiff, wouldn't this be sufficient?\n> \n>   $ show-files --others | grep -f dontdiff\n\nWell, it would work if the dontdiff file other people are maintaining \nwas made up of regexps.  But it is made of shell wildcard patterns meant \nto be used with the -X switch of the diff command.\n\n> Again, \"checking for potentially uncommitted\" files is what\n> you use show-files --others for, not show-diff.\n\nIndeed.  And yesterday I realized that the (currently unimplemented) \n--ignore switch to show-files, combined with the exclusion pattern list, \nwhould be more logical than teaching show-diff (which I still think is a \nmisnamer in the context of the other diff tools) about files unknown to \nthe cache.  The patch to show-files is also much smaller and logical.\n\nBTW, I don't do this out of pure entousiasm but rather trying to make my \nown workflow with the Linux kernel source tree more efficient in the \ncontext of git usage.  My pure coding entousiasm lies somewhere else.  \n\n\nNicolas\n"},{"id":"2056","messageId":"7vk6mm9607.fsf@assigned-by-dhcp.cox.net","threadId":"355","inReplyTo":"Pine.LNX.4.62.0504281238130.14033@localhost.localdomain","subject":"Re: [PATCH] add a diff-files command","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-04-28T17:16:08Z","receivedAt":"2005-04-28T17:16:08Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":">>>>> \"NP\" == Nicolas Pitre <nico@cam.org> writes:\n\nNP> ...  And yesterday I realized that the (currently unimplemented) \nNP> --ignore switch to show-files, combined with the exclusion pattern list, \nNP> whould be more logical than teaching show-diff (which I still think is a \nNP> misnamer in the context of the other diff tools) about files unknown to \nNP> the cache.  The patch to show-files is also much smaller and logical.\n\nI agree wholeheartedly with both counts.  (1) Linus and I\ndiscussed briefly about renaming show-diff to diff-files but it\nis on hold, waiting for a big wholesale rename.  (2) the logical\nplace for the -X and -x is \"show-files --ignore\".\n\n"}]}