{"thread":{"id":"25127","subject":"Trouble using --word-diff results","startedAt":"2010-09-17T07:19:52Z","lastAt":"2010-09-17T07:19:52Z","messageCount":1,"participants":["Wincent Colaiuta"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"150869","messageId":"A5062D09-2D2B-4F46-B813-71483325012A@wincent.com","threadId":"25127","inReplyTo":null,"subject":"Trouble using --word-diff results","fromName":"Wincent Colaiuta","fromEmail":"win@wincent.com","sentAt":"2010-09-17T07:19:52Z","receivedAt":"2010-09-17T07:19:52Z","isPatch":false,"sender":{"key":"greg@hurrell.net","avatar":"https://avatars.githubusercontent.com/u/7074?v=4"},"body":"Hi,\n\nI've been working with the output of \"git diff --word-diff\" and am seeing some unexpected results which at first I thought might be a bug, but now I am beginning to wonder if --word-diff is actually useful at all for the purposes of scripting.\n\nI noticed this specifically with the --word-diff=porcelain format, which I thought would be helpful to produce output colorized diff output like that which you can see here:\n\n  http://github.com/git/git/commit/c2e0940b44ded03f0af02be95c35b231fea633c1\n  http://qt.gitorious.org/+qt-developers/qt/staging/commit/45851a64ead74748d6b5045066545ee2c95d83f6\n\nie. normal unified diff style, but with darker background coloring within each added or removed line to draw attention to the specific parts of the line that were modified.\n\nSo, I tried to achieve this using --word-diff=porcelain format and got some unexpected results. But the problem can be demonstrated using the standard --word-diff=plain format as well, so I'll use that here seeing as it is a little easier to read.\n\nGiven a normal diff like this:\n\n  -a, b, c, d\n  +b, a, c, d\n\nWith --word-diff we get:\n\n  [-a,-]b, {+a,+} c, d\n\nNote how there is no whitespace between the removed \"a\" and the \"b\", and in the \"pre\" version of the file (where there is no \"a\" between the \"b\" and the \"c\") there will effectively be too much whitespace. Reconstructing the above in order to give us a colorized diff will yield:\n\n  -a,b,  c, d\n  +b, a, c, d\n\nUsing HTML-like tags to show where the color tags would be inserted:\n\n  -<red>a,</red>b,  c, d\n  +b, <green>a,</green>, c, d\n\nSo we get the desired coloring, but our whitespace is wrong in the \"pre\" line, and right in the \"post\" line. The problem is information about the whitespace is lost and can't be reconstructed from the output. This kind of whitespace damage doesn't happen in all cases, but in this particular example of moving something within a line, the damage occurs.\n\nLike I said, at first I thought this was a bug, but on reading the \"git diff\" man page I see:\n\n  \"Every non-overlapping match of the <regex> is considered a word. Anything between these matches is considered whitespace and ignored(!) for the purposes of finding differences. You may want to append |[^[:space:]] to your regular expression to make sure that it matches all non-whitespace characters. A match that contains a newline is silently truncated(!) at the newline.\"\n\nIt seems from that that some whitespace information loss is expected. So now I'm wondering if --word-diff, and particularly --word-diff=porcelain, is actually useful for consumption by a script. \n\nIf the output were:\n\n  [-a, -]b, {+a, +}c, d\n\nThen I could colorize like this with no whitespace damage:\n\n  -<red>a, </red>b, c, d\n  +b, <green>a, </green> c, d\n\nAnd I could optionally add a post-processing pass in my script to massage the exact positioning of those color tags to not highlight those trailing spaces:\n\n  -<red>a,</red> b, c, d\n  +b, <green>a,</green> c, d\n\nIs what I'm talking about here possibly using \"--word-diff=porcelain\"? For now I am working with normal diffs and rolling my own intra-line colorization from scratch.\n\nCheers,\nWincent"}]}