Is it ever going to help anyone to `git blame` a line of a file and see a commit message like "Whoops, fixed a typo!"? No. But you can't avoid those types of commits.
What you can do is prevent those commits from going into the released history of the product. We develop all new features in feature branches (made _very_ easy with the commandline tool we built for it) and only after code review and acceptance testing do we squash merge it to master.
This lets us put together all of the commits, typo commits, WIP commits and whatever else into a combined commit that contains all of the changes that make up that feature. We even enforce a special syntax on the commit so when you look back in the history, you can trace it back to the code review and to the actual ticket that requested the work.
This means we keep all of our dirty backup commits until release time when we throw them all away in favor of the squashed commit. It makes git blame on any line of any file a sexy experience that provides accountability and an easy way to figure out why the code is the way it is.
Our commandline tool automates a lot of this for us. It's biggest benefit is the tie in with github (and this week bitbucket) to create pull requests and the "deliver" command that handles squash merging and providing the structure for the final commit.
It's all open source and available here: http://github.com/reenhanced/gitreflow/
Do you merge master into feature branches between the time the feature branch is first pushed to the remote and when they are reviewed and ready to merge? Can your command line tool handle creating a squashed commit when master has been merged into the feature branch a few times?
Because we don't care about the commits on the feature branches, we prefer doing a regular merge, not a rebase of the feature branch, so that there's no need for force pushing at any point. We consider a force push of any kind to be unnecessarily dangerous.
The tool will handle the merge up for you, but if there are conflicts you'll have to resolve them before you can release the feature.
and how would you update a pull request branch to contain the latest master? Merge back and forth?
From the looks of it, this tool is made for the force-push flow, which doesn't suit you. See https://github.com/reenhanced/gitreflow/issues/52
It would be great if we could be perfect, but sometimes small commits to master do have to happen. All we do is make sure we subject every feature to code review and acceptance before it gets to master. If it slips through, then it's technically a new change request in our eyes
Other IDEs should offer this feature... it turns out to be quite useful in practice.
http://tewha.net/2012/01/ive-changed-my-mind-about-xcode-sna...
That's what Mercurial phases are:
It's always difficult to have these kinds of conversations in the abstract, but for me it's a slightly cumbersome distraction (unless you don't write commit messages). But if it works for you, you should certainly keep doing it. I tend to divide stuff into small chunks so never work on something for long without something that can be committed.
But that, as I said, is most usually. Sometimes, as you considered, I do write just "WIP" or "dump of current state". The second one, mostly when I already don't remember WTF was I doing here... (i.e. when I forgot to commit month ago and left some stuff on the table). The first one... I'm not sure now. But I know I sometimes do; with some guilt too; but usually the need for having that particular stuff committed is stronger than the guilt...
So, still can't really understand why anyone would want to reject it :) but that said, thanks a lot for expressing your approach. As much as it still puzzles me :)
If you're using Git or another version control that can do squash/rebase, what would be the advantage of having a separate concept of "temporary commits" or something?
In addition, git has a staging area (git add), which I use to stage intermediate steps of work.
It's a good idea to have only "clean" commits in your master branch (to allow for easy blame/bisect) but you can easily do feature branches that can remain "dirty" before squashing and merging to master.
It'd be nice to be able to mark commits as "squashable" as I went along (without actually squashing them yet), rather than finishing my feature branch and then have to go back and remember which commits were the "good" ones.
With that you can do:
git fixup HEAD~2
One of them is the "published, shared" kind; for this one, I can agree with you, that they should be self-contained and complete, especially when there many devs on the project, and/or you'd like to be able to use bisect.
The second kind, and for me actually a very important one, is more of a "local backup, dirty hacking" one. Those shouldn't probably be published (unless a private/one-guy repo), but allow for easy hacking, developing, testing, experimenting. The "commit often, whatever you have, however broken or non-ideal" approach provides safe lightweight backup, and allows for easy switching between various paths/approaches. Now, after you design stabilizes, dust settles down, and you are completing the work, you can (and probably should) eventually either just squash everything into one final feature commit (the end result will be indistinguishable to what you'd deliver if not committing in the meantime), or remodel the intermediary commits to whatever ideal shape you like them to have retroactively (with "git rebase -i", including patch editing etc.) Knowing the benefits of this approach, I don't understand why anyone would want to reject it.
edit: Also, with many small, dirty commits, it's sometimes possible to fairly quickly do stuff like carving out some subfeature into a separate branch (with judicious use of rebases, cherrypicking and some occasional small edits). Or, remove/revert commits marked earlier as DEBUG. Seems useful to me, as a means to somewhat speed up such operations and decrease the possibility of manual error at the same time.