{"thread":{"id":"12598","subject":"Parsing diff --git lines","startedAt":"2008-03-09T01:48:30Z","lastAt":"2008-03-09T20:45:15Z","messageCount":4,"participants":["Simon Fraser","Linus Torvalds","Jakub Narebski","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"71485","messageId":"F4D3B820-CCF4-4212-BF32-700EFD448143@mac.com","threadId":"12598","inReplyTo":null,"subject":"Parsing diff --git lines","fromName":"Simon Fraser","fromEmail":"smfr@mac.com","sentAt":"2008-03-09T01:48:30Z","receivedAt":"2008-03-09T01:48:30Z","isPatch":false,"sender":{"key":"smfr@mac.com","avatar":null},"body":"I'm working on a GUI for git, and I'd like to be able to provide\nsome diff navigation tools. That requires that I can find the\nfile chunks in a diff, and parse out the file names.\n\nHowever, I don't see a reliable way to identify the two files\nfrom a \"diff --git\" line. Here's a (deliberately pathological)\nexample:\n\ndiff --git a/a / b/file with spaces.txt b/a / b/file with spaces.txt\n\nIn this case, the repository contains directories called \"a \" and\n\" b\" and the file names have spaces in.\n\nWhat would make this possible would be either to always quote\nfile paths containing spaces, or use a character other than\na space (e.g. a \\t) between the two file names.\n\nThanks\nSimon\n\n"},{"id":"71490","messageId":"alpine.LFD.1.00.0803081955110.5896@woody.linux-foundation.org","threadId":"12598","inReplyTo":"F4D3B820-CCF4-4212-BF32-700EFD448143@mac.com","subject":"Re: Parsing diff --git lines","fromName":"Linus Torvalds","fromEmail":"torvalds@linux-foundation.org","sentAt":"2008-03-09T04:04:28Z","receivedAt":"2008-03-09T04:04:28Z","isPatch":false,"sender":{"key":"torvalds@linux-foundation.org","avatar":"https://avatars.githubusercontent.com/u/1024025?v=4"},"body":"\n\nOn Sat, 8 Mar 2008, Simon Fraser wrote:\n> \n> However, I don't see a reliable way to identify the two files\n> from a \"diff --git\" line. Here's a (deliberately pathological)\n> example:\n\nSee how \"git-apply\" does it.\n\nThe rule is:\n\n - if the filenames are different, you should ignore the filenames on the \n   \"diff --git\" line, and trust the ones on the \"renamed from/to\" ones \n   (which are unambiguous because they only have one filename per line)\n\n - if the filenames aren't different, then you can unambiguously know how \n   to parse it by simply making sure they are the same.\n\nSo to take your example:\n\n> diff --git a/a / b/file with spaces.txt b/a / b/file with spaces.txt\n\nHere, you can *know* that the filename is \"a / b/file with spaces.txt\", \nbecause it must match the pattern \"a/$filename b/$filename\", and no other \nsplit at a space would ever do that!\n\nSee in particular \"git_header_name()\" in builtin-apply.c. See the comments \nboth at the top of the function and there in the middle to reflect the \nabove rule:\n\n/*\n * This is to extract the same name that appears on \"diff --git\"\n * line.  We do not find and return anything if it is a rename\n * patch, and it is OK because we will find the name elsewhere.\n * We need to reliably find name only when it is mode-change only,\n * creation or deletion of an empty file.  In any of these cases,\n * both sides are the same name under a/ and b/ respectively.\n */\n...\n        /*\n         * Accept a name only if it shows up twice, exactly the same\n         * form.\n         */\n\n> What would make this possible would be either to always quote\n> file paths containing spaces, or use a character other than\n> a space (e.g. a \\t) between the two file names.\n\nWell, git didn't originally ever quote filenames at all, and I actually \nwanted the \"diff --git\" line to look as much like a regular \"diff -urN\" \nline as possible (which has spaces between the names)\n\nThese days, we could quote, but hey, anybody who parses diff lines needs \nto be able to handle the non-quoted form *anyway*, so quoting doesn't \nreally help anybody in the end.\n\n\t\t\tLinus\n"},{"id":"71493","messageId":"m3r6ekfgnw.fsf@localhost.localdomain","threadId":"12598","inReplyTo":"alpine.LFD.1.00.0803081955110.5896@woody.linux-foundation.org","subject":"Re: Parsing diff --git lines","fromName":"Jakub Narebski","fromEmail":"jnareb@gmail.com","sentAt":"2008-03-09T08:25:06Z","receivedAt":"2008-03-09T08:25:06Z","isPatch":false,"sender":{"key":"jnareb@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2706?v=4"},"body":"Linus Torvalds <torvalds@linux-foundation.org> writes:\n\n> On Sat, 8 Mar 2008, Simon Fraser wrote:\n> > \n> > However, I don't see a reliable way to identify the two files\n> > from a \"diff --git\" line. Here's a (deliberately pathological)\n> > example:\n> \n> See how \"git-apply\" does it.\n> \n> The rule is:\n> \n>  - if the filenames are different, you should ignore the filenames on the \n>    \"diff --git\" line, and trust the ones on the \"renamed from/to\" ones \n>    (which are unambiguous because they only have one filename per line)\n> \n>  - if the filenames aren't different, then you can unambiguously know how \n>    to parse it by simply making sure they are the same.\n\nBy the way, the default pre-commit hook behaves a bit strangely on\nfiles which contain spaces[*1*] in filename (due to GNU-diff-uism):\n\n*\n* You have some suspicious patch lines:\n*\n* In  b\n* trailing whitespace (line 1)\n b:1:++ b/ b\t\n\nFoootnote:\n==========\n[*1*] If file has '\"', '\\' or control character in filename,\n      it is quoted. \n-- \nJakub Narebski\nPoland\nShadeHawk on #git\n"},{"id":"71524","messageId":"alpine.LSU.1.00.0803092144150.3975@racer.site","threadId":"12598","inReplyTo":"m3r6ekfgnw.fsf@localhost.localdomain","subject":"Re: Parsing diff --git lines","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2008-03-09T20:45:15Z","receivedAt":"2008-03-09T20:45:15Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Sun, 9 Mar 2008, Jakub Narebski wrote:\n\n> Foootnote:\n\nAlternatively, you can write \"Bigfootnote\" or \"Sasquatchnote\".\n\nCiao,\nDscho\n"}]}