Should checkins be small steps or complete features? Should checkins be small steps or complete features? git git

Should checkins be small steps or complete features?


So what's a developer to do? checkin small steps or complete features?

It's possible to get the best of both worlds, especially with git and other DVCSs that let you be selective about which history to publish. Here's a simple workflow that illustrates this.

  • Your project has master and release branches. Developers each maintain their own develop branches that they don't push.

  • You use develop to do your day-to-day work. Bite-sized commits appear here, representing incremental advances in the state of the project over time. You might make topic-* branches for working on longer features that span more than a few days or major refactorings. You commit to develop very frequently, perhaps several times an hour. It's like hitting "Save" in a document that you're editing.

  • When you have some commits that are suitable for the next release, you merge the relevant commits to release. release now has a bunch of individual commits that have selectively been taken from your develop branch. You commit to release whenever you reach a good stopping point. That's usually a few times a day.

  • When the release is ready to go, your lead developer squashes all the commits since the last merge to master into a single merge commit that appears on master. Then you tag this commit with the release identifier (e.g., v.1.0.4). This happens infrequently, perhaps once an iteration or every few weeks.

Here, you get to have your cake and eat it too. Prior to releasing, you can rollback changes that shouldn't have happened or that you don't want to go into the release, and you can do it one at a time. Developer-friendly! But users get what they want, too: big, globby commits on master that represent what's changed since the last release.


The beauty of DVCS systems is that you can have both, because in a DVCS unlike a CVCS, publishing is orthogonal to committing. In a CVCS, every commit is automatically published, but it in a DVCS, commits are only published when they are pushed.

So, commit small steps, but only publish working features.

If you are worried about polluting your history, then you can rewrite it. You might have heard that rewriting history is evil, but that is not true: only rewriting published history is evil, but again, since publishing and committing are different, you can rewrite your unpublished history before publishing it.

This is how Linux development works, for example. Linus Torvalds is very concerned with keeping the history clean. In one of the very early e-mails about Git, he said that the published history should look not like you actually developed it, but how you would have developed it, if you were omniscient, could see into the future and never made any mistakes.

Now, Linux is a little bit special: it has commits going in at a rate of 1 commit every 11 minutes for 24 hours a day, 7 days a week, 365 days a year, including nights, weekends, holidays and natural disasters. And that rate is still increasing. Just imagine how much more commits there would be if every single typo and brainfart would result in a commit, too.

But the developers themselves in their private repositories commit however often they want.


Small steps. There's a reason it's called revision control, and not release control :)

Commit as often as you like. Don't hold back. There should never be negative consequences to committing code on an "in progress" branch. Development shops that expect commits not to "break the build" are misusing the RCS. Likewise, ascribing any meaning whatsoever to a commit is dangerous policy, simply because it conflicts with the purpose of revision control. Meaning should instead be ascribed to tags, branches, clones, stashes, or whatever your RCS calls them. These things have meta data (perhaps as minimal as a name) designed to convey the purpose. Revisions are simply a history of what you modified.

The last thing you want to do is institute a policy to discourage developers from committing their code, for any reason.