{"thread":{"id":"24289","subject":"[BUG] Spurious leading '/' in filename in \"git diff --raw --relative=<subdirectory>\"","startedAt":"2010-07-05T08:15:23Z","lastAt":"2010-08-09T14:59:56Z","messageCount":10,"participants":["Jakub Narebski","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"144801","messageId":"201007051015.26995.jnareb@gmail.com","threadId":"24289","inReplyTo":null,"subject":"[BUG] Spurious leading '/' in filename in \"git diff --raw --relative=<subdirectory>\"","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-07-05T08:15:23Z","receivedAt":"2010-07-05T08:15:23Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"I wanted to get non-recursive raw diff (difftree), but for a given\nsubdirectory and not starting from root.  \n\nI have found '--relative[=<path>]', introduced in \n\n  c0cb4a0 (diff --relative: help working in a bare repository, 2008-02-13)\n  cd676a5 (diff --relative: output paths as relative to the current subdirectory, 2008-02-12)\n\nBut when examining it's output in 'raw' mode, I have notice spurious\nleading '/' in filename:\n\n  $ git diff-tree --abbrev -r --raw HEAD --relative=sub\n  a3a8425fe5496c61921010cb1e7b455a1f52bb86\n  :100644 100644 d90bda0... cefcae0... M\t/quux\n\nThe output without '-r' (recurse into sub-trees) is even more strange\n\n  $ git diff-tree --abbrev --raw HEAD --relative=sub\n  a3a8425fe5496c61921010cb1e7b455a1f52bb86\n  :040000 040000 e62aa6e... b5d4a43... M\t\n\n(that's a trailing TAB, and no filename).\n\nWhat I expected was the following output:\n\n  $ git diff-tree --abbrev --raw HEAD --relative=sub\n  a3a8425fe5496c61921010cb1e7b455a1f52bb86\n  :040000 040000 e62aa6e... b5d4a43... M\tquux\n\n\nI see that the '--relative' and '--relative=<path>' options were introduced\nfor patch ('-p') format, and not for difftree / raw format, but I think\nthey should work for it, too.\n\n\nP.S. I have noticed this bug when working on proof-of-concept tree-blame\n(i.e. when given file was modified) in Perl.\n-- \nJakub Narebski\nPoland\n"},{"id":"144826","messageId":"201007051744.54266.jnareb@gmail.com","threadId":"24289","inReplyTo":"201007051015.26995.jnareb@gmail.com","subject":"Re: [BUG] Spurious leading '/' in filename in \"git diff --raw --relative=<subdirectory>\"","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-07-05T15:44:50Z","receivedAt":"2010-07-05T15:44:50Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Jakub Narebski wrote:\n\n> The output without '-r' (recurse into sub-trees) is even more strange\n> \n>   $ git diff-tree --abbrev --raw HEAD --relative=sub\n>   a3a8425fe5496c61921010cb1e7b455a1f52bb86\n>   :040000 040000 e62aa6e... b5d4a43... M\t\n> \n> (that's a trailing TAB, and no filename).\n> \n> What I expected was the following output:\n> \n>   $ git diff-tree --abbrev --raw HEAD --relative=sub\n>   a3a8425fe5496c61921010cb1e7b455a1f52bb86\n>   :040000 040000 e62aa6e... b5d4a43... M\tquux\n\nIf I change directory to 'sub', and use '--relative', it works\ncorrectly with '-r' (and doesn't show any output without '-r'):\n\n    $ ( cd sub &&  git diff-tree --abbrev -r --raw HEAD --relative )\n    a3a8425fe5496c61921010cb1e7b455a1f52bb86\n    :100644 100644 d90bda0... cefcae0... M\tquux\n\n-- \nJakub Narebski\nPoland\n"},{"id":"145109","messageId":"201007081300.18712.jnareb@gmail.com","threadId":"24289","inReplyTo":"201007051744.54266.jnareb@gmail.com","subject":"[BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-07-08T11:00:17Z","receivedAt":"2010-07-08T11:00:17Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"I wanted to get non-recursive raw diff (difftree), but for a given\nsubdirectory and not starting from root.\n\nIn February 2008 Junio C Hamano added support for --relative and \n--relative=<path> options to git-diff:\n* cd676a5 (diff --relative: output paths as relative\n           to the current subdirectory, 2008-02-12)\n* c0cb4a0 (diff --relative: help working in a bare repository,\n           2008-02-13)\n\n>From the commit message for cd676a5 (the c0cb4a0 just allows the \n--relative option to say which subdirectory to pretend to be in,\ni.e. adds the --relative=<path> version) it looks like this option\nwas intended for patch (-p) output format.\n\nThere was added support also for raw output format, so both \n'git diff-tree' and 'git diff --raw' works with --relative option,\nbut support for this is buggy, and in my opinion wrong way around.\n\n\nThe '--relative[=<path>]' option works currently like this.  First,\nif git command is invoked in subdirectory the diffopts structure\ngets set prefix and prefix_length (in init_revisions).  If \n--relative[=<path>] option is passed, git sets RELATIVE_NAME flag,\nand if there is argument, prefix is set to it.  Later git removes\nprefix (sets it to NULL) if RELATIVE_NAME option is not set.\n\nWhat's important in this step is that prefix is set without any \nnormalization from --relative=<path> argument, while (from what\nI understand) if it is set from current directory i.e. with --relative \noption without argument, it is set with trailing slash.  So using\n--relative=sub instead of --relative=sub/ might be thought as user\nerror... but I think here it is lack of robustness in the API.\n\n\nThen comes the filtering part.  In functions such as diff_change\nor stuff_change, if path(s) does not begin with prefix, they are\nsimply skipped.  This solution limits --relative[=<path>] to work\nonly with *recursive* (full tree) output, such as patch output format,\nor \"git diff\", or \"git diff-tree -r\" (and \"git diff-tree -t\", which\nimplies \"-r\").\n\n\nLast there is filename munging, done using strip_prefix function.\nThis is done using prefix_length only, and that is the cause of\nthe bug:\n  $ git diff-tree --abbrev -r --raw HEAD --relative=sub\n  a3a8425fe5496c61921010cb1e7b455a1f52bb86\n  :100644 100644 d90bda0... cefcae0... M\t/quux\n\nif one uses '--relative=sub' instead of '--relative=sub/'.\n\n\nWhat I'd like to see for the raw output format is to work with \n--relative[=<path>] to work as if <path> was top directory of \nrepository.  For example for diff between two trees\n\n  $ git diff-tree A B --relative=sub/\n\nwould be equivalent to running\n\n  $ git diff-tree A:sub/ B:sub/\n\n*This* could be done, I think, by modifying diff_tree_sha1 to do a diff \nbetweem A:sub/ and B:sub/ (taking 'sub/' from prefix) and unsetting \nprefix (setting prefix to NULL and prefix_length to 0).  But that would \nwork only in the case that can be reducted to diff between two tree \nobjects.  This wouldn't work for diff in raw output format between tree \nand working area, tree and index, or index and working area.\n\nIs the idea of automagically translating <sha1> into <sha1>:<prefix>\nto support --relative / relative=<prefix> well in raw diff output format\na good idea?  Or should I search for another solution.\n\nI also do not know code enough (and it is not simple) to guess how\none would go with the same result for diff between trees, index, and\nworking area files.\n\nBTW. the approach proposed here has the advantage that for B:<sub>,\nif <sub> does not exist in B, we can try to do what 'subtree' merge \nstrategy does (and what wholesame directory rename detection did),\nnamely try to find given directory under different path (like for \nexample subtree-merged git-gui and gitk).\n\n-- \nJakub Narebski\nPoland\n"},{"id":"145116","messageId":"20100708114125.GA2427@sigill.intra.peff.net","threadId":"24289","inReplyTo":"201007081300.18712.jnareb@gmail.com","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-07-08T11:41:25Z","receivedAt":"2010-07-08T11:41:25Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jul 08, 2010 at 01:00:17PM +0200, Jakub Narebski wrote:\n\n> Last there is filename munging, done using strip_prefix function.\n> This is done using prefix_length only, and that is the cause of\n> the bug:\n>   $ git diff-tree --abbrev -r --raw HEAD --relative=sub\n>   a3a8425fe5496c61921010cb1e7b455a1f52bb86\n>   :100644 100644 d90bda0... cefcae0... M\t/quux\n> \n> if one uses '--relative=sub' instead of '--relative=sub/'.\n\nIs that a bug or a feature? You need to say \"sub/\" to get what you want,\nwhich is annoying. But it means you can also you \"--relative=su\" to get\n\"b/quux\". In that example, it's probably useless, but consider a set of\nfilenames \"foo-1\" through \"foo-5\". You don't always want to break on a\ndirectory boundary.\n\nI believe \"git-archive --prefix\" has the same behavior for the same\nreason.\n\n-Peff\n"},{"id":"145118","messageId":"201007081411.14843.jnareb@gmail.com","threadId":"24289","inReplyTo":"20100708114125.GA2427@sigill.intra.peff.net","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-07-08T12:11:13Z","receivedAt":"2010-07-08T12:11:13Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 8 Jul 2010, Jeff King wrote:\n> On Thu, Jul 08, 2010 at 01:00:17PM +0200, Jakub Narebski wrote:\n> \n> > Last there is filename munging, done using strip_prefix function.\n> > This is done using prefix_length only, and that is the cause of\n> > the bug:\n> >   $ git diff-tree --abbrev -r --raw HEAD --relative=sub\n> >   a3a8425fe5496c61921010cb1e7b455a1f52bb86\n> >   :100644 100644 d90bda0... cefcae0... M\t/quux\n> > \n> > if one uses '--relative=sub' instead of '--relative=sub/'.\n> \n> Is that a bug or a feature? You need to say \"sub/\" to get what you want,\n> which is annoying. But it means you can also you \"--relative=su\" to get\n> \"b/quux\". In that example, it's probably useless, but consider a set of\n> filenames \"foo-1\" through \"foo-5\". You don't always want to break on a\n> directory boundary.\n> \n> I believe \"git-archive --prefix\" has the same behavior for the same\n> reason.\n\nIt is called --relative=<path>, *not* --relative=<prefix>.  I also\nthink that it was meant to be the opposite of --directory=<root> of\ngit-am and git-apply.\n\n\"git archive --prefix\" is IMVHO a bit of horse of different color.\n\nNevertheless in current situation it would be good to have the\nfollowing applied.\n-- >8 --\ndiff --git i/Documentation/diff-options.txt w/Documentation/diff-options.txt\nindex 2371262..bc837cd 100644\n--- i/Documentation/diff-options.txt\n+++ w/Documentation/diff-options.txt\n@@ -278,7 +278,7 @@ ifndef::git-format-patch[]\n \tSwap two inputs; that is, show differences from index or\n \ton-disk file to tree contents.\n \n---relative[=<path>]::\n+--relative[=<path>/]::\n \tWhen run from a subdirectory of the project, it can be\n \ttold to exclude changes outside the directory and show\n \tpathnames relative to it with this option.  When you are\n-- 8< --\n\n-- \nJakub Narebski\nPoland\n"},{"id":"145119","messageId":"201007081419.42702.jnareb@gmail.com","threadId":"24289","inReplyTo":"20100708114125.GA2427@sigill.intra.peff.net","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-07-08T12:19:42Z","receivedAt":"2010-07-08T12:19:42Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 8 Jul 2010, Jeff King wrote:\n> On Thu, Jul 08, 2010 at 01:00:17PM +0200, Jakub Narebski wrote:\n> \n> > Last there is filename munging, done using strip_prefix function.\n> > This is done using prefix_length only, and that is the cause of\n> > the bug:\n> >   $ git diff-tree --abbrev -r --raw HEAD --relative=sub\n> >   a3a8425fe5496c61921010cb1e7b455a1f52bb86\n> >   :100644 100644 d90bda0... cefcae0... M\t/quux\n> > \n> > if one uses '--relative=sub' instead of '--relative=sub/'.\n> \n> Is that a bug or a feature? You need to say \"sub/\" to get what you want,\n> which is annoying. But it means you can also you \"--relative=su\" to get\n> \"b/quux\". In that example, it's probably useless, but consider a set of\n> filenames \"foo-1\" through \"foo-5\". You don't always want to break on a\n> directory boundary.\n> \n> I believe \"git-archive --prefix\" has the same behavior for the same\n> reason.\n\nNevertheless for the patch output format both \"git diff --relative=sub\"\nand \"git diff --relative=sub/\" give the same output, without 'b//quux'.\nThe same IMHO should be done for raw output format, so we don't have\n'/quux' but 'quux'.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"145128","messageId":"20100708142341.GA9991@coredump.intra.peff.net","threadId":"24289","inReplyTo":"201007081419.42702.jnareb@gmail.com","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-07-08T14:23:41Z","receivedAt":"2010-07-08T14:23:41Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jul 08, 2010 at 02:19:42PM +0200, Jakub Narebski wrote:\n\n> Nevertheless for the patch output format both \"git diff --relative=sub\"\n> and \"git diff --relative=sub/\" give the same output, without 'b//quux'.\n> The same IMHO should be done for raw output format, so we don't have\n> '/quux' but 'quux'.\n\nHmm. That is because the diff output properly eliminates the double \"/\".\nBut AFAICT, all of the following do what I would expect:\n\n  git diff --relative=sub\n  git diff --relative=sub/ ;# same as above\n  git diff --relative=foo- ;# yields \"a/10\" for file \"foo-10\"\n\nDoing\n\n  git diff --relative=sub --stat\n\nshows the same issue as your --raw version, as does --name-only. I think\nthe right solution is to clean up a leading \"/\" for those cases. That\nleaves the possibility for non-directory prefixes, but should do what\nthe user wants in the directory case (since a leading \"/\" is\nnonsensical).\n\nOr was that what you had in mind the whole time? My impression was that\nyou wanted --relative=foo to always be equivalent to --relative=foo/.\nThe subtle difference is that I want the \"/\" removed only if it is the\nnext character (or another way of thinking about it is to append \"/\" to\nthe prefix only if it is an actual directory).\n\n-Peff\n"},{"id":"145132","messageId":"201007081656.23474.jnareb@gmail.com","threadId":"24289","inReplyTo":"20100708142341.GA9991@coredump.intra.peff.net","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2010-07-08T14:56:20Z","receivedAt":"2010-07-08T14:56:20Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"On Thu, 8 Jul 2010, Jeff King wrote:\n> On Thu, Jul 08, 2010 at 02:19:42PM +0200, Jakub Narebski wrote:\n> \n> > Nevertheless for the patch output format both \"git diff --relative=sub\"\n> > and \"git diff --relative=sub/\" give the same output, without 'b//quux'.\n> > The same IMHO should be done for raw output format, so we don't have\n> > '/quux' but 'quux'.\n> \n> Hmm. That is because the diff output properly eliminates the double \"/\".\n> But AFAICT, all of the following do what I would expect:\n> \n>   git diff --relative=sub\n>   git diff --relative=sub/ ;# same as above\n>   git diff --relative=foo- ;# yields \"a/10\" for file \"foo-10\"\n> \n> Doing\n> \n>   git diff --relative=sub --stat\n> \n> shows the same issue as your --raw version, as does --name-only. I think\n> the right solution is to clean up a leading \"/\" for those cases. That\n> leaves the possibility for non-directory prefixes, but should do what\n> the user wants in the directory case (since a leading \"/\" is\n> nonsensical).\n\nPerhaps this would be enough:\n\n-- >8 --\ndiff --git i/diff.c w/diff.c\nindex 3aa695d..3a4696e 100644\n--- i/diff.c\n+++ w/diff.c\n@@ -2705,10 +2705,16 @@ static void diff_fill_sha1_info(struct diff_filespec *one)\n static void strip_prefix(int prefix_length, const char **namep, const char **otherp)\n {\n \t/* Strip the prefix but do not molest /dev/null and absolute paths */\n-\tif (*namep && **namep != '/')\n+\tif (*namep && **namep != '/') {\n \t\t*namep += prefix_length;\n-\tif (*otherp && **otherp != '/')\n+\t\tif (**namep == '/')\n+\t\t\t++*namep;\n+\t}\n+\tif (*otherp && **otherp != '/') {\n \t\t*otherp += prefix_length;\n+\t\tif (**otherp == '/')\n+\t\t\t++*otherp;\n+\t}\n }\n \n static void run_diff(struct diff_filepair *p, struct diff_options *o)\n-- 8< --\n\n> \n> Or was that what you had in mind the whole time? My impression was that\n> you wanted --relative=foo to always be equivalent to --relative=foo/.\n> The subtle difference is that I want the \"/\" removed only if it is the\n> next character (or another way of thinking about it is to append \"/\" to\n> the prefix only if it is an actual directory).\n\nWhat I wanted is for \"git diff-tree A B --relative=sub\" to behave as\n\"git diff-tree A:sub B:sub\".  Currently without -r / -t (without turning\non recursive mode) it produces no output; well at least no output if\n'sub' is really subdirectory.\n\nWhat's more I wanted for \"git diff --raw\" in any combination to behave\nthe same... although I guess here point is moot, as \"git diff\" is\nautomatically recursive regardless of output format, and you can't turn\nit off.\n\nStil I'd like for \"git diff-tree <commit>\" to behave appropriately\nwith --relative or --relative=<path>.\n\n-- \nJakub Narebski\nPoland\n"},{"id":"147503","messageId":"20100809145053.GA3438@sigill","threadId":"24289","inReplyTo":"201007081656.23474.jnareb@gmail.com","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-08-09T14:50:53Z","receivedAt":"2010-08-09T14:50:53Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"[Sorry for the long delay in responding. I was moving and am just now\n clearing my backlog of mail.]\n\nOn Thu, Jul 08, 2010 at 04:56:20PM +0200, Jakub Narebski wrote:\n\n> > Hmm. That is because the diff output properly eliminates the double \"/\".\n> > But AFAICT, all of the following do what I would expect:\n> > \n> >   git diff --relative=sub\n> >   git diff --relative=sub/ ;# same as above\n> >   git diff --relative=foo- ;# yields \"a/10\" for file \"foo-10\"\n> > \n> > Doing\n> > \n> >   git diff --relative=sub --stat\n> > \n> > shows the same issue as your --raw version, as does --name-only. I think\n> > the right solution is to clean up a leading \"/\" for those cases. That\n> > leaves the possibility for non-directory prefixes, but should do what\n> > the user wants in the directory case (since a leading \"/\" is\n> > nonsensical).\n> \n> Perhaps this would be enough:\n\nI think your patch is the right solution. Here it is with a commit\nmessage and some tests.\n\n-- >8 --\nFrom: Jakub Narebski <jnareb@gmail.com>\nSubject: [PATCH] diff: strip extra \"/\" when stripping prefix\n\nThere are two ways a user might want to use \"diff\n--relative\":\n\n  1. For a file in a directory, like \"subdir/file\", the user\n     can use \"--relative=subdir/\" to strip the directory.\n\n  2. To strip part of a filename, like \"foo-10\", they can\n     use \"--relative=foo-\".\n\nWe currently handle both of those situations. However, if\nthe user passes \"--relative=subdir\" (without the trailing\nslash), we produce inconsistent results. For the unified\ndiff format, we collapse the double-slash of \"a//file\"\ncorrectly into \"a/file\". But for other formats (raw, stat,\nname-status), we end up with \"/file\".\n\nWe can do what the user means here and strip the extra \"/\"\n(and only a slash).  We are not hurting any existing users\nof (2) above with this behavior change because the existing\noutput for this case was nonsensical.\n\nPatch by Jakub, tests and commit message by Jeff King.\n\nSigned-off-by: Jeff King <peff@peff.net>\n---\n diff.c                   |   10 ++++++-\n t/t4045-diff-relative.sh |   61 ++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 69 insertions(+), 2 deletions(-)\n create mode 100755 t/t4045-diff-relative.sh\n\ndiff --git a/diff.c b/diff.c\nindex 782896d..bf65892 100644\n--- a/diff.c\n+++ b/diff.c\n@@ -2704,10 +2704,16 @@ static void diff_fill_sha1_info(struct diff_filespec *one)\n static void strip_prefix(int prefix_length, const char **namep, const char **otherp)\n {\n \t/* Strip the prefix but do not molest /dev/null and absolute paths */\n-\tif (*namep && **namep != '/')\n+\tif (*namep && **namep != '/') {\n \t\t*namep += prefix_length;\n-\tif (*otherp && **otherp != '/')\n+\t\tif (**namep == '/')\n+\t\t\t++*namep;\n+\t}\n+\tif (*otherp && **otherp != '/') {\n \t\t*otherp += prefix_length;\n+\t\tif (**otherp == '/')\n+\t\t\t++*otherp;\n+\t}\n }\n \n static void run_diff(struct diff_filepair *p, struct diff_options *o)\ndiff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh\nnew file mode 100755\nindex 0000000..8a3c63b\n--- /dev/null\n+++ b/t/t4045-diff-relative.sh\n@@ -0,0 +1,61 @@\n+#!/bin/sh\n+\n+test_description='diff --relative tests'\n+. ./test-lib.sh\n+\n+test_expect_success 'setup' '\n+\tgit commit --allow-empty -m empty &&\n+\techo content >file1 &&\n+\tmkdir subdir &&\n+\techo other content >subdir/file2 &&\n+\tgit add . &&\n+\tgit commit -m one\n+'\n+\n+check_diff() {\n+expect=$1; shift\n+cat >expected <<EOF\n+diff --git a/$expect b/$expect\n+new file mode 100644\n+index 0000000..25c05ef\n+--- /dev/null\n++++ b/$expect\n+@@ -0,0 +1 @@\n++other content\n+EOF\n+test_expect_success \"-p $*\" \"\n+\tgit diff -p $* HEAD^ >actual &&\n+\ttest_cmp expected actual\n+\"\n+}\n+\n+check_stat() {\n+expect=$1; shift\n+cat >expected <<EOF\n+ $expect |    1 +\n+ 1 files changed, 1 insertions(+), 0 deletions(-)\n+EOF\n+test_expect_success \"--stat $*\" \"\n+\tgit diff --stat $* HEAD^ >actual &&\n+\ttest_cmp expected actual\n+\"\n+}\n+\n+check_raw() {\n+expect=$1; shift\n+cat >expected <<EOF\n+:000000 100644 0000000000000000000000000000000000000000 25c05ef3639d2d270e7fe765a67668f098092bc5 A\t$expect\n+EOF\n+test_expect_success \"--raw $*\" \"\n+\tgit diff --no-abbrev --raw $* HEAD^ >actual &&\n+\ttest_cmp expected actual\n+\"\n+}\n+\n+for type in diff stat raw; do\n+\tcheck_$type file2 --relative=subdir/\n+\tcheck_$type file2 --relative=subdir\n+\tcheck_$type dir/file2 --relative=sub\n+done\n+\n+test_done\n-- \n1.7.2.1.63.g6ffaf\n"},{"id":"147504","messageId":"20100809145956.GB3438@sigill","threadId":"24289","inReplyTo":"201007081656.23474.jnareb@gmail.com","subject":"Re: [BUG/RFC] Raw diff output format (git-diff-tree) and --relative[=<path>] option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2010-08-09T14:59:56Z","receivedAt":"2010-08-09T14:59:56Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jul 08, 2010 at 04:56:20PM +0200, Jakub Narebski wrote:\n\n> > Or was that what you had in mind the whole time? My impression was that\n> > you wanted --relative=foo to always be equivalent to --relative=foo/.\n> > The subtle difference is that I want the \"/\" removed only if it is the\n> > next character (or another way of thinking about it is to append \"/\" to\n> > the prefix only if it is an actual directory).\n> \n> What I wanted is for \"git diff-tree A B --relative=sub\" to behave as\n> \"git diff-tree A:sub B:sub\".  Currently without -r / -t (without turning\n> on recursive mode) it produces no output; well at least no output if\n> 'sub' is really subdirectory.\n\nI think this is a separate issue from the extra slash problem. I don't\nthink it would hurt anything to enable \"-r\" automatically in diff-tree,\nbut _only_ if we know that the prefix we stripped ended in \"/\". Since\nthat is just changing a case that is already nonsensical, whereas\nturning on recursion for \"git diff-tree --relative=foo- A B\" would\nactually be a change in behavior.\n\nIt should be possible, but it is a bit more surgery, since the prefix\nstripping code is pretty dumb currently.\n\n> What's more I wanted for \"git diff --raw\" in any combination to behave\n> the same... although I guess here point is moot, as \"git diff\" is\n> automatically recursive regardless of output format, and you can't turn\n> it off.\n\nYeah, I think \"git diff\" already does what you want, since 82cb8af\n(git-diff: turn on recursion by default, 2007-07-29).\n\n-Peff\n"}]}