{"thread":{"id":"13637","subject":"git diff-files weirdness (bug?)","startedAt":"2008-05-23T14:20:47Z","lastAt":"2008-05-24T07:26:33Z","messageCount":11,"participants":["Catalin Marinas","Linus Torvalds","Johannes Schindelin","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"77554","messageId":"b0943d9e0805230720h61cbabbbw180908e1b28a34cc@mail.gmail.com","threadId":"13637","inReplyTo":null,"subject":"git diff-files weirdness (bug?)","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2008-05-23T14:20:47Z","receivedAt":"2008-05-23T14:20:47Z","isPatch":false,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"Hi,\n\nI was investigating a bug in \"stg refresh\" failing with moved files\nand noticed that it was caused by Git (HEAD pulled yesterday):\n\n  git init\n  touch a\n  git add a\n  git commit -m \"test\"\n  git mv a b\n\nThese are OK:\n\n  git diff-files -- a\n  git diff-files -- b\n\nThese fail:\n\n  git diff-files -- a b\n  git diff-files -- a c\n\nThese are OK:\n\n  git diff-files -- a b c\n  git diff-files -- a b c d e\n  git diff-files -- c d e\n  ...\n\nIt looks like the two arguments command is a special case. Passing\n\"-q\" doesn't make any difference.\n\nThanks.\n\n-- \nCatalin\n"},{"id":"77561","messageId":"alpine.LFD.1.10.0805230906110.3081@woody.linux-foundation.org","threadId":"13637","inReplyTo":"b0943d9e0805230720h61cbabbbw180908e1b28a34cc@mail.gmail.com","subject":"Re: git diff-files weirdness (bug?)","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-05-23T16:14:19Z","receivedAt":"2008-05-23T16:14:19Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\nLooks like a real bug.\n\nOn Fri, 23 May 2008, Catalin Marinas wrote:\n>\n> I was investigating a bug in \"stg refresh\" failing with moved files\n> and noticed that it was caused by Git (HEAD pulled yesterday):\n> \n>   git init\n>   touch a\n>   git add a\n>   git commit -m \"test\"\n>   git mv a b\n> \n> These are OK:\n> \n>   git diff-files -- a\n>   git diff-files -- b\n> \n> These fail:\n> \n>   git diff-files -- a b\n>   git diff-files -- a c\n\nYes, that's buggy.\n\nWhat happens is that we get to run_diff_files_cmd(), but then we don't \nactually do \"run_diff_files()\", because we go into the NO_INDEX case:\n\n\tif (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) {\n\t\t...\n\ninstead.\n\nWhich in turn is because \"setup_diff_no_index()\" is broken.\n\nAnd I think \"setup_diff_no_index()\" is broken exactly because it sees that \n'--' and then totally ignores it and says \"if I see two paths, we'll say \nit's the non-index case\".\n\n\t\tLinus\n"},{"id":"77564","messageId":"alpine.LFD.1.10.0805230942480.3081@woody.linux-foundation.org","threadId":"13637","inReplyTo":"alpine.LFD.1.10.0805230906110.3081@woody.linux-foundation.org","subject":"Re: git diff-files weirdness (bug?)","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-05-23T16:50:55Z","receivedAt":"2008-05-23T16:50:55Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Fri, 23 May 2008, Linus Torvalds wrote:\n> \n> And I think \"setup_diff_no_index()\" is broken exactly because it sees that \n> '--' and then totally ignores it and says \"if I see two paths, we'll say \n> it's the non-index case\".\n\nActually, I think it's broken not so much because it ignores '--', but \nbecause it's just way too eager to do the \"non-git\" case.\n\nBasically, it is trying to act like a traditional \"diff\", but in doing so \nit disables the normal \"git diff\" semantics. Which is incorrect, when you \nactually _want_ the normal \"git diff\" behaviour.\n\nSo I would suggest that we make it *much* harder to trigger the \"make it \nact like a traditional 'diff'\" thing.\n\nI would suggest that we *not* invoce the traditional 'diff' behaviour \nwhen:\n\n - we're called as \"git-diff-files\". That's clearly a git thing. Don't try \n   to make it act like an external non-git diff. Only do the special case \n   for plain \"git diff\" itself.\n\n - even for plain \"git diff\", make it much harder to trigger non-git \n   behaviour. Don't do it if the files don't exist. Don't do it if there \n   is '--' there.\n\nIn fact, maybe we should remove that thing entirely, or *require* a flag \nto enable it (at least if we're in a git directory). It's a cute hack, but \nwhen the cute hack actually makes it impossible to do certain real git \noperations, it's a cute hack that is detrimental.\n\n\t\tLinus\n"},{"id":"77609","messageId":"alpine.DEB.1.00.0805232309350.30431@racer","threadId":"13637","inReplyTo":"7vbq2wsxnk.fsf@gitster.siamese.dyndns.org","subject":"[PATCH] diff -- file1 file2: do not default to --no-index inside a git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-05-23T22:49:22Z","receivedAt":"2008-05-23T22:49:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWhen calling \"git diff -- a b\", as opposed to \"git diff a b\" without \"--\",\ndo not default to --no-index inside a git repository.\n\nFor example,\n\n\tgit mv a b && git diff -- a b\n\nused to have an unexpected result.\n\nNoticed by Catalin Marinas, diagnosed by Linus.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tOn Fri, 23 May 2008, Junio C Hamano wrote:\n\n\t> Linus Torvalds <torvalds@linux-foundation.org> writes:\n\t> \n\t> > ... So I would suggest that we make it *much* harder to \n\t> > trigger the \"make it act like a traditional 'diff'\" thing.\n\t> >\n\t> > I would suggest that we *not* invoce the traditional 'diff' \n\t> > behaviour when:\n\t> >\n\t> >  - we're called as \"git-diff-files\". That's clearly a git \n\t> >    thing. Don't try to make it act like an external non-git diff. \n\t> >    Only do the special case for plain \"git diff\" itself.\n\n\tI am not so sure about that.\n\n\t> >  - even for plain \"git diff\", make it much harder to trigger \n\t> >    non-git behaviour. Don't do it if the files don't exist.\n\t> >    Don't do it if there is '--' there.\n\t> >\n\t> > In fact, maybe we should remove that thing entirely, or \n\t> > *require* a flag to enable it (at least if we're in a git\n\t> > directory).  It's a cute hack, but when the cute hack actually \n\t> > makes it impossible to do certain real git operations, it's a \n\t> > cute hack that is detrimental.\n\t> \n\t> Very well said.  I've always wanted to rip that hack out of the \n\t> normal \"git diff with two pathspec parameters\" codepath.\n\n\tYes, I see how that cute hack does the wrong thing here.\n\n\tHowever, it is pretty convenient to be able to say \"git diff a b\" \n\tand have it fall back to --no-index if either a or b is not in the \n\tindex.  Most of the time, I would actually expect it to be the \n\tright thing, too.\n\n\tHey, but if you disagree, just rip it out.  Actually, I did that \n\talready, and will reply with that alternative patch.\n\n diff-lib.c            |    4 ++--\n t/t4002-diff-basic.sh |   31 +++++++++++++++++++++++++++++++\n 2 files changed, 33 insertions(+), 2 deletions(-)\n\ndiff --git a/diff-lib.c b/diff-lib.c\nindex fe2ccec..b1daad6 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -257,8 +257,8 @@ int setup_diff_no_index(struct rev_info *revs,\n \t\tif (argv[i][0] != '-' || argv[i][1] == '\\0')\n \t\t\tbreak;\n \t\telse if (!strcmp(argv[i], \"--\")) {\n-\t\t\ti++;\n-\t\t\tbreak;\n+\t\t\trevs->max_count = -2;\n+\t\t\treturn -1;\n \t\t} else if (i < argc - 3 && !strcmp(argv[i], \"--no-index\")) {\n \t\t\ti = argc - 3;\n \t\t\tDIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);\ndiff --git a/t/t4002-diff-basic.sh b/t/t4002-diff-basic.sh\nindex a4cfde6..678c4a5 100755\n--- a/t/t4002-diff-basic.sh\n+++ b/t/t4002-diff-basic.sh\n@@ -244,4 +244,35 @@ test_expect_success \\\n     git diff-tree -r -R $tree_A $tree_B >.test-b &&\n     cmp -s .test-a .test-b'\n \n+cat > expect << EOF\n+diff --git a/AA b/AA\n+index ccba72a..6aa2b53 100644\n+--- a/AA\n++++ b/AA\n+@@ -1 +1 @@\n+-This is added AA in the branch A.\n++This is added AA in the branch B.\n+EOF\n+\n+test_expect_success '\"diff -- AA DM\" does not imply --no-index' '\n+\n+\tgit diff -- AA DM > output &&\n+\tcmp -s output expect\n+\n+'\n+\n+cat > expect << EOF\n+diff --git a/AA b/DM\n+index 6aa2b53..3c4d8de 100644\n+--- a/AA\n++++ b/DM\n+@@ -1 +1 @@\n+-This is added AA in the branch B.\n++This is modified DM in the branch B.\n+EOF\n+\n+test_expect_success '\"diff AA DM\" implies --no-index' '\n+\n+'\n+\n test_done\n-- \n1.5.5.1.553.ga1dd7.dirty\n"},{"id":"77610","messageId":"alpine.DEB.1.00.0805232349410.30431@racer","threadId":"13637","inReplyTo":"alpine.DEB.1.00.0805232309350.30431@racer","subject":"[ALTERNATIVE PATCH] diff file1 file2: do not default to --no-index inside a git repository","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-05-23T22:50:29Z","receivedAt":"2008-05-23T22:50:29Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"\nWhen calling \"diff -- a b\" where a exists in the index, but b does not,\ndo not default to --no-index inside a git repository.\n\nFor example,\n\n\tgit mv a b && git diff a b\n\nwould not have the expected result.\n\nNoticed by Catalin Marinas, diagnosed by Linus.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n\n\tOn Fri, 23 May 2008, Johannes Schindelin wrote:\n\n\t> \tHey, but if you disagree, just rip it out.  Actually, I \n\t> \tdid that already, and will reply with that alternative patch.\n\n\tHere it goes.\n\n\n diff-lib.c                                         |   43 --------------------\n t/t4013-diff-various.sh                            |    3 +-\n t/t4013/diff.diff_--name-status_dir2_dir           |    1 -\n .../diff.diff_--no-index_--name-status_dir2_dir    |    3 +\n t/t4018-diff-funcname.sh                           |    8 ++--\n t/t5400-send-pack.sh                               |    2 +-\n 6 files changed, 10 insertions(+), 50 deletions(-)\n create mode 100644 t/t4013/diff.diff_--no-index_--name-status_dir2_dir\n\ndiff --git a/diff-lib.c b/diff-lib.c\nindex fe2ccec..ee2c16a 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -144,36 +144,6 @@ static int queue_diff(struct diff_options *o,\n \t}\n }\n \n-/*\n- * Does the path name a blob in the working tree, or a directory\n- * in the working tree?\n- */\n-static int is_in_index(const char *path)\n-{\n-\tint len, pos;\n-\tstruct cache_entry *ce;\n-\n-\tlen = strlen(path);\n-\twhile (path[len-1] == '/')\n-\t\tlen--;\n-\tif (!len)\n-\t\treturn 1; /* \".\" */\n-\tpos = cache_name_pos(path, len);\n-\tif (0 <= pos)\n-\t\treturn 1;\n-\tpos = -1 - pos;\n-\twhile (pos < active_nr) {\n-\t\tce = active_cache[pos++];\n-\t\tif (ce_namelen(ce) <= len ||\n-\t\t    strncmp(ce->name, path, len) ||\n-\t\t    (ce->name[len] > '/'))\n-\t\t\tbreak; /* path cannot be a prefix */\n-\t\tif (ce->name[len] == '/')\n-\t\t\treturn 1;\n-\t}\n-\treturn 0;\n-}\n-\n static int handle_diff_files_args(struct rev_info *revs,\n \t\t\t\t  int argc, const char **argv,\n \t\t\t\t  unsigned int *options)\n@@ -201,19 +171,6 @@ static int handle_diff_files_args(struct rev_info *revs,\n \t\targv++; argc--;\n \t}\n \n-\tif (revs->max_count == -1 && revs->diffopt.nr_paths == 2) {\n-\t\t/*\n-\t\t * If two files are specified, and at least one is untracked,\n-\t\t * default to no-index.\n-\t\t */\n-\t\tread_cache();\n-\t\tif (!is_in_index(revs->diffopt.paths[0]) ||\n-\t\t\t\t\t!is_in_index(revs->diffopt.paths[1])) {\n-\t\t\trevs->max_count = -2;\n-\t\t\tDIFF_OPT_SET(&revs->diffopt, NO_INDEX);\n-\t\t}\n-\t}\n-\n \t/*\n \t * Make sure there are NO revision (i.e. pending object) parameter,\n \t * rev.max_count is reasonable (0 <= n <= 3),\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex 6b4d1c5..1ce05da 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -112,7 +112,7 @@ do\n \t\t} >\"$actual\" &&\n \t\tif test -f \"$expect\"\n \t\tthen\n-\t\t\tgit diff \"$expect\" \"$actual\" &&\n+\t\t\tgit diff --no-index \"$expect\" \"$actual\" &&\n \t\t\trm -f \"$actual\"\n \t\telse\n \t\t\t# this is to help developing new tests.\n@@ -257,6 +257,7 @@ diff --patch-with-raw initial..side\n diff --patch-with-stat -r initial..side\n diff --patch-with-raw -r initial..side\n diff --name-status dir2 dir\n+diff --no-index --name-status dir2 dir\n EOF\n \n test_done\ndiff --git a/t/t4013/diff.diff_--name-status_dir2_dir b/t/t4013/diff.diff_--name-status_dir2_dir\nindex ef7fdb7..d0d96aa 100644\n--- a/t/t4013/diff.diff_--name-status_dir2_dir\n+++ b/t/t4013/diff.diff_--name-status_dir2_dir\n@@ -1,3 +1,2 @@\n $ git diff --name-status dir2 dir\n-A\tdir/sub\n $\ndiff --git a/t/t4013/diff.diff_--no-index_--name-status_dir2_dir b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir\nnew file mode 100644\nindex 0000000..6a47584\n--- /dev/null\n+++ b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir\n@@ -0,0 +1,3 @@\n+$ git diff --no-index --name-status dir2 dir\n+A\tdir/sub\n+$\ndiff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh\nindex f9db81d..6d3ef6c 100755\n--- a/t/t4018-diff-funcname.sh\n+++ b/t/t4018-diff-funcname.sh\n@@ -33,13 +33,13 @@ EOF\n sed 's/beer\\\\/beer,\\\\/' < Beer.java > Beer-correct.java\n \n test_expect_success 'default behaviour' '\n-\tgit diff Beer.java Beer-correct.java |\n+\tgit diff --no-index Beer.java Beer-correct.java |\n \tgrep \"^@@.*@@ public class Beer\"\n '\n \n test_expect_success 'preset java pattern' '\n \techo \"*.java diff=java\" >.gitattributes &&\n-\tgit diff Beer.java Beer-correct.java |\n+\tgit diff --no-index Beer.java Beer-correct.java |\n \tgrep \"^@@.*@@ public static void main(\"\n '\n \n@@ -48,13 +48,13 @@ git config diff.java.funcname '!static\n [^ \t].*s.*'\n \n test_expect_success 'custom pattern' '\n-\tgit diff Beer.java Beer-correct.java |\n+\tgit diff --no-index Beer.java Beer-correct.java |\n \tgrep \"^@@.*@@ int special;$\"\n '\n \n test_expect_success 'last regexp must not be negated' '\n \tgit config diff.java.funcname \"!static\" &&\n-\t! git diff Beer.java Beer-correct.java\n+\t! git diff --no-index Beer.java Beer-correct.java\n '\n \n test_done\ndiff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh\nindex af8d5a3..846534e 100755\n--- a/t/t5400-send-pack.sh\n+++ b/t/t5400-send-pack.sh\n@@ -110,7 +110,7 @@ test_expect_success \\\n \tcd .. &&\n \tgit update-ref refs/heads/master master^ || return 1\n \tgit-send-pack --force ./victim/.git/ master && return 1\n-\t! git diff .git/refs/heads/master victim/.git/refs/heads/master\n+\t! git diff --no-index .git/refs/heads/master victim/.git/refs/heads/master\n '\n \n test_expect_success \\\n-- \n1.5.5.1.553.ga1dd7.dirty\n"},{"id":"77615","messageId":"7v8wy0r2pa.fsf@gitster.siamese.dyndns.org","threadId":"13637","inReplyTo":"alpine.DEB.1.00.0805232309350.30431@racer","subject":"Re: [PATCH] diff -- file1 file2: do not default to --no-index inside a git repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-24T00:00:17Z","receivedAt":"2008-05-24T00:00:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> \tOn Fri, 23 May 2008, Junio C Hamano wrote:\n>\n> \t> Linus Torvalds <torvalds@linux-foundation.org> writes:\n> \t> \n> \t> > ... So I would suggest that we make it *much* harder to \n> \t> > trigger the \"make it act like a traditional 'diff'\" thing.\n> \t> >\n> \t> > I would suggest that we *not* invoce the traditional 'diff' \n> \t> > behaviour when:\n> \t> >\n> \t> >  - we're called as \"git-diff-files\". That's clearly a git \n> \t> >    thing. Don't try to make it act like an external non-git diff. \n> \t> >    Only do the special case for plain \"git diff\" itself.\n>\n> \tI am not so sure about that.\n\nUnsure that \"git-diff-files\" is clearly a git thing?\n\n> \t> >  - even for plain \"git diff\", make it much harder to trigger \n> \t> >    non-git behaviour. Don't do it if the files don't exist.\n> \t> >    Don't do it if there is '--' there.\n> \t> >\n> \t> > In fact, maybe we should remove that thing entirely, or \n> \t> > *require* a flag to enable it (at least if we're in a git\n> \t> > directory).  It's a cute hack, but when the cute hack actually \n> \t> > makes it impossible to do certain real git operations, it's a \n> \t> > cute hack that is detrimental.\n> \t> \n> \t> Very well said.  I've always wanted to rip that hack out of the \n> \t> normal \"git diff with two pathspec parameters\" codepath.\n>\n> \tYes, I see how that cute hack does the wrong thing here.\n>\n> \tHowever, it is pretty convenient to be able to say \"git diff a b\" \n> \tand have it fall back to --no-index if either a or b is not in the \n> \tindex.  Most of the time, I would actually expect it to be the \n> \tright thing, too.\n\n\"Most-of-the-time\" may be a good thing in Porcelains, but is clearly a\nwrong thing for plumbing.\n\nI think ripping out --no-index from git-diff-files is probably the first\nstep.  \"git diff\" also needs to fixed as Linus outlined, but that is a\nseparate topic.\n\nHow about doing something like this as a start?  At least that would get\nwell behaved Porcelains like stg unstuck?\n\n---\n\n builtin-diff-files.c |   38 +++++++++++++++++++++++++++++++-------\n git.c                |    2 +-\n 2 files changed, 32 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin-diff-files.c b/builtin-diff-files.c\nindex e2306c1..6898e3e 100644\n--- a/builtin-diff-files.c\n+++ b/builtin-diff-files.c\n@@ -10,26 +10,50 @@\n #include \"builtin.h\"\n \n static const char diff_files_usage[] =\n-\"git-diff-files [-q] [-0/-1/2/3 |-c|--cc|--no-index] [<common diff options>] [<path>...]\"\n+\"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]\"\n COMMON_DIFF_OPTIONS_HELP;\n \n int cmd_diff_files(int argc, const char **argv, const char *prefix)\n {\n \tstruct rev_info rev;\n-\tint nongit;\n \tint result;\n+\tunsigned options;\n \n-\tprefix = setup_git_directory_gently(&nongit);\n \tinit_revisions(&rev, prefix);\n \tgit_config(git_diff_basic_config); /* no \"diff\" UI options */\n \trev.abbrev = 0;\n \n-\tif (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))\n-\t\targc = 0;\n-\telse\n-\t\targc = setup_revisions(argc, argv, &rev, NULL);\n+\targc = setup_revisions(argc, argv, &rev, NULL);\n+\twhile (1 < argc && argv[1][0] == '-') {\n+\t\tif (!strcmp(argv[1], \"--base\"))\n+\t\t\trev.max_count = 1;\n+\t\telse if (!strcmp(argv[1], \"--ours\"))\n+\t\t\trev.max_count = 2;\n+\t\telse if (!strcmp(argv[1], \"--theirs\"))\n+\t\t\trev.max_count = 3;\n+\t\telse if (!strcmp(argv[1], \"-q\"))\n+\t\t\toptions |= DIFF_SILENT_ON_REMOVED;\n+\t\telse\n+\t\t\tusage(diff_files_usage);\n+\t\targv++; argc--;\n+\t}\n \tif (!rev.diffopt.output_format)\n \t\trev.diffopt.output_format = DIFF_FORMAT_RAW;\n+\n+\t/*\n+\t * Make sure there are NO revision (i.e. pending object) parameter,\n+\t * rev.max_count is reasonable (0 <= n <= 3), and\n+\t * there is no other revision filtering parameters.\n+\t */\n+\tif (rev.pending.nr ||\n+\t    rev.min_age != -1 || rev.max_age != -1 ||\n+\t    3 < rev.max_count)\n+\t\tusage(diff_files_usage);\n+\n+\tif (rev.max_count == -1 &&\n+\t    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))\n+\t\trev.combine_merges = rev.dense_combined_merges = 1;\n+\n \tresult = run_diff_files_cmd(&rev, argc, argv);\n \treturn diff_result_code(&rev.diffopt, result);\n }\ndiff --git a/git.c b/git.c\nindex 89b431f..4b79380 100644\n--- a/git.c\n+++ b/git.c\n@@ -293,7 +293,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"count-objects\", cmd_count_objects, RUN_SETUP },\n \t\t{ \"describe\", cmd_describe, RUN_SETUP },\n \t\t{ \"diff\", cmd_diff },\n-\t\t{ \"diff-files\", cmd_diff_files },\n+\t\t{ \"diff-files\", cmd_diff_files, RUN_SETUP },\n \t\t{ \"diff-index\", cmd_diff_index, RUN_SETUP },\n \t\t{ \"diff-tree\", cmd_diff_tree, RUN_SETUP },\n \t\t{ \"fast-export\", cmd_fast_export, RUN_SETUP },\n"},{"id":"77638","messageId":"7vfxs8p9gc.fsf@gitster.siamese.dyndns.org","threadId":"13637","inReplyTo":"7v8wy0r2pa.fsf@gitster.siamese.dyndns.org","subject":"Re: [PATCH] diff -- file1 file2: do not default to --no-index inside a git repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-24T05:17:23Z","receivedAt":"2008-05-24T05:17:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> I think ripping out --no-index from git-diff-files is probably the first\n> step.  \"git diff\" also needs to fixed as Linus outlined, but that is a\n> separate topic.\n>\n> How about doing something like this as a start?  At least that would get\n> well behaved Porcelains like stg unstuck?\n> ...\n\nPlease do not use this one, not just yet.\n\nThe series to fix this unfortunately is turning out to be larger than I\nhoped for, but the result is looking very promising ;-).\n"},{"id":"77640","messageId":"7vskw8madq.fsf@gitster.siamese.dyndns.org","threadId":"13637","inReplyTo":"alpine.DEB.1.00.0805232349410.30431@racer","subject":"Re: [ALTERNATIVE PATCH] diff file1 file2: do not default to --no-index inside a git repository","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2008-05-24T07:25:37Z","receivedAt":"2008-05-24T07:25:37Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> When calling \"diff -- a b\" where a exists in the index, but b does not,\n> do not default to --no-index inside a git repository.\n>\n> For example,\n>\n> \tgit mv a b && git diff a b\n>\n> would not have the expected result.\n\nI think the rule should be much stricter and \"git diff\" should _not_ use\nno-index if run in a repository without --no-index.\n\nI also suspect that your updates to the testsuite are grossly inadequate.\nEarlier \"diff expect actual\" was replaced with \"git diff expect actual\"\nagainst my good taste (TM) in many tests, and they need to either be\nreplaced with \"git diff --no-index\" or (even better) \"test_cmp\".\n\nNo need to resend, as I did a rather unpleasant conversion of these places\nback to \"test_cmp\" already, but I'd appreciate an extra set of eyeballs to\nproofread that rather large fix to the testsuite.\n"},{"id":"77642","messageId":"7vmymgmadi.fsf@gitster.siamese.dyndns.org","threadId":"13637","inReplyTo":"alpine.DEB.1.00.0805232349410.30431@racer","subject":"[PATCH 1/3] tests: do not use implicit \"git diff --no-index\"","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-05-24T07:25:45Z","receivedAt":"2008-05-24T07:25:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"As a general principle, we should not use \"git diff\" to validate the\nresults of what git command that is being tested has done.  We would not\nknow if we are testing the command in question, or locating a bug in the\ncute hack of \"git diff --no-index\".\n\nRather use test_cmp for that purpose.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n t/diff-lib.sh                      |    6 +-\n t/t0030-stripspace.sh              |  156 +++++++++++++-------------\n t/t0040-parse-options.sh           |   18 ++--\n t/t1000-read-tree-m-3way.sh        |    2 +-\n t/t1001-read-tree-m-2way.sh        |   26 +++---\n t/t1002-read-tree-m-u-2way.sh      |    2 +-\n t/t1300-repo-config.sh             |    8 +-\n t/t1303-wacky-config.sh            |    2 +-\n t/t1502-rev-parse-parseopt.sh      |    2 +-\n t/t3001-ls-files-others-exclude.sh |    4 +-\n t/t3002-ls-files-dashpath.sh       |   10 +-\n t/t3030-merge-recursive.sh         |   42 ++++----\n t/t3040-subprojects-basic.sh       |    4 +-\n t/t3100-ls-tree-restrict.sh        |    2 +-\n t/t3101-ls-tree-dirname.sh         |    2 +-\n t/t3300-funny-names.sh             |   30 +++---\n t/t3900-i18n-commit.sh             |    2 +-\n t/t4006-diff-mode.sh               |    2 +-\n t/t4013-diff-various.sh            |    2 +-\n t/t4014-format-patch.sh            |    2 +-\n t/t4015-diff-whitespace.sh         |   12 +-\n t/t4016-diff-quote.sh              |    4 +-\n t/t4018-diff-funcname.sh           |    8 +-\n t/t4100-apply-stat.sh              |   14 ++--\n t/t4104-apply-boundary.sh          |    4 +-\n t/t4115-apply-symlink.sh           |    4 +-\n t/t4116-apply-reverse.sh           |    2 +-\n t/t4117-apply-reject.sh            |   12 +-\n t/t4118-apply-empty-context.sh     |    6 +-\n t/t4200-rerere.sh                  |    6 +-\n t/t5305-include-tag.sh             |    4 +-\n t/t5400-send-pack.sh               |    2 +-\n t/t5401-update-hooks.sh            |   10 +-\n t/t5503-tagfollow.sh               |    8 +-\n t/t5505-remote.sh                  |   10 +-\n t/t5515-fetch-merge-logic.sh       |    4 +-\n t/t6006-rev-list-format.sh         |    2 +-\n t/t6023-merge-file.sh              |    8 +-\n t/t6024-recursive-merge.sh         |    4 +-\n t/t6029-merge-subtree.sh           |    4 +-\n t/t6120-describe.sh                |    2 +-\n t/t6200-fmt-merge-msg.sh           |   16 ++--\n t/t6300-for-each-ref.sh            |   24 ++--\n t/t7003-filter-branch.sh           |    4 +-\n t/t7004-tag.sh                     |  210 ++++++++++++++++++------------------\n t/t7102-reset.sh                   |   12 +-\n t/t7502-status.sh                  |    6 +-\n t/t9100-git-svn-basic.sh           |    6 +-\n t/t9300-fast-import.sh             |   34 +++---\n t/t9600-cvsimport.sh               |    8 +-\n 50 files changed, 387 insertions(+), 387 deletions(-)\n\ndiff --git a/t/diff-lib.sh b/t/diff-lib.sh\nindex 28b941c..4bddeb5 100644\n--- a/t/diff-lib.sh\n+++ b/t/diff-lib.sh\n@@ -11,7 +11,7 @@ compare_diff_raw () {\n \n     sed -e \"$sanitize_diff_raw\" <\"$1\" >.tmp-1\n     sed -e \"$sanitize_diff_raw\" <\"$2\" >.tmp-2\n-    git diff .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2\n+    test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2\n }\n \n sanitize_diff_raw_z='/^:/s/ '\"$_x40\"' '\"$_x40\"' \\([A-Z]\\)[0-9]*$/ X X \\1#/'\n@@ -23,7 +23,7 @@ compare_diff_raw_z () {\n \n     perl -pe 'y/\\000/\\012/' <\"$1\" | sed -e \"$sanitize_diff_raw_z\" >.tmp-1\n     perl -pe 'y/\\000/\\012/' <\"$2\" | sed -e \"$sanitize_diff_raw_z\" >.tmp-2\n-    git diff .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2\n+    test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2\n }\n \n compare_diff_patch () {\n@@ -37,5 +37,5 @@ compare_diff_patch () {\n \t/^[dis]*imilarity index [0-9]*%$/d\n \t/^index [0-9a-f]*\\.\\.[0-9a-f]/d\n     ' <\"$2\" >.tmp-2\n-    git diff .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2\n+    test_cmp .tmp-1 .tmp-2 && rm -f .tmp-1 .tmp-2\n }\ndiff --git a/t/t0030-stripspace.sh b/t/t0030-stripspace.sh\nindex 3ecdd66..ccb0a3c 100755\n--- a/t/t0030-stripspace.sh\n+++ b/t/t0030-stripspace.sh\n@@ -16,96 +16,96 @@ test_expect_success \\\n     'long lines without spaces should be unchanged' '\n     echo \"$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$ttt$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$ttt$ttt$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n     'lines with spaces at the beginning should be unchanged' '\n     echo \"$sss$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$sss$sss$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$sss$sss$sss$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n     'lines with intermediate spaces should be unchanged' '\n     echo \"$ttt$sss$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$sss$sss$ttt\" >expect &&\n     git stripspace <expect >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n     'consecutive blank lines should be unified' '\n     printf \"$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\n\\n\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt$ttt\\n\\n\\n\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt$ttt$ttt\\n\\n\\n\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\n\\n\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\n\\n\\n\\n$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt$ttt$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\n\\n\\n\\n$ttt$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\t\\n \\n\\n  \\t\\t\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt$ttt\\n\\t\\n \\n\\n  \\t\\t\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt$ttt$ttt\\n\\t\\n \\n\\n  \\t\\t\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\t\\n \\n\\n  \\t\\t\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\t\\n \\n\\n  \\t\\t\\n$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$ttt$ttt$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\t\\n \\n\\n  \\t\\t\\n$ttt$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n@@ -113,114 +113,114 @@ test_expect_success \\\n     > expect &&\n \n     printf \"\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss\\n$sss\\n$sss\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss\\n$sss\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n$sss\\n$sss$sss\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss$sss$sss\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n$sss$sss$sss$sss\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n\\n$sss$sss$sss$sss\\n\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n     'consecutive blank lines at the beginning should be removed' '\n     printf \"$ttt\\n\" > expect &&\n     printf \"\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\" > expect &&\n     printf \"\\n\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\" > expect &&\n     printf \"\\n\\n\\n$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt\\n\" > expect &&\n     printf \"\\n\\n\\n$ttt$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt$ttt\\n\" > expect &&\n     printf \"\\n\\n\\n$ttt$ttt$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\" > expect &&\n \n     printf \"$sss\\n$sss\\n$sss\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n$sss\\n$sss$sss\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss\\n$sss\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss$sss\\n\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n$sss$sss$sss\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"\\n\\n$sss$sss$sss\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n     'consecutive blank lines at the end should be removed' '\n     printf \"$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\" > expect &&\n     printf \"$ttt\\n\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\" > expect &&\n     printf \"$ttt$ttt\\n\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt\\n\" > expect &&\n     printf \"$ttt$ttt$ttt\\n\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt$ttt\\n\" > expect &&\n     printf \"$ttt$ttt$ttt$ttt\\n\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\" > expect &&\n \n     printf \"$ttt\\n$sss\\n$sss\\n$sss\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$sss\\n$sss$sss\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n$sss$sss\\n$sss\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n$sss$sss$sss\\n\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n$sss$sss$sss\\n\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\\n\\n$sss$sss$sss\\n\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n@@ -257,27 +257,27 @@ test_expect_success \\\n     'text plus spaces without newline should show the correct lines' '\n     printf \"$ttt\\n\" >expect &&\n     printf \"$ttt$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\" >expect &&\n     printf \"$ttt$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n\" >expect &&\n     printf \"$ttt$sss$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\" >expect &&\n     printf \"$ttt$ttt$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\" >expect &&\n     printf \"$ttt$ttt$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt$ttt\\n\" >expect &&\n     printf \"$ttt$ttt$ttt$sss\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n@@ -294,27 +294,27 @@ test_expect_success \\\n     'text plus spaces at end should be cleaned and newline must remain' '\n     echo \"$ttt\" >expect &&\n     echo \"$ttt$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt\" >expect &&\n     echo \"$ttt$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt\" >expect &&\n     echo \"$ttt$sss$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$ttt\" >expect &&\n     echo \"$ttt$ttt$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$ttt\" >expect &&\n     echo \"$ttt$ttt$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$ttt$ttt$ttt\" >expect &&\n     echo \"$ttt$ttt$ttt$sss\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n # spaces only:\n@@ -324,19 +324,19 @@ test_expect_success \\\n     printf \"\" >expect &&\n \n     echo | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$sss$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     echo \"$sss$sss$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n@@ -353,43 +353,43 @@ test_expect_success \\\n     printf \"\" >expect &&\n \n     printf \"\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$sss$sss$sss$sss\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success \\\n     'consecutive text lines should be unchanged' '\n     printf \"$ttt$ttt\\n$ttt\\n\" >expect &&\n     printf \"$ttt$ttt\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n$ttt$ttt\\n$ttt\\n\" >expect &&\n     printf \"$ttt\\n$ttt$ttt\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n$ttt\\n$ttt\\n$ttt$ttt\\n\" >expect &&\n     printf \"$ttt\\n$ttt\\n$ttt\\n$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n$ttt\\n\\n$ttt$ttt\\n$ttt\\n\" >expect &&\n     printf \"$ttt\\n$ttt\\n\\n$ttt$ttt\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt$ttt\\n\\n$ttt\\n$ttt$ttt\\n\" >expect &&\n     printf \"$ttt$ttt\\n\\n$ttt\\n$ttt$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual &&\n+    test_cmp expect actual &&\n \n     printf \"$ttt\\n$ttt$ttt\\n\\n$ttt\\n\" >expect &&\n     printf \"$ttt\\n$ttt$ttt\\n\\n$ttt\\n\" | git stripspace >actual &&\n-    git diff expect actual\n+    test_cmp expect actual\n '\n \n test_expect_success 'strip comments, too' '\ndiff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh\nindex c23f0ac..9965cfa 100755\n--- a/t/t0040-parse-options.sh\n+++ b/t/t0040-parse-options.sh\n@@ -29,7 +29,7 @@ EOF\n test_expect_success 'test help' '\n \t! test-parse-options -h > output 2> output.err &&\n \ttest ! -s output &&\n-\tgit diff expect.err output.err\n+\ttest_cmp expect.err output.err\n '\n \n cat > expect << EOF\n@@ -40,7 +40,7 @@ EOF\n \n test_expect_success 'short options' '\n \ttest-parse-options -s123 -b -i 1729 -b > output 2> output.err &&\n-\tgit diff expect output &&\n+\ttest_cmp expect output &&\n \ttest ! -s output.err\n '\n cat > expect << EOF\n@@ -53,7 +53,7 @@ test_expect_success 'long options' '\n \ttest-parse-options --boolean --integer 1729 --boolean --string2=321 \\\n \t\t> output 2> output.err &&\n \ttest ! -s output.err &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n '\n \n cat > expect << EOF\n@@ -69,7 +69,7 @@ test_expect_success 'intermingled arguments' '\n \ttest-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \\\n \t\t> output 2> output.err &&\n \ttest ! -s output.err &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n '\n \n cat > expect << EOF\n@@ -81,13 +81,13 @@ EOF\n test_expect_success 'unambiguously abbreviated option' '\n \ttest-parse-options --int 2 --boolean --no-bo > output 2> output.err &&\n \ttest ! -s output.err &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n '\n \n test_expect_success 'unambiguously abbreviated option with \"=\"' '\n \ttest-parse-options --int=2 > output 2> output.err &&\n \ttest ! -s output.err &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n '\n \n test_expect_success 'ambiguously abbreviated option' '\n@@ -104,7 +104,7 @@ EOF\n test_expect_success 'non ambiguous option (after two options it abbreviates)' '\n \ttest-parse-options --st 123 > output 2> output.err &&\n \ttest ! -s output.err &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n '\n \n cat > expect.err << EOF\n@@ -114,7 +114,7 @@ EOF\n test_expect_success 'detect possible typos' '\n \t! test-parse-options -boolean > output 2> output.err &&\n \ttest ! -s output &&\n-\tgit diff expect.err output.err\n+\ttest_cmp expect.err output.err\n '\n \n cat > expect <<EOF\n@@ -127,7 +127,7 @@ EOF\n test_expect_success 'keep some options as arguments' '\n \ttest-parse-options --quux > output 2> output.err &&\n         test ! -s output.err &&\n-        git diff expect output\n+        test_cmp expect output\n '\n \n test_done\ndiff --git a/t/t1000-read-tree-m-3way.sh b/t/t1000-read-tree-m-3way.sh\nindex 17f519f..807fb83 100755\n--- a/t/t1000-read-tree-m-3way.sh\n+++ b/t/t1000-read-tree-m-3way.sh\n@@ -131,7 +131,7 @@ _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n \n check_result () {\n     git ls-files --stage | sed -e 's/ '\"$_x40\"' / X /' >current &&\n-    git diff expected current\n+    test_cmp expected current\n }\n \n # This is done on an empty work directory, which is the normal\ndiff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh\nindex b01b003..4b44e13 100755\n--- a/t/t1001-read-tree-m-2way.sh\n+++ b/t/t1001-read-tree-m-2way.sh\n@@ -33,7 +33,7 @@ compare_change () {\n \t    -e '/^--- /d; /^+++ /d; /^@@ /d;' \\\n \t    -e 's/^\\([-+][0-7][0-7][0-7][0-7][0-7][0-7]\\) '\"$_x40\"' /\\1 X /p' \\\n \t    \"$1\"\n-\tgit diff expected current\n+\ttest_cmp expected current\n }\n \n check_cache_at () {\n@@ -86,7 +86,7 @@ test_expect_success \\\n     'rm -f .git/index &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >1-3.out &&\n-     git diff M.out 1-3.out &&\n+     test_cmp M.out 1-3.out &&\n      check_cache_at bozbar dirty &&\n      check_cache_at frotz dirty &&\n      check_cache_at nitfol dirty'\n@@ -101,7 +101,7 @@ test_expect_success \\\n      git update-index --add yomin &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >4.out || return 1\n-     git diff M.out 4.out >4diff.out\n+     git diff --no-index M.out 4.out >4diff.out\n      compare_change 4diff.out expected &&\n      check_cache_at yomin clean'\n \n@@ -115,7 +115,7 @@ test_expect_success \\\n      echo yomin yomin >yomin &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >5.out || return 1\n-     git diff M.out 5.out >5diff.out\n+     git diff --no-index M.out 5.out >5diff.out\n      compare_change 5diff.out expected &&\n      check_cache_at yomin dirty'\n \n@@ -127,7 +127,7 @@ test_expect_success \\\n      git update-index --add frotz &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >6.out &&\n-     git diff M.out 6.out &&\n+     test_cmp M.out 6.out &&\n      check_cache_at frotz clean'\n \n test_expect_success \\\n@@ -140,7 +140,7 @@ test_expect_success \\\n      echo frotz frotz >frotz &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >7.out &&\n-     git diff M.out 7.out &&\n+     test_cmp M.out 7.out &&\n      check_cache_at frotz dirty'\n \n test_expect_success \\\n@@ -171,7 +171,7 @@ test_expect_success \\\n      git update-index --add rezrov &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >10.out &&\n-     git diff M.out 10.out'\n+     test_cmp M.out 10.out'\n \n test_expect_success \\\n     '11 - dirty path removed.' \\\n@@ -216,7 +216,7 @@ test_expect_success \\\n      git update-index --add nitfol &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >14.out || return 1\n-     git diff M.out 14.out >14diff.out\n+     git diff --no-index M.out 14.out >14diff.out\n      compare_change 14diff.out expected &&\n      check_cache_at nitfol clean'\n \n@@ -230,7 +230,7 @@ test_expect_success \\\n      echo nitfol nitfol nitfol >nitfol &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >15.out || return 1\n-     git diff M.out 15.out >15diff.out\n+     git diff --no-index M.out 15.out >15diff.out\n      compare_change 15diff.out expected &&\n      check_cache_at nitfol dirty'\n \n@@ -262,7 +262,7 @@ test_expect_success \\\n      git update-index --add bozbar &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >18.out &&\n-     git diff M.out 18.out &&\n+     test_cmp M.out 18.out &&\n      check_cache_at bozbar clean'\n \n test_expect_success \\\n@@ -275,7 +275,7 @@ test_expect_success \\\n      echo gnusto gnusto >bozbar &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >19.out &&\n-     git diff M.out 19.out &&\n+     test_cmp M.out 19.out &&\n      check_cache_at bozbar dirty'\n \n test_expect_success \\\n@@ -287,7 +287,7 @@ test_expect_success \\\n      git update-index --add bozbar &&\n      read_tree_twoway $treeH $treeM &&\n      git ls-files --stage >20.out &&\n-     git diff M.out 20.out &&\n+     test_cmp M.out 20.out &&\n      check_cache_at bozbar dirty'\n \n test_expect_success \\\n@@ -337,7 +337,7 @@ test_expect_success \\\n      git update-index --add DF &&\n      read_tree_twoway $treeDF $treeDFDF &&\n      git ls-files --stage >DFDFcheck.out &&\n-     git diff DFDF.out DFDFcheck.out &&\n+     test_cmp DFDF.out DFDFcheck.out &&\n      check_cache_at DF/DF dirty &&\n      :'\n \ndiff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh\nindex 42e5cf8..e04990e 100755\n--- a/t/t1002-read-tree-m-u-2way.sh\n+++ b/t/t1002-read-tree-m-u-2way.sh\n@@ -16,7 +16,7 @@ compare_change () {\n \tsed >current \\\n \t    -e '/^--- /d; /^+++ /d; /^@@ /d;' \\\n \t    -e 's/^\\(.[0-7][0-7][0-7][0-7][0-7][0-7]\\) '\"$_x40\"' /\\1 X /' \"$1\"\n-\tgit diff expected current\n+\ttest_cmp expected current\n }\n \n check_cache_at () {\ndiff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh\nindex a675cbb..afe7e66 100755\n--- a/t/t1300-repo-config.sh\n+++ b/t/t1300-repo-config.sh\n@@ -427,13 +427,13 @@ cat > expect << EOF\n weird\n EOF\n \n-test_expect_success \"rename succeeded\" \"git diff expect .git/config\"\n+test_expect_success \"rename succeeded\" \"test_cmp expect .git/config\"\n \n test_expect_success \"rename non-existing section\" '\n \t! git config --rename-section branch.\"world domination\" branch.drei\n '\n \n-test_expect_success \"rename succeeded\" \"git diff expect .git/config\"\n+test_expect_success \"rename succeeded\" \"test_cmp expect .git/config\"\n \n test_expect_success \"rename another section\" \\\n \t'git config --rename-section branch.\"1 234 blabl/a\" branch.drei'\n@@ -449,7 +449,7 @@ cat > expect << EOF\n weird\n EOF\n \n-test_expect_success \"rename succeeded\" \"git diff expect .git/config\"\n+test_expect_success \"rename succeeded\" \"test_cmp expect .git/config\"\n \n cat >> .git/config << EOF\n   [branch \"zwei\"] a = 1 [branch \"vier\"]\n@@ -465,7 +465,7 @@ weird\n EOF\n \n test_expect_success \"section was removed properly\" \\\n-\t\"git diff -u expect .git/config\"\n+\t\"test_cmp expect .git/config\"\n \n rm .git/config\n \ndiff --git a/t/t1303-wacky-config.sh b/t/t1303-wacky-config.sh\nindex f366b53..f98f4c5 100755\n--- a/t/t1303-wacky-config.sh\n+++ b/t/t1303-wacky-config.sh\n@@ -11,7 +11,7 @@ setup() {\n check() {\n \techo \"$2\" >expected\n \tgit config --get \"$1\" >actual\n-\tgit diff actual expected\n+\ttest_cmp actual expected\n }\n \n test_expect_success 'modify same key' '\ndiff --git a/t/t1502-rev-parse-parseopt.sh b/t/t1502-rev-parse-parseopt.sh\nindex 762af5f..d24a47d 100755\n--- a/t/t1502-rev-parse-parseopt.sh\n+++ b/t/t1502-rev-parse-parseopt.sh\n@@ -37,7 +37,7 @@ C?        option C with an optional argument\n Extras\n extra1    line above used to cause a segfault but no longer does\n EOF\n-\tgit diff expect.err output.err\n+\ttest_cmp expect.err output.err\n '\n \n test_done\ndiff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh\nindex 55f057c..1caeaca 100755\n--- a/t/t3001-ls-files-others-exclude.sh\n+++ b/t/t3001-ls-files-others-exclude.sh\n@@ -65,7 +65,7 @@ test_expect_success \\\n        --exclude-per-directory=.gitignore \\\n        --exclude-from=.git/ignore \\\n        >output &&\n-     git diff expect output'\n+     test_cmp expect output'\n \n # Test \\r\\n (MSDOS-like systems)\n printf '*.1\\r\\n/*.3\\r\\n!*.6\\r\\n' >.gitignore\n@@ -77,7 +77,7 @@ test_expect_success \\\n        --exclude-per-directory=.gitignore \\\n        --exclude-from=.git/ignore \\\n        >output &&\n-     git diff expect output'\n+     test_cmp expect output'\n \n cat > excludes-file << EOF\n *.[1-8]\ndiff --git a/t/t3002-ls-files-dashpath.sh b/t/t3002-ls-files-dashpath.sh\nindex 8687a01..8704b04 100755\n--- a/t/t3002-ls-files-dashpath.sh\n+++ b/t/t3002-ls-files-dashpath.sh\n@@ -23,7 +23,7 @@ test_expect_success \\\n test_expect_success \\\n     'git ls-files without path restriction.' \\\n     'git ls-files --others >output &&\n-     git diff output - <<EOF\n+     test_cmp output - <<EOF\n --\n -foo\n output\n@@ -34,7 +34,7 @@ EOF\n test_expect_success \\\n     'git ls-files with path restriction.' \\\n     'git ls-files --others path0 >output &&\n-\tgit diff output - <<EOF\n+\ttest_cmp output - <<EOF\n path0\n EOF\n '\n@@ -42,7 +42,7 @@ EOF\n test_expect_success \\\n     'git ls-files with path restriction with --.' \\\n     'git ls-files --others -- path0 >output &&\n-\tgit diff output - <<EOF\n+\ttest_cmp output - <<EOF\n path0\n EOF\n '\n@@ -50,7 +50,7 @@ EOF\n test_expect_success \\\n     'git ls-files with path restriction with -- --.' \\\n     'git ls-files --others -- -- >output &&\n-\tgit diff output - <<EOF\n+\ttest_cmp output - <<EOF\n --\n EOF\n '\n@@ -58,7 +58,7 @@ EOF\n test_expect_success \\\n     'git ls-files with no path restriction.' \\\n     'git ls-files --others -- >output &&\n-\tgit diff output - <<EOF\n+\ttest_cmp output - <<EOF\n --\n -foo\n output\ndiff --git a/t/t3030-merge-recursive.sh b/t/t3030-merge-recursive.sh\nindex 607f57f..aff3603 100755\n--- a/t/t3030-merge-recursive.sh\n+++ b/t/t3030-merge-recursive.sh\n@@ -43,7 +43,7 @@ test_expect_success 'setup 1' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'setup 2' '\n@@ -61,7 +61,7 @@ test_expect_success 'setup 2' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual &&\n+\ttest_cmp expected actual &&\n \n \techo goodbye >>a &&\n \to2=$(git hash-object a) &&\n@@ -82,7 +82,7 @@ test_expect_success 'setup 2' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'setup 3' '\n@@ -100,7 +100,7 @@ test_expect_success 'setup 3' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual &&\n+\ttest_cmp expected actual &&\n \n \trm -f b && mkdir b && echo df-1 >b/c && git add b/c &&\n \to3=$(git hash-object b/c) &&\n@@ -119,7 +119,7 @@ test_expect_success 'setup 3' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'setup 4' '\n@@ -137,7 +137,7 @@ test_expect_success 'setup 4' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual &&\n+\ttest_cmp expected actual &&\n \n \trm -f a && mkdir a && echo df-2 >a/c && git add a/c &&\n \to4=$(git hash-object a/c) &&\n@@ -156,7 +156,7 @@ test_expect_success 'setup 4' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'setup 5' '\n@@ -174,7 +174,7 @@ test_expect_success 'setup 5' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual &&\n+\ttest_cmp expected actual &&\n \n \trm -f b &&\n \techo remove-conflict >a &&\n@@ -195,7 +195,7 @@ test_expect_success 'setup 5' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -214,7 +214,7 @@ test_expect_success 'setup 6' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o0 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual &&\n+\ttest_cmp expected actual &&\n \n \trm -fr d && echo df-3 >d && git add d &&\n \to6=$(git hash-object d) &&\n@@ -233,7 +233,7 @@ test_expect_success 'setup 6' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o6 0\td\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'merge-recursive simple' '\n@@ -265,7 +265,7 @@ test_expect_success 'merge-recursive result' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -297,7 +297,7 @@ test_expect_success 'merge-recursive remove conflict' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -318,7 +318,7 @@ test_expect_success 'merge-recursive result' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -352,7 +352,7 @@ test_expect_success 'merge-recursive d/f conflict result' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -386,7 +386,7 @@ test_expect_success 'merge-recursive d/f conflict result the other way' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -420,7 +420,7 @@ test_expect_success 'merge-recursive d/f conflict result' '\n \t\techo \"100644 $o0 1\td/e\"\n \t\techo \"100644 $o1 2\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -454,7 +454,7 @@ test_expect_success 'merge-recursive d/f conflict result' '\n \t\techo \"100644 $o0 1\td/e\"\n \t\techo \"100644 $o1 3\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \n@@ -480,7 +480,7 @@ test_expect_success 'reset and bind merge' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual &&\n+\ttest_cmp expected actual &&\n \n \tgit read-tree --prefix=a1/ master &&\n \tgit ls-files -s >actual &&\n@@ -498,7 +498,7 @@ test_expect_success 'reset and bind merge' '\n \t\techo \"100644 $o0 0\tc\"\n \t\techo \"100644 $o1 0\td/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n \tgit read-tree --prefix=z/ master &&\n \tgit ls-files -s >actual &&\n@@ -520,7 +520,7 @@ test_expect_success 'reset and bind merge' '\n \t\techo \"100644 $o0 0\tz/c\"\n \t\techo \"100644 $o1 0\tz/d/e\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n \n '\n \ndiff --git a/t/t3040-subprojects-basic.sh b/t/t3040-subprojects-basic.sh\nindex 79b9f23..f6973e9 100755\n--- a/t/t3040-subprojects-basic.sh\n+++ b/t/t3040-subprojects-basic.sh\n@@ -24,7 +24,7 @@ test_expect_success 'create subprojects' \\\n     git add sub2 &&\n     git commit -q -m \"subprojects added\" &&\n     git diff-tree --abbrev=5 HEAD^ HEAD |cut -d\" \" -f-3,5- >current &&\n-    git diff expected current'\n+    test_cmp expected current'\n \n git branch save HEAD\n \n@@ -62,7 +62,7 @@ test_expect_success 'check if clone works' \\\n     'git ls-files -s >expected &&\n     git clone -l -s . cloned &&\n     ( cd cloned && git ls-files -s ) >current &&\n-    git diff expected current'\n+    test_cmp expected current'\n \n test_expect_success 'removing and adding subproject' \\\n     'git update-index --force-remove -- sub2 &&\ndiff --git a/t/t3100-ls-tree-restrict.sh b/t/t3100-ls-tree-restrict.sh\nindex 46427e3..6e6a254 100755\n--- a/t/t3100-ls-tree-restrict.sh\n+++ b/t/t3100-ls-tree-restrict.sh\n@@ -35,7 +35,7 @@ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n test_output () {\n     sed -e \"s/ $_x40\t/ X\t/\" <current >check\n-    git diff expected check\n+    test_cmp expected check\n }\n \n test_expect_success \\\ndiff --git a/t/t3101-ls-tree-dirname.sh b/t/t3101-ls-tree-dirname.sh\nindex 70f9ce9..4dd7d12 100755\n--- a/t/t3101-ls-tree-dirname.sh\n+++ b/t/t3101-ls-tree-dirname.sh\n@@ -43,7 +43,7 @@ _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n test_output () {\n     sed -e \"s/ $_x40\t/ X\t/\" <current >check\n-    git diff expected check\n+    test_cmp expected check\n }\n \n test_expect_success \\\ndiff --git a/t/t3300-funny-names.sh b/t/t3300-funny-names.sh\nindex 24a00a9..0574ef1 100755\n--- a/t/t3300-funny-names.sh\n+++ b/t/t3300-funny-names.sh\n@@ -35,7 +35,7 @@ no-funny' >expected\n test_expect_success 'git ls-files no-funny' \\\n \t'git update-index --add \"$p0\" \"$p2\" &&\n \tgit ls-files >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n t0=`git write-tree`\n echo \"$t0\" >t0\n@@ -48,14 +48,14 @@ EOF\n test_expect_success 'git ls-files with-funny' \\\n \t'git update-index --add \"$p1\" &&\n \tgit ls-files >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n echo 'just space\n no-funny\n tabs\t,\" (dq) and spaces' >expected\n test_expect_success 'git ls-files -z with-funny' \\\n \t'git ls-files -z | perl -pe y/\\\\000/\\\\012/ >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n t1=`git write-tree`\n echo \"$t1\" >t1\n@@ -67,28 +67,28 @@ no-funny\n EOF\n test_expect_success 'git ls-tree with funny' \\\n \t'git ls-tree -r $t1 | sed -e \"s/^[^\t]*\t//\" >current &&\n-\t git diff expected current'\n+\t test_cmp expected current'\n \n cat > expected <<\\EOF\n A\t\"tabs\\t,\\\" (dq) and spaces\"\n EOF\n test_expect_success 'git diff-index with-funny' \\\n \t'git diff-index --name-status $t0 >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n test_expect_success 'git diff-tree with-funny' \\\n \t'git diff-tree --name-status $t0 $t1 >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n echo 'A\n tabs\t,\" (dq) and spaces' >expected\n test_expect_success 'git diff-index -z with-funny' \\\n \t'git diff-index -z --name-status $t0 | perl -pe y/\\\\000/\\\\012/ >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n test_expect_success 'git diff-tree -z with-funny' \\\n \t'git diff-tree -z --name-status $t0 $t1 | perl -pe y/\\\\000/\\\\012/ >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n cat > expected <<\\EOF\n CNUM\tno-funny\t\"tabs\\t,\\\" (dq) and spaces\"\n@@ -96,7 +96,7 @@ EOF\n test_expect_success 'git diff-tree -C with-funny' \\\n \t'git diff-tree -C --find-copies-harder --name-status \\\n \t\t$t0 $t1 | sed -e 's/^C[0-9]*/CNUM/' >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n cat > expected <<\\EOF\n RNUM\tno-funny\t\"tabs\\t,\\\" (dq) and spaces\"\n@@ -105,7 +105,7 @@ test_expect_success 'git diff-tree delete with-funny' \\\n \t'git update-index --force-remove \"$p0\" &&\n \tgit diff-index -M --name-status \\\n \t\t$t0 | sed -e 's/^R[0-9]*/RNUM/' >current &&\n-\tgit diff expected current'\n+\ttest_cmp expected current'\n \n cat > expected <<\\EOF\n diff --git a/no-funny \"b/tabs\\t,\\\" (dq) and spaces\"\n@@ -116,7 +116,7 @@ EOF\n test_expect_success 'git diff-tree delete with-funny' \\\n \t'git diff-index -M -p $t0 |\n \t sed -e \"s/index [0-9]*%/index NUM%/\" >current &&\n-\t git diff expected current'\n+\t test_cmp expected current'\n \n chmod +x \"$p1\"\n cat > expected <<\\EOF\n@@ -130,7 +130,7 @@ EOF\n test_expect_success 'git diff-tree delete with-funny' \\\n \t'git diff-index -M -p $t0 |\n \t sed -e \"s/index [0-9]*%/index NUM%/\" >current &&\n-\t git diff expected current'\n+\t test_cmp expected current'\n \n cat >expected <<\\EOF\n  \"tabs\\t,\\\" (dq) and spaces\"\n@@ -139,7 +139,7 @@ EOF\n test_expect_success 'git diff-tree rename with-funny applied' \\\n \t'git diff-index -M -p $t0 |\n \t git apply --stat | sed -e \"s/|.*//\" -e \"s/ *\\$//\" >current &&\n-\t git diff expected current'\n+\t test_cmp expected current'\n \n cat > expected <<\\EOF\n  no-funny\n@@ -149,12 +149,12 @@ EOF\n test_expect_success 'git diff-tree delete with-funny applied' \\\n \t'git diff-index -p $t0 |\n \t git apply --stat | sed -e \"s/|.*//\" -e \"s/ *\\$//\" >current &&\n-\t git diff expected current'\n+\t test_cmp expected current'\n \n test_expect_success 'git apply non-git diff' \\\n \t'git diff-index -p $t0 |\n \t sed -ne \"/^[-+@]/p\" |\n \t git apply --stat | sed -e \"s/|.*//\" -e \"s/ *\\$//\" >current &&\n-\t git diff expected current'\n+\t test_cmp expected current'\n \n test_done\ndiff --git a/t/t3900-i18n-commit.sh b/t/t3900-i18n-commit.sh\nindex 94b1c24..883281d 100755\n--- a/t/t3900-i18n-commit.sh\n+++ b/t/t3900-i18n-commit.sh\n@@ -9,7 +9,7 @@ test_description='commit and log output encodings'\n \n compare_with () {\n \tgit show -s $1 | sed -e '1,/^$/d' -e 's/^    //' >current &&\n-\tgit diff current \"$2\"\n+\ttest_cmp current \"$2\"\n }\n \n test_expect_success setup '\ndiff --git a/t/t4006-diff-mode.sh b/t/t4006-diff-mode.sh\nindex ab5406d..4e92fce 100755\n--- a/t/t4006-diff-mode.sh\n+++ b/t/t4006-diff-mode.sh\n@@ -38,6 +38,6 @@ echo \":100644 100755 X X M\trezrov\" >expected\n \n test_expect_success \\\n     'verify' \\\n-    'git diff expected check'\n+    'test_cmp expected check'\n \n test_done\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex 6b4d1c5..4c038cc 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -112,7 +112,7 @@ do\n \t\t} >\"$actual\" &&\n \t\tif test -f \"$expect\"\n \t\tthen\n-\t\t\tgit diff \"$expect\" \"$actual\" &&\n+\t\t\ttest_cmp \"$expect\" \"$actual\" &&\n \t\t\trm -f \"$actual\"\n \t\telse\n \t\t\t# this is to help developing new tests.\ndiff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh\nindex b2b7a8d..3583e68 100755\n--- a/t/t4014-format-patch.sh\n+++ b/t/t4014-format-patch.sh\n@@ -226,7 +226,7 @@ test_expect_success 'shortlog of cover-letter wraps overly-long onelines' '\n \n \tgit format-patch --cover-letter -2 &&\n \tsed -e \"1,/A U Thor/d\" -e \"/^$/q\" < 0000-cover-letter.patch > output &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n \n '\n \ndiff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh\nindex 83c54b7..ca0302f 100755\n--- a/t/t4015-diff-whitespace.sh\n+++ b/t/t4015-diff-whitespace.sh\n@@ -43,13 +43,13 @@ index adf3937..6edc172 100644\n EOF\n \n git diff > out\n-test_expect_success \"Ray's example without options\" 'git diff expect out'\n+test_expect_success \"Ray's example without options\" 'test_cmp expect out'\n \n git diff -w > out\n-test_expect_success \"Ray's example with -w\" 'git diff expect out'\n+test_expect_success \"Ray's example with -w\" 'test_cmp expect out'\n \n git diff -b > out\n-test_expect_success \"Ray's example with -b\" 'git diff expect out'\n+test_expect_success \"Ray's example with -b\" 'test_cmp expect out'\n \n tr 'Q' '\\015' << EOF > x\n whitespace at beginning\n@@ -90,14 +90,14 @@ index d99af23..8b32fb5 100644\n +CR at end\n EOF\n git diff > out\n-test_expect_success 'another test, without options' 'git diff expect out'\n+test_expect_success 'another test, without options' 'test_cmp expect out'\n \n cat << EOF > expect\n diff --git a/x b/x\n index d99af23..8b32fb5 100644\n EOF\n git diff -w > out\n-test_expect_success 'another test, with -w' 'git diff expect out'\n+test_expect_success 'another test, with -w' 'test_cmp expect out'\n \n tr 'Q' '\\015' << EOF > expect\n diff --git a/x b/x\n@@ -115,7 +115,7 @@ index d99af23..8b32fb5 100644\n  CR at endQ\n EOF\n git diff -b > out\n-test_expect_success 'another test, with -b' 'git diff expect out'\n+test_expect_success 'another test, with -b' 'test_cmp expect out'\n \n test_expect_success 'check mixed spaces and tabs in indent' '\n \ndiff --git a/t/t4016-diff-quote.sh b/t/t4016-diff-quote.sh\nindex 5dbdc0c..0950250 100755\n--- a/t/t4016-diff-quote.sh\n+++ b/t/t4016-diff-quote.sh\n@@ -49,7 +49,7 @@ cat >expect <<\\EOF\n EOF\n test_expect_success 'git diff --summary -M HEAD' '\n \tgit diff --summary -M HEAD >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<\\EOF\n@@ -64,7 +64,7 @@ cat >expect <<\\EOF\n EOF\n test_expect_success 'git diff --stat -M HEAD' '\n \tgit diff --stat -M HEAD >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_done\ndiff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh\nindex f9db81d..6d3ef6c 100755\n--- a/t/t4018-diff-funcname.sh\n+++ b/t/t4018-diff-funcname.sh\n@@ -33,13 +33,13 @@ EOF\n sed 's/beer\\\\/beer,\\\\/' < Beer.java > Beer-correct.java\n \n test_expect_success 'default behaviour' '\n-\tgit diff Beer.java Beer-correct.java |\n+\tgit diff --no-index Beer.java Beer-correct.java |\n \tgrep \"^@@.*@@ public class Beer\"\n '\n \n test_expect_success 'preset java pattern' '\n \techo \"*.java diff=java\" >.gitattributes &&\n-\tgit diff Beer.java Beer-correct.java |\n+\tgit diff --no-index Beer.java Beer-correct.java |\n \tgrep \"^@@.*@@ public static void main(\"\n '\n \n@@ -48,13 +48,13 @@ git config diff.java.funcname '!static\n [^ \t].*s.*'\n \n test_expect_success 'custom pattern' '\n-\tgit diff Beer.java Beer-correct.java |\n+\tgit diff --no-index Beer.java Beer-correct.java |\n \tgrep \"^@@.*@@ int special;$\"\n '\n \n test_expect_success 'last regexp must not be negated' '\n \tgit config diff.java.funcname \"!static\" &&\n-\t! git diff Beer.java Beer-correct.java\n+\t! git diff --no-index Beer.java Beer-correct.java\n '\n \n test_done\ndiff --git a/t/t4100-apply-stat.sh b/t/t4100-apply-stat.sh\nindex 435f65b..8073a5a 100755\n--- a/t/t4100-apply-stat.sh\n+++ b/t/t4100-apply-stat.sh\n@@ -11,36 +11,36 @@ test_description='git apply --stat --summary test.\n test_expect_success \\\n     'rename' \\\n     'git apply --stat --summary <../t4100/t-apply-1.patch >current &&\n-    git diff ../t4100/t-apply-1.expect current'\n+    test_cmp ../t4100/t-apply-1.expect current'\n \n test_expect_success \\\n     'copy' \\\n     'git apply --stat --summary <../t4100/t-apply-2.patch >current &&\n-    git diff ../t4100/t-apply-2.expect current'\n+    test_cmp ../t4100/t-apply-2.expect current'\n \n test_expect_success \\\n     'rewrite' \\\n     'git apply --stat --summary <../t4100/t-apply-3.patch >current &&\n-    git diff ../t4100/t-apply-3.expect current'\n+    test_cmp ../t4100/t-apply-3.expect current'\n \n test_expect_success \\\n     'mode' \\\n     'git apply --stat --summary <../t4100/t-apply-4.patch >current &&\n-    git diff ../t4100/t-apply-4.expect current'\n+    test_cmp ../t4100/t-apply-4.expect current'\n \n test_expect_success \\\n     'non git' \\\n     'git apply --stat --summary <../t4100/t-apply-5.patch >current &&\n-    git diff ../t4100/t-apply-5.expect current'\n+    test_cmp ../t4100/t-apply-5.expect current'\n \n test_expect_success \\\n     'non git' \\\n     'git apply --stat --summary <../t4100/t-apply-6.patch >current &&\n-    git diff ../t4100/t-apply-6.expect current'\n+    test_cmp ../t4100/t-apply-6.expect current'\n \n test_expect_success \\\n     'non git' \\\n     'git apply --stat --summary <../t4100/t-apply-7.patch >current &&\n-    git diff ../t4100/t-apply-7.expect current'\n+    test_cmp ../t4100/t-apply-7.expect current'\n \n test_done\ndiff --git a/t/t4104-apply-boundary.sh b/t/t4104-apply-boundary.sh\nindex 43943ab..e7e2913 100755\n--- a/t/t4104-apply-boundary.sh\n+++ b/t/t4104-apply-boundary.sh\n@@ -90,7 +90,7 @@ do\n \t\t\t\tcat '\"$kind-patch.$with\"'\n \t\t\t\t(exit 1)\n \t\t\t} &&\n-\t\t\tgit diff '\"$kind\"'-expect victim\n+\t\t\ttest_cmp '\"$kind\"'-expect victim\n \t\t'\n \tdone\n done\n@@ -108,7 +108,7 @@ do\n \t\t\tcat '\"$kind-ng.without\"'\n \t\t\t(exit 1)\n \t\t} &&\n-\t\tgit diff '\"$kind\"'-expect victim\n+\t\ttest_cmp '\"$kind\"'-expect victim\n \t'\n done\n \ndiff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh\nindex a07ff42..9ace578 100755\n--- a/t/t4115-apply-symlink.sh\n+++ b/t/t4115-apply-symlink.sh\n@@ -33,7 +33,7 @@ test_expect_success 'apply symlink patch' '\n \tgit checkout side &&\n \tgit apply patch &&\n \tgit diff-files -p >patched &&\n-\tgit diff patch patched\n+\ttest_cmp patch patched\n \n '\n \n@@ -42,7 +42,7 @@ test_expect_success 'apply --index symlink patch' '\n \tgit checkout -f side &&\n \tgit apply --index patch &&\n \tgit diff-index --cached -p HEAD >patched &&\n-\tgit diff patch patched\n+\ttest_cmp patch patched\n \n '\n \ndiff --git a/t/t4116-apply-reverse.sh b/t/t4116-apply-reverse.sh\nindex c3f4579..1459a90 100755\n--- a/t/t4116-apply-reverse.sh\n+++ b/t/t4116-apply-reverse.sh\n@@ -42,7 +42,7 @@ test_expect_success 'apply in reverse' '\n \tgit reset --hard second &&\n \tgit apply --reverse --binary --index patch &&\n \tgit diff >diff &&\n-\tgit diff /dev/null diff\n+\ttest_cmp /dev/null diff\n \n '\n \ndiff --git a/t/t4117-apply-reject.sh b/t/t4117-apply-reject.sh\nindex 659e17c..e9ccd16 100755\n--- a/t/t4117-apply-reject.sh\n+++ b/t/t4117-apply-reject.sh\n@@ -54,7 +54,7 @@ test_expect_success 'apply without --reject should fail' '\n \t\texit 1\n \tfi\n \n-\tgit diff file1 saved.file1\n+\ttest_cmp file1 saved.file1\n '\n \n test_expect_success 'apply without --reject should fail' '\n@@ -65,7 +65,7 @@ test_expect_success 'apply without --reject should fail' '\n \t\texit 1\n \tfi\n \n-\tgit diff file1 saved.file1\n+\ttest_cmp file1 saved.file1\n '\n \n test_expect_success 'apply with --reject should fail but update the file' '\n@@ -79,7 +79,7 @@ test_expect_success 'apply with --reject should fail but update the file' '\n \t\texit 1\n \tfi\n \n-\tgit diff file1 expected &&\n+\ttest_cmp file1 expected &&\n \n \tcat file1.rej &&\n \n@@ -105,7 +105,7 @@ test_expect_success 'apply with --reject should fail but update the file' '\n \t\techo \"file1 still exists?\"\n \t\texit 1\n \t}\n-\tgit diff file2 expected &&\n+\ttest_cmp file2 expected &&\n \n \tcat file2.rej &&\n \n@@ -132,7 +132,7 @@ test_expect_success 'the same test with --verbose' '\n \t\techo \"file1 still exists?\"\n \t\texit 1\n \t}\n-\tgit diff file2 expected &&\n+\ttest_cmp file2 expected &&\n \n \tcat file2.rej &&\n \n@@ -151,7 +151,7 @@ test_expect_success 'apply cleanly with --verbose' '\n \n \tgit apply --verbose patch.1 &&\n \n-\tgit diff file1 clean\n+\ttest_cmp file1 clean\n '\n \n test_done\ndiff --git a/t/t4118-apply-empty-context.sh b/t/t4118-apply-empty-context.sh\nindex 1d531ca..f92e259 100755\n--- a/t/t4118-apply-empty-context.sh\n+++ b/t/t4118-apply-empty-context.sh\n@@ -38,7 +38,7 @@ test_expect_success 'apply --numstat' '\n \t\techo \"0\t1\tfile1\" &&\n \t\techo \"0\t1\tfile2\"\n \t} >expect &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n \n '\n \n@@ -48,8 +48,8 @@ test_expect_success 'apply --apply' '\n \tcat file2.orig >file2 &&\n \tgit update-index file1 file2 &&\n \tgit apply --index diff.output &&\n-\tgit diff file1.mods file1 &&\n-\tgit diff file2.mods file2\n+\ttest_cmp file1.mods file1 &&\n+\ttest_cmp file2.mods file2\n '\n \n test_done\ndiff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh\nindex 3cbfee7..85d7e3e 100755\n--- a/t/t4200-rerere.sh\n+++ b/t/t4200-rerere.sh\n@@ -101,7 +101,7 @@ cat > expect << EOF\n EOF\n git rerere diff > out\n \n-test_expect_success 'rerere diff' 'git diff expect out'\n+test_expect_success 'rerere diff' 'test_cmp expect out'\n \n cat > expect << EOF\n a1\n@@ -109,7 +109,7 @@ EOF\n \n git rerere status > out\n \n-test_expect_success 'rerere status' 'git diff expect out'\n+test_expect_success 'rerere status' 'test_cmp expect out'\n \n test_expect_success 'commit succeeds' \\\n \t\"git commit -q -a -m 'prefer first over second'\"\n@@ -126,7 +126,7 @@ test_expect_success 'another conflicting merge' '\n git show first:a1 | sed 's/To die: t/To die! T/' > expect\n test_expect_success 'rerere kicked in' \"! grep ======= a1\"\n \n-test_expect_success 'rerere prefers first change' 'git diff a1 expect'\n+test_expect_success 'rerere prefers first change' 'test_cmp a1 expect'\n \n rm $rr/postimage\n echo \"$sha1\ta1\" | perl -pe 'y/\\012/\\000/' > .git/rr-cache/MERGE_RR\ndiff --git a/t/t5305-include-tag.sh b/t/t5305-include-tag.sh\nindex 0db2754..fb471a0 100755\n--- a/t/t5305-include-tag.sh\n+++ b/t/t5305-include-tag.sh\n@@ -50,7 +50,7 @@ test_expect_success 'check unpacked result (have commit, no tag)' '\n \t\ttest_must_fail git cat-file -e $tag &&\n \t\tgit rev-list --objects $commit\n \t) >list.actual &&\n-\tgit diff list.expect list.actual\n+\ttest_cmp list.expect list.actual\n '\n \n rm -rf clone.git\n@@ -78,7 +78,7 @@ test_expect_success 'check unpacked result (have commit, have tag)' '\n \t\texport GIT_DIR &&\n \t\tgit rev-list --objects $tag\n \t) >list.actual &&\n-\tgit diff list.expect list.actual\n+\ttest_cmp list.expect list.actual\n '\n \n test_done\ndiff --git a/t/t5400-send-pack.sh b/t/t5400-send-pack.sh\nindex 2b6b6e3..68c2ae6 100755\n--- a/t/t5400-send-pack.sh\n+++ b/t/t5400-send-pack.sh\n@@ -110,7 +110,7 @@ test_expect_success \\\n \tcd .. &&\n \tgit update-ref refs/heads/master master^ || return 1\n \tgit-send-pack --force ./victim/.git/ master && return 1\n-\t! git diff .git/refs/heads/master victim/.git/refs/heads/master\n+\t! test_cmp .git/refs/heads/master victim/.git/refs/heads/master\n '\n \n test_expect_success \\\ndiff --git a/t/t5401-update-hooks.sh b/t/t5401-update-hooks.sh\nindex 9a12024..2fff300 100755\n--- a/t/t5401-update-hooks.sh\n+++ b/t/t5401-update-hooks.sh\n@@ -83,23 +83,23 @@ test_expect_success 'hooks ran' '\n test_expect_success 'pre-receive hook input' '\n \t(echo $commit0 $commit1 refs/heads/master;\n \t echo $commit1 $commit0 refs/heads/tofail\n-\t) | git diff - victim/.git/pre-receive.stdin\n+\t) | test_cmp - victim/.git/pre-receive.stdin\n '\n \n test_expect_success 'update hook arguments' '\n \t(echo refs/heads/master $commit0 $commit1;\n \t echo refs/heads/tofail $commit1 $commit0\n-\t) | git diff - victim/.git/update.args\n+\t) | test_cmp - victim/.git/update.args\n '\n \n test_expect_success 'post-receive hook input' '\n \techo $commit0 $commit1 refs/heads/master |\n-\tgit diff - victim/.git/post-receive.stdin\n+\ttest_cmp - victim/.git/post-receive.stdin\n '\n \n test_expect_success 'post-update hook arguments' '\n \techo refs/heads/master |\n-\tgit diff - victim/.git/post-update.args\n+\ttest_cmp - victim/.git/post-update.args\n '\n \n test_expect_success 'all hook stdin is /dev/null' '\n@@ -130,7 +130,7 @@ STDERR post-update\n EOF\n test_expect_success 'send-pack stderr contains hook messages' '\n \tgrep ^STD send.err >actual &&\n-\tgit diff - actual <expect\n+\ttest_cmp - actual <expect\n '\n \n test_done\ndiff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh\nindex 86e5b9b..4074e23 100755\n--- a/t/t5503-tagfollow.sh\n+++ b/t/t5503-tagfollow.sh\n@@ -50,7 +50,7 @@ test_expect_success 'fetch A (new commit : 1 connection)' '\n \t) &&\n \ttest -s $U &&\n \tcut -d\" \" -f1,2 $U >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_expect_success \"create tag T on A, create C on branch cat\" '\n@@ -82,7 +82,7 @@ test_expect_success 'fetch C, T (new branch, tag : 1 connection)' '\n \t) &&\n \ttest -s $U &&\n \tcut -d\" \" -f1,2 $U >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_expect_success \"create commits O, B, tag S on B\" '\n@@ -118,7 +118,7 @@ test_expect_success 'fetch B, S (commit and tag : 1 connection)' '\n \t) &&\n \ttest -s $U &&\n \tcut -d\" \" -f1,2 $U >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat - <<EOF >expect\n@@ -144,7 +144,7 @@ test_expect_success 'new clone fetch master and tags' '\n \t) &&\n \ttest -s $U &&\n \tcut -d\" \" -f1,2 $U >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_done\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 48ff2d4..a37b6f5 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -135,7 +135,7 @@ test_expect_success 'show' '\n \t git config --add remote.origin.push \\\n \t\t+refs/tags/lastbackup &&\n \t git remote show origin > output &&\n-\t git diff expect output)\n+\t test_cmp expect output)\n '\n \n test_expect_success 'prune' '\n@@ -179,7 +179,7 @@ test_expect_success 'update' '\n \t git remote add apis ../mirror &&\n \t git remote update &&\n \t git branch -r > output &&\n-\t git diff expect output)\n+\t test_cmp expect output)\n \n '\n \n@@ -206,7 +206,7 @@ test_expect_success 'update with arguments' '\n \t git config remotes.titanus manduca &&\n \t git remote update phobaeticus titanus &&\n \t git branch -r > output &&\n-\t git diff expect output)\n+\t test_cmp expect output)\n \n '\n \n@@ -229,7 +229,7 @@ test_expect_success 'update default' '\n \t git config remote.drosophila.skipDefaultUpdate true &&\n \t git remote update default &&\n \t git branch -r > output &&\n-\t git diff expect output)\n+\t test_cmp expect output)\n \n '\n \n@@ -249,7 +249,7 @@ test_expect_success 'update default (overridden, with funny whitespace)' '\n \t git config remotes.default \"$(printf \"\\t drosophila  \\n\")\" &&\n \t git remote update default &&\n \t git branch -r > output &&\n-\t git diff expect output)\n+\t test_cmp expect output)\n \n '\n \ndiff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh\nindex 65c3774..3def75e 100755\n--- a/t/t5515-fetch-merge-logic.sh\n+++ b/t/t5515-fetch-merge-logic.sh\n@@ -151,7 +151,7 @@ do\n \t\tgit show-ref >\"$actual_r\" &&\n \t\tif test -f \"$expect_f\"\n \t\tthen\n-\t\t\tgit diff -u \"$expect_f\" \"$actual_f\" &&\n+\t\t\ttest_cmp \"$expect_f\" \"$actual_f\" &&\n \t\t\trm -f \"$actual_f\"\n \t\telse\n \t\t\t# this is to help developing new tests.\n@@ -160,7 +160,7 @@ do\n \t\tfi &&\n \t\tif test -f \"$expect_r\"\n \t\tthen\n-\t\t\tgit diff -u \"$expect_r\" \"$actual_r\" &&\n+\t\t\ttest_cmp \"$expect_r\" \"$actual_r\" &&\n \t\t\trm -f \"$actual_r\"\n \t\telse\n \t\t\t# this is to help developing new tests.\ndiff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh\nindex 0dc915e..9176484 100755\n--- a/t/t6006-rev-list-format.sh\n+++ b/t/t6006-rev-list-format.sh\n@@ -15,7 +15,7 @@ test_format() {\n \tcat >expect.$1\n \ttest_expect_success \"format $1\" \"\n git rev-list --pretty=format:$2 master >output.$1 &&\n-git diff expect.$1 output.$1\n+test_cmp expect.$1 output.$1\n \"\n }\n \ndiff --git a/t/t6023-merge-file.sh b/t/t6023-merge-file.sh\nindex 79dc58b..74e9e66 100755\n--- a/t/t6023-merge-file.sh\n+++ b/t/t6023-merge-file.sh\n@@ -63,7 +63,7 @@ test_expect_success \"merge without conflict (missing LF at EOF)\" \\\n \t\"git merge-file test2.txt orig.txt new2.txt\"\n \n test_expect_success \"merge result added missing LF\" \\\n-\t\"git diff test.txt test2.txt\"\n+\t\"test_cmp test.txt test2.txt\"\n \n cp test.txt backup.txt\n test_expect_success \"merge with conflicts\" \\\n@@ -86,7 +86,7 @@ non timebo mala, quoniam tu mecum es:\n virga tua et baculus tuus ipsa me consolata sunt.\n EOF\n \n-test_expect_success \"expected conflict markers\" \"git diff test.txt expect.txt\"\n+test_expect_success \"expected conflict markers\" \"test_cmp test.txt expect.txt\"\n \n cp backup.txt test.txt\n test_expect_success \"merge with conflicts, using -L\" \\\n@@ -110,7 +110,7 @@ virga tua et baculus tuus ipsa me consolata sunt.\n EOF\n \n test_expect_success \"expected conflict markers, with -L\" \\\n-\t\"git diff test.txt expect.txt\"\n+\t\"test_cmp test.txt expect.txt\"\n \n sed \"s/ tu / TU /\" < new1.txt > new5.txt\n test_expect_success \"conflict in removed tail\" \\\n@@ -132,7 +132,7 @@ virga tua et baculus tuus ipsa me consolata sunt.\n >>>>>>> new5.txt\n EOF\n \n-test_expect_success \"expected conflict markers\" \"git diff expect out\"\n+test_expect_success \"expected conflict markers\" \"test_cmp expect out\"\n \n test_expect_success 'binary files cannot be merged' '\n \t! git merge-file -p orig.txt ../test4012.png new1.txt 2> merge.err &&\ndiff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh\nindex 23d24d3..6a6a130 100755\n--- a/t/t6024-recursive-merge.sh\n+++ b/t/t6024-recursive-merge.sh\n@@ -70,7 +70,7 @@ G\n >>>>>>> G:a1\n EOF\n \n-test_expect_success \"result contains a conflict\" \"git diff expect a1\"\n+test_expect_success \"result contains a conflict\" \"test_cmp expect a1\"\n \n git ls-files --stage > out\n cat > expect << EOF\n@@ -79,7 +79,7 @@ cat > expect << EOF\n 100644 fd7923529855d0b274795ae3349c5e0438333979 3\ta1\n EOF\n \n-test_expect_success \"virtual trees were processed\" \"git diff expect out\"\n+test_expect_success \"virtual trees were processed\" \"test_cmp expect out\"\n \n test_expect_success 'refuse to merge binary files' '\n \tgit reset --hard &&\ndiff --git a/t/t6029-merge-subtree.sh b/t/t6029-merge-subtree.sh\nindex 43f5459..5bbfa44 100755\n--- a/t/t6029-merge-subtree.sh\n+++ b/t/t6029-merge-subtree.sh\n@@ -57,7 +57,7 @@ test_expect_success 'initial merge' '\n \t\techo \"100644 $o1 0\tgit-gui/git-gui.sh\"\n \t\techo \"100644 $o2 0\tgit.c\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'merge update' '\n@@ -73,7 +73,7 @@ test_expect_success 'merge update' '\n \t\techo \"100644 $o3 0\tgit-gui/git-gui.sh\"\n \t\techo \"100644 $o2 0\tgit.c\"\n \t) >expected &&\n-\tgit diff -u expected actual\n+\ttest_cmp expected actual\n '\n \n test_done\ndiff --git a/t/t6120-describe.sh b/t/t6120-describe.sh\nindex 56bbd85..ea476a2 100755\n--- a/t/t6120-describe.sh\n+++ b/t/t6120-describe.sh\n@@ -108,7 +108,7 @@ warning: tag 'A' is really 'Q' here\n EOF\n check_describe A-* HEAD\n test_expect_success 'warning was displayed for Q' '\n-\tgit diff err.expect err.actual\n+\ttest_cmp err.expect err.actual\n '\n test_expect_success 'rename tag Q back to A' '\n \tmv .git/refs/tags/Q .git/refs/tags/A\ndiff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh\nindex c9bf6fd..bc74349 100755\n--- a/t/t6200-fmt-merge-msg.sh\n+++ b/t/t6200-fmt-merge-msg.sh\n@@ -79,7 +79,7 @@ test_expect_success 'merge-msg test #1' '\n \tgit fetch . left &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n cat >expected <<EOF\n@@ -92,7 +92,7 @@ test_expect_success 'merge-msg test #2' '\n \tgit fetch ../\"$test\" left &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -117,7 +117,7 @@ test_expect_success 'merge-msg test #3-1' '\n \tgit fetch . left &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'merge-msg test #3-2' '\n@@ -131,7 +131,7 @@ test_expect_success 'merge-msg test #3-2' '\n \tgit fetch . left &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -163,7 +163,7 @@ test_expect_success 'merge-msg test #4-1' '\n \tgit fetch . left right &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'merge-msg test #4-2' '\n@@ -177,7 +177,7 @@ test_expect_success 'merge-msg test #4-2' '\n \tgit fetch . left right &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'merge-msg test #5-1' '\n@@ -191,7 +191,7 @@ test_expect_success 'merge-msg test #5-1' '\n \tgit fetch . left right &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'merge-msg test #5-2' '\n@@ -205,7 +205,7 @@ test_expect_success 'merge-msg test #5-2' '\n \tgit fetch . left right &&\n \n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\tgit diff actual expected\n+\ttest_cmp expected actual\n '\n \n test_done\ndiff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh\nindex f46ec93..91ea85d 100755\n--- a/t/t6300-for-each-ref.sh\n+++ b/t/t6300-for-each-ref.sh\n@@ -75,14 +75,14 @@ EOF\n test_expect_success 'Check unformatted date fields output' '\n \t(git for-each-ref --shell --format=\"%(refname) %(committerdate) %(authordate)\" refs/heads &&\n \tgit for-each-ref --shell --format=\"%(refname) %(taggerdate)\" refs/tags) >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'Check format \"default\" formatted date fields output' '\n \tf=default &&\n \t(git for-each-ref --shell --format=\"%(refname) %(committerdate:$f) %(authordate:$f)\" refs/heads &&\n \tgit for-each-ref --shell --format=\"%(refname) %(taggerdate:$f)\" refs/tags) >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n # Don't know how to do relative check because I can't know when this script\n@@ -109,7 +109,7 @@ test_expect_success 'Check format \"short\" date fields output' '\n \tf=short &&\n \t(git for-each-ref --shell --format=\"%(refname) %(committerdate:$f) %(authordate:$f)\" refs/heads &&\n \tgit for-each-ref --shell --format=\"%(refname) %(taggerdate:$f)\" refs/tags) >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -121,7 +121,7 @@ test_expect_success 'Check format \"local\" date fields output' '\n \tf=local &&\n \t(git for-each-ref --shell --format=\"%(refname) %(committerdate:$f) %(authordate:$f)\" refs/heads &&\n \tgit for-each-ref --shell --format=\"%(refname) %(taggerdate:$f)\" refs/tags) >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -133,7 +133,7 @@ test_expect_success 'Check format \"iso8601\" date fields output' '\n \tf=iso8601 &&\n \t(git for-each-ref --shell --format=\"%(refname) %(committerdate:$f) %(authordate:$f)\" refs/heads &&\n \tgit for-each-ref --shell --format=\"%(refname) %(taggerdate:$f)\" refs/tags) >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -145,7 +145,7 @@ test_expect_success 'Check format \"rfc2822\" date fields output' '\n \tf=rfc2822 &&\n \t(git for-each-ref --shell --format=\"%(refname) %(committerdate:$f) %(authordate:$f)\" refs/heads &&\n \tgit for-each-ref --shell --format=\"%(refname) %(taggerdate:$f)\" refs/tags) >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -155,7 +155,7 @@ EOF\n \n test_expect_success 'Verify ascending sort' '\n \tgit-for-each-ref --format=\"%(refname)\" --sort=refname >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n \n@@ -166,7 +166,7 @@ EOF\n \n test_expect_success 'Verify descending sort' '\n \tgit-for-each-ref --format=\"%(refname)\" --sort=-refname >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -176,17 +176,17 @@ EOF\n \n test_expect_success 'Quoting style: shell' '\n \tgit for-each-ref --shell --format=\"%(refname)\" >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'Quoting style: perl' '\n \tgit for-each-ref --perl --format=\"%(refname)\" >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n test_expect_success 'Quoting style: python' '\n \tgit for-each-ref --python --format=\"%(refname)\" >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n cat >expected <<\\EOF\n@@ -196,7 +196,7 @@ EOF\n \n test_expect_success 'Quoting style: tcl' '\n \tgit for-each-ref --tcl --format=\"%(refname)\" >actual &&\n-\tgit diff expected actual\n+\ttest_cmp expected actual\n '\n \n for i in \"--perl --shell\" \"-s --python\" \"--python --tcl\" \"--tcl --perl\"; do\ndiff --git a/t/t7003-filter-branch.sh b/t/t7003-filter-branch.sh\nindex 1639c7a..1e8a205 100755\n--- a/t/t7003-filter-branch.sh\n+++ b/t/t7003-filter-branch.sh\n@@ -224,7 +224,7 @@ test_expect_success 'Tag name filtering retains tag message' '\n \tgit cat-file tag T > expect &&\n \tgit filter-branch -f --tag-name-filter cat &&\n \tgit cat-file tag T > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n faux_gpg_tag='object XXXXXX\n@@ -248,7 +248,7 @@ test_expect_success 'Tag name filtering strips gpg signature' '\n \techo \"$faux_gpg_tag\" | sed -e s/XXXXXX/$sha1/ | head -n 6 > expect &&\n \tgit filter-branch -f --tag-name-filter cat &&\n \tgit cat-file tag S > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_done\ndiff --git a/t/t7004-tag.sh b/t/t7004-tag.sh\nindex 2dcee7c..241c70d 100755\n--- a/t/t7004-tag.sh\n+++ b/t/t7004-tag.sh\n@@ -116,9 +116,9 @@ mytag\n EOF\n test_expect_success \\\n \t'trying to delete tags without params should succeed and do nothing' '\n-\tgit tag -l > actual && git diff expect actual &&\n+\tgit tag -l > actual && test_cmp expect actual &&\n \tgit-tag -d &&\n-\tgit tag -l > actual && git diff expect actual\n+\tgit tag -l > actual && test_cmp expect actual\n '\n \n test_expect_success \\\n@@ -173,9 +173,9 @@ test_expect_success 'listing all tags should print them ordered' '\n \tgit tag v1.0 &&\n \tgit tag t210 &&\n \tgit tag -l > actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit tag > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -186,7 +186,7 @@ EOF\n test_expect_success \\\n \t'listing tags with substring as pattern must print those matching' '\n \tgit-tag -l \"*a*\" > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -196,7 +196,7 @@ EOF\n test_expect_success \\\n \t'listing tags with a suffix as pattern must print those matching' '\n \tgit-tag -l \"*.1\" > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -206,7 +206,7 @@ EOF\n test_expect_success \\\n \t'listing tags with a prefix as pattern must print those matching' '\n \tgit-tag -l \"t21*\" > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -215,7 +215,7 @@ EOF\n test_expect_success \\\n \t'listing tags using a name as pattern must print that one matching' '\n \tgit-tag -l a1 > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -224,7 +224,7 @@ EOF\n test_expect_success \\\n \t'listing tags using a name as pattern must print that one matching' '\n \tgit-tag -l v1.0 > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -234,14 +234,14 @@ EOF\n test_expect_success \\\n \t'listing tags with ? in the pattern should print those matching' '\n \tgit-tag -l \"v1.?.?\" > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n >expect\n test_expect_success \\\n \t'listing tags using v.* should print nothing because none have v.' '\n \tgit-tag -l \"v.*\" > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >expect <<EOF\n@@ -253,7 +253,7 @@ EOF\n test_expect_success \\\n \t'listing tags using v* should print only those having v' '\n \tgit-tag -l \"v*\" > actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n # creating and verifying lightweight tags:\n@@ -302,7 +302,7 @@ test_expect_success \\\n \t'creating an annotated tag with -m message should succeed' '\n \tgit-tag -m \"A message\" annotated-tag &&\n \tget_tag_msg annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >msgfile <<EOF\n@@ -315,7 +315,7 @@ test_expect_success \\\n \t'creating an annotated tag with -F messagefile should succeed' '\n \tgit-tag -F msgfile file-annotated-tag &&\n \tget_tag_msg file-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >inputmsg <<EOF\n@@ -327,7 +327,7 @@ cat inputmsg >>expect\n test_expect_success 'creating an annotated tag with -F - should succeed' '\n \tgit-tag -F - stdin-annotated-tag <inputmsg &&\n \tget_tag_msg stdin-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_expect_success \\\n@@ -358,7 +358,7 @@ test_expect_success \\\n \t'creating a tag with an empty -m message should succeed' '\n \tgit-tag -m \"\" empty-annotated-tag &&\n \tget_tag_msg empty-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n >emptyfile\n@@ -367,7 +367,7 @@ test_expect_success \\\n \t'creating a tag with an empty -F messagefile should succeed' '\n \tgit-tag -F emptyfile emptyfile-annotated-tag &&\n \tget_tag_msg emptyfile-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n printf '\\n\\n  \\n\\t\\nLeading blank lines\\n' >blanksfile\n@@ -388,7 +388,7 @@ test_expect_success \\\n \t'extra blanks in the message for an annotated tag should be removed' '\n \tgit-tag -F blanksfile blanks-annotated-tag &&\n \tget_tag_msg blanks-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n get_tag_header blank-annotated-tag $commit commit $time >expect\n@@ -396,7 +396,7 @@ test_expect_success \\\n \t'creating a tag with blank -m message with spaces should succeed' '\n \tgit-tag -m \"     \" blank-annotated-tag &&\n \tget_tag_msg blank-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n echo '     ' >blankfile\n@@ -407,7 +407,7 @@ test_expect_success \\\n \t'creating a tag with blank -F messagefile with spaces should succeed' '\n \tgit-tag -F blankfile blankfile-annotated-tag &&\n \tget_tag_msg blankfile-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n printf '      ' >blanknonlfile\n@@ -416,7 +416,7 @@ test_expect_success \\\n \t'creating a tag with -F file of spaces and no newline should succeed' '\n \tgit-tag -F blanknonlfile blanknonlfile-annotated-tag &&\n \tget_tag_msg blanknonlfile-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n # messages with commented lines:\n@@ -451,7 +451,7 @@ test_expect_success \\\n \t'creating a tag using a -F messagefile with #comments should succeed' '\n \tgit-tag -F commentsfile comments-annotated-tag &&\n \tget_tag_msg comments-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n get_tag_header comment-annotated-tag $commit commit $time >expect\n@@ -459,7 +459,7 @@ test_expect_success \\\n \t'creating a tag with a #comment in the -m message should succeed' '\n \tgit-tag -m \"#comment\" comment-annotated-tag &&\n \tget_tag_msg comment-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n echo '#comment' >commentfile\n@@ -470,7 +470,7 @@ test_expect_success \\\n \t'creating a tag with #comments in the -F messagefile should succeed' '\n \tgit-tag -F commentfile commentfile-annotated-tag &&\n \tget_tag_msg commentfile-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n printf '#comment' >commentnonlfile\n@@ -479,7 +479,7 @@ test_expect_success \\\n \t'creating a tag with a file of #comment and no newline should succeed' '\n \tgit-tag -F commentnonlfile commentnonlfile-annotated-tag &&\n \tget_tag_msg commentnonlfile-annotated-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n # listing messages for annotated non-signed tags:\n@@ -490,23 +490,23 @@ test_expect_success \\\n \n \techo \"tag-one-line\" >expect &&\n \tgit-tag -l | grep \"^tag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l | grep \"^tag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l tag-one-line >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"tag-one-line    A msg\" >expect &&\n \tgit-tag -n1 -l | grep \"^tag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n -l | grep \"^tag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n1 -l tag-one-line >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n2 -l tag-one-line >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n999 -l tag-one-line >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_expect_success \\\n@@ -515,23 +515,23 @@ test_expect_success \\\n \n \techo \"tag-zero-lines\" >expect &&\n \tgit-tag -l | grep \"^tag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l | grep \"^tag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l tag-zero-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"tag-zero-lines  \" >expect &&\n \tgit-tag -n1 -l | grep \"^tag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n -l | grep \"^tag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n1 -l tag-zero-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n2 -l tag-zero-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n999 -l tag-zero-lines >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n echo 'tag line one' >annotagmsg\n@@ -543,39 +543,39 @@ test_expect_success \\\n \n \techo \"tag-lines\" >expect &&\n \tgit-tag -l | grep \"^tag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l | grep \"^tag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l tag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"tag-lines       tag line one\" >expect &&\n \tgit-tag -n1 -l | grep \"^tag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n -l | grep \"^tag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n1 -l tag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"    tag line two\" >>expect &&\n \tgit-tag -n2 -l | grep \"^ *tag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n2 -l tag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"    tag line three\" >>expect &&\n \tgit-tag -n3 -l | grep \"^ *tag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n3 -l tag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n4 -l | grep \"^ *tag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n4 -l tag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n99 -l | grep \"^ *tag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n99 -l tag-lines >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n # subsequent tests require gpg; check if it is available\n@@ -635,7 +635,7 @@ echo '-----BEGIN PGP SIGNATURE-----' >>expect\n test_expect_success 'creating a signed tag with -m message should succeed' '\n \tgit-tag -s -m \"A signed tag message\" signed-tag &&\n \tget_tag_msg signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n get_tag_header u-signed-tag $commit commit $time >expect\n@@ -645,7 +645,7 @@ test_expect_success 'sign with a given key id' '\n \n \tgit tag -u committer@example.com -m \"Another message\" u-signed-tag &&\n \tget_tag_msg u-signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n \n '\n \n@@ -675,7 +675,7 @@ echo '-----BEGIN PGP SIGNATURE-----' >>expect\n test_expect_success '-u implies signed tag' '\n \tGIT_EDITOR=./fakeeditor git-tag -u CDDE430D implied-sign &&\n \tget_tag_msg implied-sign >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >sigmsgfile <<EOF\n@@ -689,7 +689,7 @@ test_expect_success \\\n \t'creating a signed tag with -F messagefile should succeed' '\n \tgit-tag -s -F sigmsgfile file-signed-tag &&\n \tget_tag_msg file-signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n cat >siginputmsg <<EOF\n@@ -702,7 +702,7 @@ echo '-----BEGIN PGP SIGNATURE-----' >>expect\n test_expect_success 'creating a signed tag with -F - should succeed' '\n \tgit-tag -s -F - stdin-signed-tag <siginputmsg &&\n \tget_tag_msg stdin-signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n get_tag_header implied-annotate $commit commit $time >expect\n@@ -711,7 +711,7 @@ echo '-----BEGIN PGP SIGNATURE-----' >>expect\n test_expect_success '-s implies annotated tag' '\n \tGIT_EDITOR=./fakeeditor git-tag -s implied-annotate &&\n \tget_tag_msg implied-annotate >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_expect_success \\\n@@ -752,7 +752,7 @@ test_expect_success \\\n \t'creating a signed tag with an empty -m message should succeed' '\n \tgit-tag -s -m \"\" empty-signed-tag &&\n \tget_tag_msg empty-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v empty-signed-tag\n '\n \n@@ -763,7 +763,7 @@ test_expect_success \\\n \t'creating a signed tag with an empty -F messagefile should succeed' '\n \tgit-tag -s -F sigemptyfile emptyfile-signed-tag &&\n \tget_tag_msg emptyfile-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v emptyfile-signed-tag\n '\n \n@@ -786,7 +786,7 @@ test_expect_success \\\n \t'extra blanks in the message for a signed tag should be removed' '\n \tgit-tag -s -F sigblanksfile blanks-signed-tag &&\n \tget_tag_msg blanks-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v blanks-signed-tag\n '\n \n@@ -796,7 +796,7 @@ test_expect_success \\\n \t'creating a signed tag with a blank -m message should succeed' '\n \tgit-tag -s -m \"     \" blank-signed-tag &&\n \tget_tag_msg blank-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v blank-signed-tag\n '\n \n@@ -809,7 +809,7 @@ test_expect_success \\\n \t'creating a signed tag with blank -F file with spaces should succeed' '\n \tgit-tag -s -F sigblankfile blankfile-signed-tag &&\n \tget_tag_msg blankfile-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v blankfile-signed-tag\n '\n \n@@ -820,7 +820,7 @@ test_expect_success \\\n \t'creating a signed tag with spaces and no newline should succeed' '\n \tgit-tag -s -F sigblanknonlfile blanknonlfile-signed-tag &&\n \tget_tag_msg blanknonlfile-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v signed-tag\n '\n \n@@ -857,7 +857,7 @@ test_expect_success \\\n \t'creating a signed tag with a -F file with #comments should succeed' '\n \tgit-tag -s -F sigcommentsfile comments-signed-tag &&\n \tget_tag_msg comments-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v comments-signed-tag\n '\n \n@@ -867,7 +867,7 @@ test_expect_success \\\n \t'creating a signed tag with #commented -m message should succeed' '\n \tgit-tag -s -m \"#comment\" comment-signed-tag &&\n \tget_tag_msg comment-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v comment-signed-tag\n '\n \n@@ -880,7 +880,7 @@ test_expect_success \\\n \t'creating a signed tag with #commented -F messagefile should succeed' '\n \tgit-tag -s -F sigcommentfile commentfile-signed-tag &&\n \tget_tag_msg commentfile-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v commentfile-signed-tag\n '\n \n@@ -891,7 +891,7 @@ test_expect_success \\\n \t'creating a signed tag with a #comment and no newline should succeed' '\n \tgit-tag -s -F sigcommentnonlfile commentnonlfile-signed-tag &&\n \tget_tag_msg commentnonlfile-signed-tag >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -v commentnonlfile-signed-tag\n '\n \n@@ -903,23 +903,23 @@ test_expect_success \\\n \n \techo \"stag-one-line\" >expect &&\n \tgit-tag -l | grep \"^stag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l | grep \"^stag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l stag-one-line >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"stag-one-line   A message line signed\" >expect &&\n \tgit-tag -n1 -l | grep \"^stag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n -l | grep \"^stag-one-line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n1 -l stag-one-line >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n2 -l stag-one-line >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n999 -l stag-one-line >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_expect_success \\\n@@ -928,23 +928,23 @@ test_expect_success \\\n \n \techo \"stag-zero-lines\" >expect &&\n \tgit-tag -l | grep \"^stag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l | grep \"^stag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l stag-zero-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"stag-zero-lines \" >expect &&\n \tgit-tag -n1 -l | grep \"^stag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n -l | grep \"^stag-zero-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n1 -l stag-zero-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n2 -l stag-zero-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n999 -l stag-zero-lines >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n echo 'stag line one' >sigtagmsg\n@@ -956,39 +956,39 @@ test_expect_success \\\n \n \techo \"stag-lines\" >expect &&\n \tgit-tag -l | grep \"^stag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l | grep \"^stag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n0 -l stag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"stag-lines      stag line one\" >expect &&\n \tgit-tag -n1 -l | grep \"^stag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n -l | grep \"^stag-lines\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n1 -l stag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"    stag line two\" >>expect &&\n \tgit-tag -n2 -l | grep \"^ *stag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n2 -l stag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \n \techo \"    stag line three\" >>expect &&\n \tgit-tag -n3 -l | grep \"^ *stag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n3 -l stag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n4 -l | grep \"^ *stag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n4 -l stag-lines >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n99 -l | grep \"^ *stag.line\" >actual &&\n-\tgit diff expect actual &&\n+\ttest_cmp expect actual &&\n \tgit-tag -n99 -l stag-lines >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n # tags pointing to objects different from commits:\n@@ -1004,7 +1004,7 @@ test_expect_success \\\n \t'creating a signed tag pointing to a tree should succeed' '\n \tgit-tag -s -m \"A message for a tree\" tree-signed-tag HEAD^{tree} &&\n \tget_tag_msg tree-signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n get_tag_header blob-signed-tag $blob blob $time >expect\n@@ -1014,7 +1014,7 @@ test_expect_success \\\n \t'creating a signed tag pointing to a blob should succeed' '\n \tgit-tag -s -m \"A message for a blob\" blob-signed-tag HEAD:foo &&\n \tget_tag_msg blob-signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n get_tag_header tag-signed-tag $tag tag $time >expect\n@@ -1024,7 +1024,7 @@ test_expect_success \\\n \t'creating a signed tag pointing to another tag should succeed' '\n \tgit-tag -s -m \"A message for another tag\" tag-signed-tag signed-tag &&\n \tget_tag_msg tag-signed-tag >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n # try to sign with bad user.signingkey\n@@ -1064,7 +1064,7 @@ test_expect_success \\\n \tgit tag -a -m \"An annotation to be reused\" reuse &&\n \tGIT_EDITOR=true git tag -f -a reuse &&\n \tget_tag_msg reuse >actual &&\n-\tgit diff expect actual\n+\ttest_cmp expect actual\n '\n \n test_done\ndiff --git a/t/t7102-reset.sh b/t/t7102-reset.sh\nindex e5c9f30..39ba141 100755\n--- a/t/t7102-reset.sh\n+++ b/t/t7102-reset.sh\n@@ -34,13 +34,13 @@ test_expect_success 'creating initial files and commits' '\n \n check_changes () {\n \ttest \"$(git rev-parse HEAD)\" = \"$1\" &&\n-\tgit diff | git diff .diff_expect - &&\n-\tgit diff --cached | git diff .cached_expect - &&\n+\tgit diff | test_cmp .diff_expect - &&\n+\tgit diff --cached | test_cmp .cached_expect - &&\n \tfor FILE in *\n \tdo\n \t\techo $FILE':'\n \t\tcat $FILE || return\n-\tdone | git diff .cat_expect -\n+\tdone | test_cmp .cat_expect -\n }\n \n >.diff_expect\n@@ -390,9 +390,9 @@ test_expect_success 'test --mixed <paths>' '\n \tgit add file1 file3 file4 &&\n \t! git reset HEAD -- file1 file2 file3 &&\n \tgit diff > output &&\n-\tgit diff output expect &&\n+\ttest_cmp output expect &&\n \tgit diff --cached > output &&\n-\tgit diff output cached_expect\n+\ttest_cmp output cached_expect\n '\n \n test_expect_success 'test resetting the index at give paths' '\n@@ -425,7 +425,7 @@ EOF\n test_expect_success '--mixed refreshes the index' '\n \techo 123 >> file2 &&\n \tgit reset --mixed HEAD > output &&\n-\tgit diff --exit-code expect output\n+\ttest_cmp expect output\n '\n \n test_done\ndiff --git a/t/t7502-status.sh b/t/t7502-status.sh\nindex e4bfcae..80a438d 100755\n--- a/t/t7502-status.sh\n+++ b/t/t7502-status.sh\n@@ -63,7 +63,7 @@ EOF\n test_expect_success 'status (2)' '\n \n \tgit status > output &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n \n '\n \n@@ -93,7 +93,7 @@ EOF\n test_expect_success 'status with relative paths' '\n \n \t(cd dir1 && git status) > output &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n \n '\n \n@@ -124,7 +124,7 @@ test_expect_success 'status without relative paths' '\n \n \tgit config status.relativePaths false\n \t(cd dir1 && git status) > output &&\n-\tgit diff expect output\n+\ttest_cmp expect output\n \n '\n \ndiff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh\nindex bdf29c1..242cdf0 100755\n--- a/t/t9100-git-svn-basic.sh\n+++ b/t/t9100-git-svn-basic.sh\n@@ -169,7 +169,7 @@ test_expect_success \"$name\" '\n \tsvn up \"$SVN_TREE\" &&\n \ttest -f \"$SVN_TREE\"/exec-2.sh &&\n \ttest ! -L \"$SVN_TREE\"/exec-2.sh &&\n-\tgit diff help \"$SVN_TREE\"/exec-2.sh'\n+\ttest_cmp help \"$SVN_TREE\"/exec-2.sh'\n \n if test \"$have_utf8\" = t\n then\n@@ -193,7 +193,7 @@ test_expect_success \"$name\" \\\n     'git-svn init \"$svnrepo\" && git-svn fetch &&\n      git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a &&\n      git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b &&\n-     git diff a b'\n+     test_cmp a b'\n \n name='check imported tree checksums expected tree checksums'\n rm -f expected\n@@ -211,7 +211,7 @@ tree d667270a1f7b109f5eb3aaea21ede14b56bfdd6e\n tree 8f51f74cf0163afc9ad68a4b1537288c4558b5a4\n EOF\n \n-test_expect_success \"$name\" \"git diff a expected\"\n+test_expect_success \"$name\" \"test_cmp a expected\"\n \n test_expect_success 'exit if remote refs are ambigious' \"\n         git config --add svn-remote.svn.fetch \\\ndiff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh\nindex c4f4465..5edf56f 100755\n--- a/t/t9300-fast-import.sh\n+++ b/t/t9300-fast-import.sh\n@@ -74,7 +74,7 @@ EOF\n test_expect_success \\\n \t'A: verify commit' \\\n \t'git cat-file commit master | sed 1d >actual &&\n-\tgit diff expect actual'\n+\ttest_cmp expect actual'\n \n cat >expect <<EOF\n 100644 blob file2\n@@ -84,22 +84,22 @@ EOF\n test_expect_success \\\n \t'A: verify tree' \\\n \t'git cat-file -p master^{tree} | sed \"s/ [0-9a-f]*\t/ /\" >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n echo \"$file2_data\" >expect\n test_expect_success \\\n \t'A: verify file2' \\\n-\t'git cat-file blob master:file2 >actual && git diff expect actual'\n+\t'git cat-file blob master:file2 >actual && test_cmp expect actual'\n \n echo \"$file3_data\" >expect\n test_expect_success \\\n \t'A: verify file3' \\\n-\t'git cat-file blob master:file3 >actual && git diff expect actual'\n+\t'git cat-file blob master:file3 >actual && test_cmp expect actual'\n \n printf \"$file4_data\" >expect\n test_expect_success \\\n \t'A: verify file4' \\\n-\t'git cat-file blob master:file4 >actual && git diff expect actual'\n+\t'git cat-file blob master:file4 >actual && test_cmp expect actual'\n \n cat >expect <<EOF\n :2 `git rev-parse --verify master:file2`\n@@ -109,7 +109,7 @@ cat >expect <<EOF\n EOF\n test_expect_success \\\n \t'A: verify marks output' \\\n-\t'git diff expect marks.out'\n+\t'test_cmp expect marks.out'\n \n test_expect_success \\\n \t'A: verify marks import' \\\n@@ -117,7 +117,7 @@ test_expect_success \\\n \t\t--import-marks=marks.out \\\n \t\t--export-marks=marks.new \\\n \t\t</dev/null &&\n-\tgit diff -u expect marks.new'\n+\ttest_cmp expect marks.new'\n \n test_tick\n cat >input <<INPUT_END\n@@ -259,7 +259,7 @@ EOF\n test_expect_success \\\n \t'C: verify commit' \\\n \t'git cat-file commit branch | sed 1d >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n cat >expect <<EOF\n :000000 100755 0000000000000000000000000000000000000000 f1fb5da718392694d0076d677d6d0e364c79b0bc A\tfile2/newf\n@@ -316,13 +316,13 @@ echo \"$file5_data\" >expect\n test_expect_success \\\n \t'D: verify file5' \\\n \t'git cat-file blob branch:newdir/interesting >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n echo \"$file6_data\" >expect\n test_expect_success \\\n \t'D: verify file6' \\\n \t'git cat-file blob branch:newdir/exec.sh >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n ###\n ### series E\n@@ -358,7 +358,7 @@ EOF\n test_expect_success \\\n \t'E: verify commit' \\\n \t'git cat-file commit branch | sed 1,2d >actual &&\n-\tgit diff expect actual'\n+\ttest_cmp expect actual'\n \n ###\n ### series F\n@@ -411,7 +411,7 @@ EOF\n test_expect_success \\\n \t'F: verify other commit' \\\n \t'git cat-file commit other >actual &&\n-\tgit diff expect actual'\n+\ttest_cmp expect actual'\n \n ###\n ### series G\n@@ -489,7 +489,7 @@ echo \"$file5_data\" >expect\n test_expect_success \\\n \t'H: verify file' \\\n \t'git cat-file blob H:h/e/l/lo >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n ###\n ### series I\n@@ -515,7 +515,7 @@ EOF\n test_expect_success \\\n \t'I: verify edge list' \\\n \t'sed -e s/pack-.*pack/pack-.pack/ edges.list >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n ###\n ### series J\n@@ -625,7 +625,7 @@ test_expect_success \\\n     'L: verify internal tree sorting' \\\n \t'git-fast-import <input &&\n \t git diff-tree --abbrev --raw L^ L >output &&\n-\t git diff expect output'\n+\t test_cmp expect output'\n \n ###\n ### series M\n@@ -885,7 +885,7 @@ test_expect_success \\\n \t test 8 = `find .git/objects/pack -type f | wc -l` &&\n \t test `git rev-parse refs/tags/O3-2nd` = `git rev-parse O3^` &&\n \t git log --reverse --pretty=oneline O3 | sed s/^.*z// >actual &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n cat >input <<INPUT_END\n commit refs/heads/O4\n@@ -916,6 +916,6 @@ test_expect_success \\\n \t'O: progress outputs as requested by input' \\\n \t'git-fast-import <input >actual &&\n \t grep \"progress \" <input >expect &&\n-\t git diff expect actual'\n+\t test_cmp expect actual'\n \n test_done\ndiff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh\nindex 0b115a1..655f882 100755\n--- a/t/t9600-cvsimport.sh\n+++ b/t/t9600-cvsimport.sh\n@@ -69,7 +69,7 @@ EOF\n test_expect_success 'import a trivial module' '\n \n \tgit cvsimport -a -z 0 -C module-git module &&\n-\tgit diff module-cvs/o_fortuna module-git/o_fortuna\n+\ttest_cmp module-cvs/o_fortuna module-git/o_fortuna\n \n '\n \n@@ -110,7 +110,7 @@ test_expect_success 'update git module' '\n \tgit cvsimport -a -z 0 module &&\n \tgit merge origin &&\n \tcd .. &&\n-\tgit diff module-cvs/o_fortuna module-git/o_fortuna\n+\ttest_cmp module-cvs/o_fortuna module-git/o_fortuna\n \n '\n \n@@ -131,7 +131,7 @@ test_expect_success 'cvsimport.module config works' '\n \t\tgit cvsimport -a -z0 &&\n \t\tgit merge origin &&\n \tcd .. &&\n-\tgit diff module-cvs/tick module-git/tick\n+\ttest_cmp module-cvs/tick module-git/tick\n \n '\n \n@@ -142,7 +142,7 @@ test_expect_success 'import from a CVS working tree' '\n \t\tgit cvsimport -a -z0 &&\n \t\techo 1 >expect &&\n \t\tgit log -1 --pretty=format:%s%n >actual &&\n-\t\tgit diff actual expect &&\n+\t\ttest_cmp actual expect &&\n \tcd ..\n \n '\n"},{"id":"77641","messageId":"7vhccomacn.fsf@gitster.siamese.dyndns.org","threadId":"13637","inReplyTo":"alpine.DEB.1.00.0805232349410.30431@racer","subject":"[PATCH 2/3] diff-files: do not play --no-index games","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-05-24T07:26:16Z","receivedAt":"2008-05-24T07:26:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Being able to say \"git diff A B\" outside a git repository and getting a\ncolourful version of \"diff -u A B\" may be nice, but such a cute hack\nshould not give bogus results to scripts that want to give two paths,\neither or both of which happen to have been removed from the work tree,\nto \"git diff-files\".\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n Documentation/git-diff-files.txt |    5 +---\n builtin-diff-files.c             |   44 +++++++++++++++++++++++++++++++-------\n git.c                            |    2 +-\n 3 files changed, 38 insertions(+), 13 deletions(-)\n\ndiff --git a/Documentation/git-diff-files.txt b/Documentation/git-diff-files.txt\nindex 6d2ea16..ca1bb6a 100644\n--- a/Documentation/git-diff-files.txt\n+++ b/Documentation/git-diff-files.txt\n@@ -8,7 +8,7 @@ git-diff-files - Compares files in the working tree and the index\n \n SYNOPSIS\n --------\n-'git-diff-files' [-q] [-0|-1|-2|-3|-c|--cc|--no-index] [<common diff options>] [<path>...]\n+'git-diff-files' [-q] [-0|-1|-2|-3|-c|--cc] [<common diff options>] [<path>...]\n \n DESCRIPTION\n -----------\n@@ -36,9 +36,6 @@ omit diff output for unmerged entries and just show \"Unmerged\".\n \tdiff, similar to the way 'diff-tree' shows a merge\n \tcommit with these flags.\n \n---no-index::\n-\tCompare the two given files / directories.\n-\n -q::\n \tRemain silent even on nonexistent files\n \ndiff --git a/builtin-diff-files.c b/builtin-diff-files.c\nindex e2306c1..3aa031f 100644\n--- a/builtin-diff-files.c\n+++ b/builtin-diff-files.c\n@@ -10,26 +10,54 @@\n #include \"builtin.h\"\n \n static const char diff_files_usage[] =\n-\"git-diff-files [-q] [-0/-1/2/3 |-c|--cc|--no-index] [<common diff options>] [<path>...]\"\n+\"git-diff-files [-q] [-0/-1/2/3 |-c|--cc] [<common diff options>] [<path>...]\"\n COMMON_DIFF_OPTIONS_HELP;\n \n int cmd_diff_files(int argc, const char **argv, const char *prefix)\n {\n \tstruct rev_info rev;\n-\tint nongit;\n \tint result;\n+\tunsigned options = 0;\n \n-\tprefix = setup_git_directory_gently(&nongit);\n \tinit_revisions(&rev, prefix);\n \tgit_config(git_diff_basic_config); /* no \"diff\" UI options */\n \trev.abbrev = 0;\n \n-\tif (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))\n-\t\targc = 0;\n-\telse\n-\t\targc = setup_revisions(argc, argv, &rev, NULL);\n+\targc = setup_revisions(argc, argv, &rev, NULL);\n+\twhile (1 < argc && argv[1][0] == '-') {\n+\t\tif (!strcmp(argv[1], \"--base\"))\n+\t\t\trev.max_count = 1;\n+\t\telse if (!strcmp(argv[1], \"--ours\"))\n+\t\t\trev.max_count = 2;\n+\t\telse if (!strcmp(argv[1], \"--theirs\"))\n+\t\t\trev.max_count = 3;\n+\t\telse if (!strcmp(argv[1], \"-q\"))\n+\t\t\toptions |= DIFF_SILENT_ON_REMOVED;\n+\t\telse\n+\t\t\tusage(diff_files_usage);\n+\t\targv++; argc--;\n+\t}\n \tif (!rev.diffopt.output_format)\n \t\trev.diffopt.output_format = DIFF_FORMAT_RAW;\n-\tresult = run_diff_files_cmd(&rev, argc, argv);\n+\n+\t/*\n+\t * Make sure there are NO revision (i.e. pending object) parameter,\n+\t * rev.max_count is reasonable (0 <= n <= 3), and\n+\t * there is no other revision filtering parameters.\n+\t */\n+\tif (rev.pending.nr ||\n+\t    rev.min_age != -1 || rev.max_age != -1 ||\n+\t    3 < rev.max_count)\n+\t\tusage(diff_files_usage);\n+\n+\tif (rev.max_count == -1 &&\n+\t    (rev.diffopt.output_format & DIFF_FORMAT_PATCH))\n+\t\trev.combine_merges = rev.dense_combined_merges = 1;\n+\n+\tif (read_cache() < 0) {\n+\t\tperror(\"read_cache\");\n+\t\treturn -1;\n+\t}\n+\tresult = run_diff_files(&rev, options);\n \treturn diff_result_code(&rev.diffopt, result);\n }\ndiff --git a/git.c b/git.c\nindex 89b431f..4b79380 100644\n--- a/git.c\n+++ b/git.c\n@@ -293,7 +293,7 @@ static void handle_internal_command(int argc, const char **argv)\n \t\t{ \"count-objects\", cmd_count_objects, RUN_SETUP },\n \t\t{ \"describe\", cmd_describe, RUN_SETUP },\n \t\t{ \"diff\", cmd_diff },\n-\t\t{ \"diff-files\", cmd_diff_files },\n+\t\t{ \"diff-files\", cmd_diff_files, RUN_SETUP },\n \t\t{ \"diff-index\", cmd_diff_index, RUN_SETUP },\n \t\t{ \"diff-tree\", cmd_diff_tree, RUN_SETUP },\n \t\t{ \"fast-export\", cmd_fast_export, RUN_SETUP },\n-- \n1.5.5.1.540.g57780\n"},{"id":"77643","messageId":"7vbq2wmac6.fsf@gitster.siamese.dyndns.org","threadId":"13637","inReplyTo":"alpine.DEB.1.00.0805232349410.30431@racer","subject":"[PATCH 3/3] \"git diff\": do not ignore index without --no-index","fromName":"Junio C Hamano","fromEmail":"junio@pobox.com","sentAt":"2008-05-24T07:26:33Z","receivedAt":"2008-05-24T07:26:33Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Even if \"foo\" and/or \"bar\" does not exist in index, \"git diff foo bar\"\nshould not change behaviour drastically from \"git diff foo bar baz\" or\n\"git diff foo\".  A feature that \"sometimes works and is handy\" is an\nunreliable cute hack.\n\n\"git diff foo bar\" outside a git repository continues to work as a more\ncolourful alternative to \"diff -u\" as before.\n\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\n * option parsing loop can be trivially factored out between\n   builtin_diff_files() and cmd_diff_files(), but I am too tired\n   so I'll call it a night.\n\n Makefile                                           |    1 +\n builtin-diff.c                                     |   55 +++-\n diff-lib.c                                         |  323 --------------------\n diff-no-index.c                                    |  231 ++++++++++++++\n diff.h                                             |    6 +-\n t/t4013-diff-various.sh                            |    1 +\n t/t4013/diff.diff_--name-status_dir2_dir           |    1 -\n .../diff.diff_--no-index_--name-status_dir2_dir    |    3 +\n 8 files changed, 283 insertions(+), 338 deletions(-)\n create mode 100644 diff-no-index.c\n create mode 100644 t/t4013/diff.diff_--no-index_--name-status_dir2_dir\n\ndiff --git a/Makefile b/Makefile\nindex 865e2bf..ad09e6c 100644\n--- a/Makefile\n+++ b/Makefile\n@@ -405,6 +405,7 @@ LIB_OBJS += diffcore-order.o\n LIB_OBJS += diffcore-pickaxe.o\n LIB_OBJS += diffcore-rename.o\n LIB_OBJS += diff-delta.o\n+LIB_OBJS += diff-no-index.o\n LIB_OBJS += diff-lib.o\n LIB_OBJS += diff.o\n LIB_OBJS += dir.o\ndiff --git a/builtin-diff.c b/builtin-diff.c\nindex 7c2a841..8b3b51e 100644\n--- a/builtin-diff.c\n+++ b/builtin-diff.c\n@@ -202,6 +202,37 @@ static void refresh_index_quietly(void)\n \trollback_lock_file(lock_file);\n }\n \n+static int builtin_diff_files(struct rev_info *revs, int argc, const char **argv)\n+{\n+\tint result;\n+\tunsigned int options = 0;\n+\n+\twhile (1 < argc && argv[1][0] == '-') {\n+\t\tif (!strcmp(argv[1], \"--base\"))\n+\t\t\trevs->max_count = 1;\n+\t\telse if (!strcmp(argv[1], \"--ours\"))\n+\t\t\trevs->max_count = 2;\n+\t\telse if (!strcmp(argv[1], \"--theirs\"))\n+\t\t\trevs->max_count = 3;\n+\t\telse if (!strcmp(argv[1], \"-q\"))\n+\t\t\toptions |= DIFF_SILENT_ON_REMOVED;\n+\t\telse\n+\t\t\treturn error(\"invalid option: %s\", argv[1]);\n+\t\targv++; argc--;\n+\t}\n+\n+\tif (revs->max_count == -1 &&\n+\t    (revs->diffopt.output_format & DIFF_FORMAT_PATCH))\n+\t\trevs->combine_merges = revs->dense_combined_merges = 1;\n+\n+\tif (read_cache() < 0) {\n+\t\tperror(\"read_cache\");\n+\t\treturn -1;\n+\t}\n+\tresult = run_diff_files(revs, options);\n+\treturn diff_result_code(&revs->diffopt, result);\n+}\n+\n int cmd_diff(int argc, const char **argv, const char *prefix)\n {\n \tint i;\n@@ -230,6 +261,9 @@ int cmd_diff(int argc, const char **argv, const char *prefix)\n \t * N=2, M=0:\n \t *      tree vs tree (diff-tree)\n \t *\n+\t * N=0, M=0, P=2:\n+\t *      compare two filesystem entities (aka --no-index).\n+\t *\n \t * Other cases are errors.\n \t */\n \n@@ -240,21 +274,21 @@ int cmd_diff(int argc, const char **argv, const char *prefix)\n \t\tdiff_use_color_default = git_use_color_default;\n \n \tinit_revisions(&rev, prefix);\n+\n+\t/* If this is a no-index diff, just run it and exit there. */\n+\tdiff_no_index(&rev, argc, argv, nongit, prefix);\n+\n+\t/* Otherwise, we are doing the usual \"git\" diff */\n \trev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index;\n \n-\tif (!setup_diff_no_index(&rev, argc, argv, nongit, prefix))\n-\t\targc = 0;\n-\telse\n-\t\targc = setup_revisions(argc, argv, &rev, NULL);\n+\tif (nongit)\n+\t\tdie(\"Not a git repository\");\n+\targc = setup_revisions(argc, argv, &rev, NULL);\n \tif (!rev.diffopt.output_format) {\n \t\trev.diffopt.output_format = DIFF_FORMAT_PATCH;\n \t\tif (diff_setup_done(&rev.diffopt) < 0)\n \t\t\tdie(\"diff_setup_done failed\");\n \t}\n-\tif (rev.diffopt.prefix && nongit) {\n-\t\trev.diffopt.prefix = NULL;\n-\t\trev.diffopt.prefix_length = 0;\n-\t}\n \tDIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL);\n \tDIFF_OPT_SET(&rev.diffopt, RECURSIVE);\n \n@@ -265,7 +299,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)\n \tif (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))\n \t\tsetup_pager();\n \n-\t/* Do we have --cached and not have a pending object, then\n+\t/*\n+\t * Do we have --cached and not have a pending object, then\n \t * default to HEAD by hand.  Eek.\n \t */\n \tif (!rev.pending.nr) {\n@@ -333,7 +368,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)\n \tif (!ents) {\n \t\tswitch (blobs) {\n \t\tcase 0:\n-\t\t\tresult = run_diff_files_cmd(&rev, argc, argv);\n+\t\t\tresult = builtin_diff_files(&rev, argc, argv);\n \t\t\tbreak;\n \t\tcase 1:\n \t\t\tif (paths != 1)\ndiff --git a/diff-lib.c b/diff-lib.c\nindex fe2ccec..b17722d 100644\n--- a/diff-lib.c\n+++ b/diff-lib.c\n@@ -8,7 +8,6 @@\n #include \"diffcore.h\"\n #include \"revision.h\"\n #include \"cache-tree.h\"\n-#include \"path-list.h\"\n #include \"unpack-trees.h\"\n #include \"refs.h\"\n \n@@ -16,328 +15,6 @@\n  * diff-files\n  */\n \n-static int read_directory(const char *path, struct path_list *list)\n-{\n-\tDIR *dir;\n-\tstruct dirent *e;\n-\n-\tif (!(dir = opendir(path)))\n-\t\treturn error(\"Could not open directory %s\", path);\n-\n-\twhile ((e = readdir(dir)))\n-\t\tif (strcmp(\".\", e->d_name) && strcmp(\"..\", e->d_name))\n-\t\t\tpath_list_insert(e->d_name, list);\n-\n-\tclosedir(dir);\n-\treturn 0;\n-}\n-\n-static int get_mode(const char *path, int *mode)\n-{\n-\tstruct stat st;\n-\n-\tif (!path || !strcmp(path, \"/dev/null\"))\n-\t\t*mode = 0;\n-\telse if (!strcmp(path, \"-\"))\n-\t\t*mode = create_ce_mode(0666);\n-\telse if (stat(path, &st))\n-\t\treturn error(\"Could not access '%s'\", path);\n-\telse\n-\t\t*mode = st.st_mode;\n-\treturn 0;\n-}\n-\n-static int queue_diff(struct diff_options *o,\n-\t\tconst char *name1, const char *name2)\n-{\n-\tint mode1 = 0, mode2 = 0;\n-\n-\tif (get_mode(name1, &mode1) || get_mode(name2, &mode2))\n-\t\treturn -1;\n-\n-\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))\n-\t\treturn error(\"file/directory conflict: %s, %s\", name1, name2);\n-\n-\tif (S_ISDIR(mode1) || S_ISDIR(mode2)) {\n-\t\tchar buffer1[PATH_MAX], buffer2[PATH_MAX];\n-\t\tstruct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1};\n-\t\tint len1 = 0, len2 = 0, i1, i2, ret = 0;\n-\n-\t\tif (name1 && read_directory(name1, &p1))\n-\t\t\treturn -1;\n-\t\tif (name2 && read_directory(name2, &p2)) {\n-\t\t\tpath_list_clear(&p1, 0);\n-\t\t\treturn -1;\n-\t\t}\n-\n-\t\tif (name1) {\n-\t\t\tlen1 = strlen(name1);\n-\t\t\tif (len1 > 0 && name1[len1 - 1] == '/')\n-\t\t\t\tlen1--;\n-\t\t\tmemcpy(buffer1, name1, len1);\n-\t\t\tbuffer1[len1++] = '/';\n-\t\t}\n-\n-\t\tif (name2) {\n-\t\t\tlen2 = strlen(name2);\n-\t\t\tif (len2 > 0 && name2[len2 - 1] == '/')\n-\t\t\t\tlen2--;\n-\t\t\tmemcpy(buffer2, name2, len2);\n-\t\t\tbuffer2[len2++] = '/';\n-\t\t}\n-\n-\t\tfor (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) {\n-\t\t\tconst char *n1, *n2;\n-\t\t\tint comp;\n-\n-\t\t\tif (i1 == p1.nr)\n-\t\t\t\tcomp = 1;\n-\t\t\telse if (i2 == p2.nr)\n-\t\t\t\tcomp = -1;\n-\t\t\telse\n-\t\t\t\tcomp = strcmp(p1.items[i1].path,\n-\t\t\t\t\tp2.items[i2].path);\n-\n-\t\t\tif (comp > 0)\n-\t\t\t\tn1 = NULL;\n-\t\t\telse {\n-\t\t\t\tn1 = buffer1;\n-\t\t\t\tstrncpy(buffer1 + len1, p1.items[i1++].path,\n-\t\t\t\t\t\tPATH_MAX - len1);\n-\t\t\t}\n-\n-\t\t\tif (comp < 0)\n-\t\t\t\tn2 = NULL;\n-\t\t\telse {\n-\t\t\t\tn2 = buffer2;\n-\t\t\t\tstrncpy(buffer2 + len2, p2.items[i2++].path,\n-\t\t\t\t\t\tPATH_MAX - len2);\n-\t\t\t}\n-\n-\t\t\tret = queue_diff(o, n1, n2);\n-\t\t}\n-\t\tpath_list_clear(&p1, 0);\n-\t\tpath_list_clear(&p2, 0);\n-\n-\t\treturn ret;\n-\t} else {\n-\t\tstruct diff_filespec *d1, *d2;\n-\n-\t\tif (DIFF_OPT_TST(o, REVERSE_DIFF)) {\n-\t\t\tunsigned tmp;\n-\t\t\tconst char *tmp_c;\n-\t\t\ttmp = mode1; mode1 = mode2; mode2 = tmp;\n-\t\t\ttmp_c = name1; name1 = name2; name2 = tmp_c;\n-\t\t}\n-\n-\t\tif (!name1)\n-\t\t\tname1 = \"/dev/null\";\n-\t\tif (!name2)\n-\t\t\tname2 = \"/dev/null\";\n-\t\td1 = alloc_filespec(name1);\n-\t\td2 = alloc_filespec(name2);\n-\t\tfill_filespec(d1, null_sha1, mode1);\n-\t\tfill_filespec(d2, null_sha1, mode2);\n-\n-\t\tdiff_queue(&diff_queued_diff, d1, d2);\n-\t\treturn 0;\n-\t}\n-}\n-\n-/*\n- * Does the path name a blob in the working tree, or a directory\n- * in the working tree?\n- */\n-static int is_in_index(const char *path)\n-{\n-\tint len, pos;\n-\tstruct cache_entry *ce;\n-\n-\tlen = strlen(path);\n-\twhile (path[len-1] == '/')\n-\t\tlen--;\n-\tif (!len)\n-\t\treturn 1; /* \".\" */\n-\tpos = cache_name_pos(path, len);\n-\tif (0 <= pos)\n-\t\treturn 1;\n-\tpos = -1 - pos;\n-\twhile (pos < active_nr) {\n-\t\tce = active_cache[pos++];\n-\t\tif (ce_namelen(ce) <= len ||\n-\t\t    strncmp(ce->name, path, len) ||\n-\t\t    (ce->name[len] > '/'))\n-\t\t\tbreak; /* path cannot be a prefix */\n-\t\tif (ce->name[len] == '/')\n-\t\t\treturn 1;\n-\t}\n-\treturn 0;\n-}\n-\n-static int handle_diff_files_args(struct rev_info *revs,\n-\t\t\t\t  int argc, const char **argv,\n-\t\t\t\t  unsigned int *options)\n-{\n-\t*options = 0;\n-\n-\t/* revs->max_count == -2 means --no-index */\n-\twhile (1 < argc && argv[1][0] == '-') {\n-\t\tif (!strcmp(argv[1], \"--base\"))\n-\t\t\trevs->max_count = 1;\n-\t\telse if (!strcmp(argv[1], \"--ours\"))\n-\t\t\trevs->max_count = 2;\n-\t\telse if (!strcmp(argv[1], \"--theirs\"))\n-\t\t\trevs->max_count = 3;\n-\t\telse if (!strcmp(argv[1], \"-n\") ||\n-\t\t\t\t!strcmp(argv[1], \"--no-index\")) {\n-\t\t\trevs->max_count = -2;\n-\t\t\tDIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);\n-\t\t\tDIFF_OPT_SET(&revs->diffopt, NO_INDEX);\n-\t\t}\n-\t\telse if (!strcmp(argv[1], \"-q\"))\n-\t\t\t*options |= DIFF_SILENT_ON_REMOVED;\n-\t\telse\n-\t\t\treturn error(\"invalid option: %s\", argv[1]);\n-\t\targv++; argc--;\n-\t}\n-\n-\tif (revs->max_count == -1 && revs->diffopt.nr_paths == 2) {\n-\t\t/*\n-\t\t * If two files are specified, and at least one is untracked,\n-\t\t * default to no-index.\n-\t\t */\n-\t\tread_cache();\n-\t\tif (!is_in_index(revs->diffopt.paths[0]) ||\n-\t\t\t\t\t!is_in_index(revs->diffopt.paths[1])) {\n-\t\t\trevs->max_count = -2;\n-\t\t\tDIFF_OPT_SET(&revs->diffopt, NO_INDEX);\n-\t\t}\n-\t}\n-\n-\t/*\n-\t * Make sure there are NO revision (i.e. pending object) parameter,\n-\t * rev.max_count is reasonable (0 <= n <= 3),\n-\t * there is no other revision filtering parameters.\n-\t */\n-\tif (revs->pending.nr || revs->max_count > 3 ||\n-\t    revs->min_age != -1 || revs->max_age != -1)\n-\t\treturn error(\"no revision allowed with diff-files\");\n-\n-\tif (revs->max_count == -1 &&\n-\t    (revs->diffopt.output_format & DIFF_FORMAT_PATCH))\n-\t\trevs->combine_merges = revs->dense_combined_merges = 1;\n-\n-\treturn 0;\n-}\n-\n-static int is_outside_repo(const char *path, int nongit, const char *prefix)\n-{\n-\tint i;\n-\tif (nongit || !strcmp(path, \"-\") || is_absolute_path(path))\n-\t\treturn 1;\n-\tif (prefixcmp(path, \"../\"))\n-\t\treturn 0;\n-\tif (!prefix)\n-\t\treturn 1;\n-\tfor (i = strlen(prefix); !prefixcmp(path, \"../\"); ) {\n-\t\twhile (i > 0 && prefix[i - 1] != '/')\n-\t\t\ti--;\n-\t\tif (--i < 0)\n-\t\t\treturn 1;\n-\t\tpath += 3;\n-\t}\n-\treturn 0;\n-}\n-\n-int setup_diff_no_index(struct rev_info *revs,\n-\t\tint argc, const char ** argv, int nongit, const char *prefix)\n-{\n-\tint i;\n-\tfor (i = 1; i < argc; i++)\n-\t\tif (argv[i][0] != '-' || argv[i][1] == '\\0')\n-\t\t\tbreak;\n-\t\telse if (!strcmp(argv[i], \"--\")) {\n-\t\t\ti++;\n-\t\t\tbreak;\n-\t\t} else if (i < argc - 3 && !strcmp(argv[i], \"--no-index\")) {\n-\t\t\ti = argc - 3;\n-\t\t\tDIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);\n-\t\t\tbreak;\n-\t\t}\n-\tif (nongit && argc != i + 2)\n-\t\tdie(\"git diff [--no-index] takes two paths\");\n-\n-\tif (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&\n-\t\t\t\t!is_outside_repo(argv[i], nongit, prefix)))\n-\t\treturn -1;\n-\n-\tdiff_setup(&revs->diffopt);\n-\tfor (i = 1; i < argc - 2; )\n-\t\tif (!strcmp(argv[i], \"--no-index\"))\n-\t\t\ti++;\n-\t\telse {\n-\t\t\tint j = diff_opt_parse(&revs->diffopt,\n-\t\t\t\t\targv + i, argc - i);\n-\t\t\tif (!j)\n-\t\t\t\tdie(\"invalid diff option/value: %s\", argv[i]);\n-\t\t\ti += j;\n-\t\t}\n-\n-\tif (prefix) {\n-\t\tint len = strlen(prefix);\n-\n-\t\trevs->diffopt.paths = xcalloc(2, sizeof(char*));\n-\t\tfor (i = 0; i < 2; i++) {\n-\t\t\tconst char *p = argv[argc - 2 + i];\n-\t\t\t/*\n-\t\t\t * stdin should be spelled as '-'; if you have\n-\t\t\t * path that is '-', spell it as ./-.\n-\t\t\t */\n-\t\t\tp = (strcmp(p, \"-\")\n-\t\t\t     ? xstrdup(prefix_filename(prefix, len, p))\n-\t\t\t     : p);\n-\t\t\trevs->diffopt.paths[i] = p;\n-\t\t}\n-\t}\n-\telse\n-\t\trevs->diffopt.paths = argv + argc - 2;\n-\trevs->diffopt.nr_paths = 2;\n-\tDIFF_OPT_SET(&revs->diffopt, NO_INDEX);\n-\trevs->max_count = -2;\n-\tif (diff_setup_done(&revs->diffopt) < 0)\n-\t\tdie(\"diff_setup_done failed\");\n-\treturn 0;\n-}\n-\n-int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)\n-{\n-\tunsigned int options;\n-\n-\tif (handle_diff_files_args(revs, argc, argv, &options))\n-\t\treturn -1;\n-\n-\tif (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) {\n-\t\tif (revs->diffopt.nr_paths != 2)\n-\t\t\treturn error(\"need two files/directories with --no-index\");\n-\t\tif (queue_diff(&revs->diffopt, revs->diffopt.paths[0],\n-\t\t\t\trevs->diffopt.paths[1]))\n-\t\t\treturn -1;\n-\t\tdiffcore_std(&revs->diffopt);\n-\t\tdiff_flush(&revs->diffopt);\n-\t\t/*\n-\t\t * The return code for --no-index imitates diff(1):\n-\t\t * 0 = no changes, 1 = changes, else error\n-\t\t */\n-\t\treturn revs->diffopt.found_changes;\n-\t}\n-\n-\tif (read_cache() < 0) {\n-\t\tperror(\"read_cache\");\n-\t\treturn -1;\n-\t}\n-\treturn run_diff_files(revs, options);\n-}\n-\n /*\n  * Has the work tree entity been removed?\n  *\ndiff --git a/diff-no-index.c b/diff-no-index.c\nnew file mode 100644\nindex 0000000..1b57fee\n--- /dev/null\n+++ b/diff-no-index.c\n@@ -0,0 +1,231 @@\n+/*\n+ * \"diff --no-index\" support\n+ * Copyright (c) 2007 by Johannes Schindelin\n+ * Copyright (c) 2008 by Junio C Hamano\n+ */\n+\n+#include \"cache.h\"\n+#include \"color.h\"\n+#include \"commit.h\"\n+#include \"blob.h\"\n+#include \"tag.h\"\n+#include \"diff.h\"\n+#include \"diffcore.h\"\n+#include \"revision.h\"\n+#include \"log-tree.h\"\n+#include \"builtin.h\"\n+#include \"path-list.h\"\n+\n+static int read_directory(const char *path, struct path_list *list)\n+{\n+\tDIR *dir;\n+\tstruct dirent *e;\n+\n+\tif (!(dir = opendir(path)))\n+\t\treturn error(\"Could not open directory %s\", path);\n+\n+\twhile ((e = readdir(dir)))\n+\t\tif (strcmp(\".\", e->d_name) && strcmp(\"..\", e->d_name))\n+\t\t\tpath_list_insert(e->d_name, list);\n+\n+\tclosedir(dir);\n+\treturn 0;\n+}\n+\n+static int get_mode(const char *path, int *mode)\n+{\n+\tstruct stat st;\n+\n+\tif (!path || !strcmp(path, \"/dev/null\"))\n+\t\t*mode = 0;\n+\telse if (!strcmp(path, \"-\"))\n+\t\t*mode = create_ce_mode(0666);\n+\telse if (stat(path, &st))\n+\t\treturn error(\"Could not access '%s'\", path);\n+\telse\n+\t\t*mode = st.st_mode;\n+\treturn 0;\n+}\n+\n+static int queue_diff(struct diff_options *o,\n+\t\tconst char *name1, const char *name2)\n+{\n+\tint mode1 = 0, mode2 = 0;\n+\n+\tif (get_mode(name1, &mode1) || get_mode(name2, &mode2))\n+\t\treturn -1;\n+\n+\tif (mode1 && mode2 && S_ISDIR(mode1) != S_ISDIR(mode2))\n+\t\treturn error(\"file/directory conflict: %s, %s\", name1, name2);\n+\n+\tif (S_ISDIR(mode1) || S_ISDIR(mode2)) {\n+\t\tchar buffer1[PATH_MAX], buffer2[PATH_MAX];\n+\t\tstruct path_list p1 = {NULL, 0, 0, 1}, p2 = {NULL, 0, 0, 1};\n+\t\tint len1 = 0, len2 = 0, i1, i2, ret = 0;\n+\n+\t\tif (name1 && read_directory(name1, &p1))\n+\t\t\treturn -1;\n+\t\tif (name2 && read_directory(name2, &p2)) {\n+\t\t\tpath_list_clear(&p1, 0);\n+\t\t\treturn -1;\n+\t\t}\n+\n+\t\tif (name1) {\n+\t\t\tlen1 = strlen(name1);\n+\t\t\tif (len1 > 0 && name1[len1 - 1] == '/')\n+\t\t\t\tlen1--;\n+\t\t\tmemcpy(buffer1, name1, len1);\n+\t\t\tbuffer1[len1++] = '/';\n+\t\t}\n+\n+\t\tif (name2) {\n+\t\t\tlen2 = strlen(name2);\n+\t\t\tif (len2 > 0 && name2[len2 - 1] == '/')\n+\t\t\t\tlen2--;\n+\t\t\tmemcpy(buffer2, name2, len2);\n+\t\t\tbuffer2[len2++] = '/';\n+\t\t}\n+\n+\t\tfor (i1 = i2 = 0; !ret && (i1 < p1.nr || i2 < p2.nr); ) {\n+\t\t\tconst char *n1, *n2;\n+\t\t\tint comp;\n+\n+\t\t\tif (i1 == p1.nr)\n+\t\t\t\tcomp = 1;\n+\t\t\telse if (i2 == p2.nr)\n+\t\t\t\tcomp = -1;\n+\t\t\telse\n+\t\t\t\tcomp = strcmp(p1.items[i1].path,\n+\t\t\t\t\tp2.items[i2].path);\n+\n+\t\t\tif (comp > 0)\n+\t\t\t\tn1 = NULL;\n+\t\t\telse {\n+\t\t\t\tn1 = buffer1;\n+\t\t\t\tstrncpy(buffer1 + len1, p1.items[i1++].path,\n+\t\t\t\t\t\tPATH_MAX - len1);\n+\t\t\t}\n+\n+\t\t\tif (comp < 0)\n+\t\t\t\tn2 = NULL;\n+\t\t\telse {\n+\t\t\t\tn2 = buffer2;\n+\t\t\t\tstrncpy(buffer2 + len2, p2.items[i2++].path,\n+\t\t\t\t\t\tPATH_MAX - len2);\n+\t\t\t}\n+\n+\t\t\tret = queue_diff(o, n1, n2);\n+\t\t}\n+\t\tpath_list_clear(&p1, 0);\n+\t\tpath_list_clear(&p2, 0);\n+\n+\t\treturn ret;\n+\t} else {\n+\t\tstruct diff_filespec *d1, *d2;\n+\n+\t\tif (DIFF_OPT_TST(o, REVERSE_DIFF)) {\n+\t\t\tunsigned tmp;\n+\t\t\tconst char *tmp_c;\n+\t\t\ttmp = mode1; mode1 = mode2; mode2 = tmp;\n+\t\t\ttmp_c = name1; name1 = name2; name2 = tmp_c;\n+\t\t}\n+\n+\t\tif (!name1)\n+\t\t\tname1 = \"/dev/null\";\n+\t\tif (!name2)\n+\t\t\tname2 = \"/dev/null\";\n+\t\td1 = alloc_filespec(name1);\n+\t\td2 = alloc_filespec(name2);\n+\t\tfill_filespec(d1, null_sha1, mode1);\n+\t\tfill_filespec(d2, null_sha1, mode2);\n+\n+\t\tdiff_queue(&diff_queued_diff, d1, d2);\n+\t\treturn 0;\n+\t}\n+}\n+\n+void diff_no_index(struct rev_info *revs,\n+\t\t   int argc, const char **argv,\n+\t\t   int nongit, const char *prefix)\n+{\n+\tint i;\n+\tint no_index = 0;\n+\tunsigned options = 0;\n+\n+\t/* Were we asked to do --no-index explicitly? */\n+\tfor (i = 1; i < argc; i++) {\n+\t\tif (!strcmp(argv[i], \"--\"))\n+\t\t\treturn;\n+\t\tif (!strcmp(argv[i], \"--no-index\"))\n+\t\t\tno_index = 1;\n+\t\tif (argv[i][0] != '-')\n+\t\t\tbreak;\n+\t}\n+\n+\t/*\n+\t * No explicit --no-index, but \"git diff --opts A B\" outside\n+\t * a git repository is a cute hack to support.\n+\t */\n+\tif (!no_index && !nongit)\n+\t\treturn;\n+\n+\tif (argc != i + 2)\n+\t\tdie(\"git diff %s takes two paths\",\n+\t\t    no_index ? \"--no-index\" : \"[--no-index]\");\n+\n+\tdiff_setup(&revs->diffopt);\n+\tif (!revs->diffopt.output_format)\n+\t\trevs->diffopt.output_format = DIFF_FORMAT_PATCH;\n+\tfor (i = 1; i < argc - 2; ) {\n+\t\tint j;\n+\t\tif (!strcmp(argv[i], \"--no-index\"))\n+\t\t\ti++;\n+\t\telse if (!strcmp(argv[1], \"-q\"))\n+\t\t\toptions |= DIFF_SILENT_ON_REMOVED;\n+\t\telse {\n+\t\t\tj = diff_opt_parse(&revs->diffopt, argv + i, argc - i);\n+\t\t\tif (!j)\n+\t\t\t\tdie(\"invalid diff option/value: %s\", argv[i]);\n+\t\t\ti += j;\n+\t\t}\n+\t}\n+\n+\tif (prefix) {\n+\t\tint len = strlen(prefix);\n+\n+\t\trevs->diffopt.paths = xcalloc(2, sizeof(char*));\n+\t\tfor (i = 0; i < 2; i++) {\n+\t\t\tconst char *p = argv[argc - 2 + i];\n+\t\t\t/*\n+\t\t\t * stdin should be spelled as '-'; if you have\n+\t\t\t * path that is '-', spell it as ./-.\n+\t\t\t */\n+\t\t\tp = (strcmp(p, \"-\")\n+\t\t\t     ? xstrdup(prefix_filename(prefix, len, p))\n+\t\t\t     : p);\n+\t\t\trevs->diffopt.paths[i] = p;\n+\t\t}\n+\t}\n+\telse\n+\t\trevs->diffopt.paths = argv + argc - 2;\n+\trevs->diffopt.nr_paths = 2;\n+\n+\tDIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);\n+\tDIFF_OPT_SET(&revs->diffopt, NO_INDEX);\n+\n+\trevs->max_count = -2;\n+\tif (diff_setup_done(&revs->diffopt) < 0)\n+\t\tdie(\"diff_setup_done failed\");\n+\n+\tif (queue_diff(&revs->diffopt, revs->diffopt.paths[0],\n+\t\t       revs->diffopt.paths[1]))\n+\t\texit(1);\n+\tdiffcore_std(&revs->diffopt);\n+\tdiff_flush(&revs->diffopt);\n+\n+\t/*\n+\t * The return code for --no-index imitates diff(1):\n+\t * 0 = no changes, 1 = changes, else error\n+\t */\n+\texit(revs->diffopt.found_changes);\n+}\ndiff --git a/diff.h b/diff.h\nindex 3a02d38..e019730 100644\n--- a/diff.h\n+++ b/diff.h\n@@ -250,10 +250,6 @@ extern const char *diff_unique_abbrev(const unsigned char *, int);\n /* report racily-clean paths as modified */\n #define DIFF_RACY_IS_MODIFIED 02\n extern int run_diff_files(struct rev_info *revs, unsigned int option);\n-extern int setup_diff_no_index(struct rev_info *revs,\n-\t\tint argc, const char ** argv, int nongit, const char *prefix);\n-extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv);\n-\n extern int run_diff_index(struct rev_info *revs, int cached);\n \n extern int do_diff_cache(const unsigned char *, struct diff_options *);\n@@ -261,4 +257,6 @@ extern int diff_flush_patch_id(struct diff_options *, unsigned char *);\n \n extern int diff_result_code(struct diff_options *, int);\n \n+extern void diff_no_index(struct rev_info *, int, const char **, int, const char *);\n+\n #endif /* DIFF_H */\ndiff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh\nindex 4c038cc..9337b81 100755\n--- a/t/t4013-diff-various.sh\n+++ b/t/t4013-diff-various.sh\n@@ -257,6 +257,7 @@ diff --patch-with-raw initial..side\n diff --patch-with-stat -r initial..side\n diff --patch-with-raw -r initial..side\n diff --name-status dir2 dir\n+diff --no-index --name-status dir2 dir\n EOF\n \n test_done\ndiff --git a/t/t4013/diff.diff_--name-status_dir2_dir b/t/t4013/diff.diff_--name-status_dir2_dir\nindex ef7fdb7..d0d96aa 100644\n--- a/t/t4013/diff.diff_--name-status_dir2_dir\n+++ b/t/t4013/diff.diff_--name-status_dir2_dir\n@@ -1,3 +1,2 @@\n $ git diff --name-status dir2 dir\n-A\tdir/sub\n $\ndiff --git a/t/t4013/diff.diff_--no-index_--name-status_dir2_dir b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir\nnew file mode 100644\nindex 0000000..6a47584\n--- /dev/null\n+++ b/t/t4013/diff.diff_--no-index_--name-status_dir2_dir\n@@ -0,0 +1,3 @@\n+$ git diff --no-index --name-status dir2 dir\n+A\tdir/sub\n+$\n-- \n1.5.5.1.540.g57780\n"}]}