From a useless Git Diff to a useful one
coderwall.com
coderwall.com
You should make two different commits, changing indentation and changing a feature are different changes and should be tracked independently.
Oh and another cool feature is worddiffs for when you're editing text.
Now doing a code format to tweak indenting and brace positioning, etc., that should definitely be put into a separate commit.
??? No it's not
The better solution would be to teach people to stop being careless about trailing whitespace in their commits.
We have these awesomely powerful systems, with this awesomely powerful software, that oftentimes I'm depressed by people doing things by hand. Heck, if I was really not willing to deal with whitespace retards, I'd just make a hook on the server auto indent and whitespace cleanup all changes before commit.
I'd love to be wrong on this!
As usual, it comes down to trust: if you can't trust your developers to write good code or not subvert the system, you either need to educate them, or work with better developers (fire them, or quit and work somewhere better). The point at which you have to start enforcing things by machine fiat can be helpful to catch honest mistakes, but it can also be a sign of a dysfunctional team.
All that it takes is that every single user behaves exactly correctly. That's an indication of a poor design. Tools should naturally guide people to the correct usage and be moderately forgiving of minor examples of incorrect usage.
For "I wrapped these 5 lines in a conditional and adjusted the indentation per code standard" in a language like C# I disagree with you, the first commit is ugly and leaves the codebase (temporarily) out of sync with codebase style, which may fail the build or fail to submit in the first place if you enforce such things via precommit hook or build process.
For the same operation in python, where semantics changes are attached to indentation level changes, the first commit is BROKEN, WRONG, AND BAD. The build not failing the first commit reflects poorly on the unit tests.
Increasing the readability of a diff is a noble goal. Splitting the diff in 'twain can help, but it's not a full answer. Neither is keeping commits as small as possible: simple renames can easily touch 30 files at a time, to say nothing of adding parameters or more complicated refactorings which must be committed together or leaves the codebase in a broken state.
Other tools include highlighting difference within a line instead of merely at a per-line level. Ignoring whitespace changes in languages which aren't whitespace sensitive can also help: I personally find the two highlighted lines of an if statement and it's end more informative than the seven highlighted lines which include it's functionally unchanged body that's merely changed scope.
https://github.com/dmnd/git-whiteout
(Can't vouch for it; I just assumed that someone would have automated this by now so I dug around for the tool)
It tends to produce more "this looks like what I did" diffs, with code at least.
I hop back and forth between GUI-based editors and the command line. Some things are just better in a GUI, and diff is one of those things--especially any nontrivial diff.
[1] http://www.scootersoftware.com/
[2] I'm sure you can do this in vi and/or emacs as well. I leave how to do that as an exercise to the reader.
I didn't realise how spoiled I was until I started using git, and found the hard way how limiting the text diff format can be. Column-oriented changes in particular are very difficult to figure out, and even for more readable sets of changes I always found it a bit hard to get a rough idea of how spread out or clustered together the changes are. git gui and SourceTree try their best to help, but ultimately they're just displaying a prettified version of the same sometimes-unhelpful view of things.
On the other hand, if you're making small changes to a lot of files, a text diff is just the thing. It would be hyperbole to state that there's nothing worse than telling Araxis Merge to do a folder compare and find out that 1,000+ files have had 1 line changed in them - but it is rather annoying, and very time-consuming to investigate thoroughly. You need a text diff for that sort of thing.
But I still always reach for Araxis first...
Beyond Compare (linked above) lets you set patterns to ignore, which has been incredibly useful for when an autogenerated time/date stamp is changed in 1000+ files; I can say "ignore that change; tell me what changed that DOESN'T match the pattern".
You can do the same thing with grep on the command line of course. But then you lose out on all the GUI awesomeness.
I've used Araxis, and it's Even More Awesome, but 5x the cost (last I checked) as Beyond Compare, and I didn't think it was 5x as awesome. BC has gotten much cooler since then too (with comparison plug-ins, and bitmap compare -- let's see diff compare two bitmaps and tell me which pixels have changed! -- and DOC file compare, and normalized XML file compare, and so on ;).
You can also ignore whitespace when picking commits apart with hg record (akin to git add -p, I think).
That's pretty outside the scope of git diff or gnu diff, though.
gitdiff() {
git diff --patience --ignore-space-at-eol -b -w --ignore-blank-lines $1
}This one is simple enough to be defined as an alias:
alias gitdiff='git diff --patience --ignore-space-at-eol -b -w --ignore-blank-lines'
This[1] discusses aliases vs functions (just to make my reply a bit more useful [may be not for you, but in general] and to me feel less guilty.)[1] http://unix.stackexchange.com/questions/30925/in-bash-when-t...
Also, you're only accepting one argument, where there could be many depending on your refspec and path.
[alias]
df = diff --patience --ignore-space-at-eol -b -w --ignore-blank-lines