216
votes

How often should I commit changes to source control ? After every small feature, or only for large features ?

I'm working on a project and have a long-term feature to implement. Currently, I'm committing after every chunk of work, i.e. every sub-feature implemented and bug fixed. I even commit after I've added a new chunk of tests for some feature after discovering a bug.

However, I'm concerned about this pattern. In a productive day of work I might make 10 commits. Given that I'm using Subversion, these commits affect the whole repository, so I wonder if it indeed is a good practice to make so many ?

26
Man, this question is not opinion-based, and is a totally valid question with proper answer. Committing is some sort of important skill, the idea is you have to commit a working and stable enhancement/feature/hotFix that you added in your codebase including descriptive commit messages. if it's end of the day and you want to leave you can't just commit a broken code and say you will fix it tomorrow, because it's better to use rebase alongside merge to keep the important commit and messages and squash the unnecessary ones, if you just want to keep a temporary state you have to use git stashEric
For avoiding ambiguity, if in some particular situations you needed to commit and push a not finished code, after you came back and wanted to continue that branch again, when you finished the thing you have to amend the previous incomplete commit and then push it. it's totally up to you how to keep your working tree clean and useful for retrospections but believe it or not when it comes to find and tackle very hidden or subtle bugs or poor functionalities it's a huge help if you have clean and professional working tree when you want to use git debug tools like - git blame or git bisectEric

26 Answers

209
votes

Anytime I complete a "full thought" of code that compiles and runs I check-in. This usually ends up being anywhere between 15-60 minutes. Sometimes it could be longer, but I always try to checkin if I have a lot of code changes that I wouldn't want to rewrite in case of failure. I also usually make sure my code compiles and I check-in at the end of the work day before I go home.

I wouldn't worry about making "too many" commits/check-ins. It really sucks when you have to rewrite something, and it's nice to be able to rollback in small increments just in case.

88
votes

When you say you are concerned that your "commits affect the whole repository" --- are you referring to the fact that the whole repository's revision number increases? I don't know how many bits Subversion uses to store it, but I'm pretty sure you're not going to run out of revision numbers! Many commits are not a problem. You can commit ten times as often as the guy next door and you won't increase your carbon footprint at all.

A single function or method should be named for what it does, and if the name is too long, it is doing too much. I try to apply the same rule to check-ins: the check-in comment should describe exactly what the change accomplishes, and if the comment is too long, I'm probably changing too much at once.

37
votes
25
votes

I personally commit every logical group of code that is finished/stable/compiles and try not to leave the day without committing what I did that day.

20
votes

If you are making major changes and are concerned about affecting others working on the code, you can create a new branch, and then merge back into the trunk after your changes are complete.

14
votes

If your version control comment is longer than one or two sentences, you probably aren't committing often enough.

13
votes

I follow the open-source mantra (paraphrased) - commit early, commit often.

Basically whenever I think I've added useful functionality (however small) without introducing problems for other team members.

This commit-often strategy is particularly useful in continuous integration environments as it allows integration testing against other development efforts, giving early detection of problems.

12
votes

I commit everytime I'm done with a task. That usually takes 30 mins to 1 hr.

11
votes

Don't commit code that doesn't actually work. Don't use your repository as a backup solution.

Instead, back up your incomplete code locally in an automated way. Time Machine takes care of me, and there are plenty of free programs for other platforms.

8
votes

The rule of thumb, that I use, is check-in when the group of files being checked-in can be covered by a single check-in comment.

This is generally to ensure that check-ins are atomic and that the comments can be easily digested by other developers.

It is especially true when your changes affect a configuration file (such as a spring context file or a struts config file) that has application wide scope. If you make several 'groups' of changes before checking in, their impact overlaps in the configuration file, causing the 2 groups to become merged with each other.

7
votes

I don't think you should worry so much about how often. The important thing here is what, when and why. Saying that you have to commit every 3 hours or every 24 hours really makes no sense. Commit when you have something to commit, don't if you don't.

Here's an extract from my recommended best practices for version control:

[...] If you are doing many changes to a project at the same time, split them up into logical parts and commit them in multiple sessions. This makes it much easier to track the history of individual changes, which will save you a lot of time when trying to find and fix bugs later on. For example, if you are implementing feature A, B and C and fixing bug 1, 2 and 3, that should result in a total of at least six commits, one for each feature and one for each bug. If you are working on a big feature or doing extensive refactoring, consider splitting your work up into even smaller parts, and make a commit after each part is completed. Also, when implementing independent changes to multiple logical modules, commit changes to each module separately, even if they are part of a bigger change.

Ideally, you should never leave your office with uncommitted changes on your hard drive. If you are working on projects where changes will affect other people, consider using a branch to implement your changes and merge them back into the trunk when you are done. When committing changes to libraries or projects that other projects—and thus, other people—depend on, make sure you don’t break their builds by committing code that won’t compile. However, having code that doesn’t compile is not an excuse to avoid committing. Use branches instead. [...]

6
votes

Your current pattern makes sense. Keep in mind how you use this source control: what if you have to rollback, or if you want to do a diff? The chunks you describe seem like exactly the right differential in those cases: the diff will show you exactly what changed in implementing bug #(specified in checkin log), or exactly what the new code was for implementing a feature. The rollback, similarly, will only touch one thing at a time.

6
votes

I also like to commit after I finish a chunk of work, which is often several times a day. I think it's easier to see what's happening in small commits than big ones. If you're worried about too many commits, you may consider creating a branch and merging it back to the trunk when the whole feature is finished.

Here's a related blog post: Coding Horror: Check In Early, Check In Often

4
votes

As others have stated, try to commit one logical chunk that is "complete" enough that it does not get in other devs' way (e.g., it builds and passes automated tests).

Each dev team / company must define what is "complete enough" for each branch. For example, you may have feature branches that require the code only to build, a Trunk that also requires code to pass automated tests, and labels indicating something has passed QA testing... or something like that.

I'm not saying that this is a good pattern to follow; I'm only pointing out that how done is "done" depends on your team's / company's policies.

3
votes

The moment you think about it.

(as long as what you check in is safe)

3
votes

Depends on your source code system and what else you have in place. If you're using Git, then commit whenever you finish a step. I use SVN and I like to commit when I finish a whole feature, so, every one to five hours. If I were using CVS I'd do the same.

3
votes

I agree with several of the responses: do not check in code that will not compile; use a personal branch or repository if your concern is having a "backup" of the code or its changes; check in when logical units are complete.

One other thing that I would add is that depending on your environment, the check-in rate may vary with time. For example, early in a project checking in after each functional piece of a component is complete makes sense for both safety and having a revision history (I am thinking of cases where earlier bits get refactored as later ones are being developed). Later in the project, on the other hand, entirely complete functionality becomes more important, especially during integration development/testing. A half-integration or half-fix does not help anyone.

As for checking in after each bug fix: unless the fix is trivial, absolutely! Nothing is more of a pain than finding that one check in contained three fixes and one of them needs to be rolled back. More often than not it seems that in that situation the developer fixed three bugs in one area and unwinding which change goes to which bug fix is a nightmare.

3
votes

I also like to check in regularly. That is every time I have a completed a step towards my goal.

This is typically every couple of hours.

My difficulty is finding someone willing and able to perform so many code reviews.

Our company policy is that we need to have a code review before we can check anything in, which makes sense, but there is not always someone in the department who has time to immediately perform a code review. Possible Solutions:

  1. More work per check in; less checkins == less reviews.
  2. Change the company checkin policy. If I have just done some refactoring and the unit tests all run green, maybe I can relax the rule?
  3. Shelve the change until someone can perform the review and continue working. This can be problematic if the reviewer does not like you code and you have to redesign. Juggling different stages of a task by 'shelving' changes can become messy.
2
votes

I like to commit changes every 30-60 minutes, as long as it compiles cleanly and there are no regressions in unit tests.

2
votes

Well, you could have your own branch to which you can commit as often as you like, and when you are done with your feature, you could merge it to the main trunk.

On the frequency of Commits, I think of it this way, how much pain would it be to me if my hard disk crashed and I hadn't committed something - the quantum of this something for me is about 2 hours of work.

Of course, I never commit something that doesn't compile.

2
votes

At least once a day.

2
votes

I don't have a specific time limit per commit, I tend to commit once a test has passed and I'm happy with the code. I wouldn;t commit code that does not compile or is otherwise in a state that I would not feel good about reverting to in case of failure

2
votes

You have to balance the compromise between safety and recoverability on the one hand and ease of change management for the entire project on the other.

The best scheme that I've used has had two answers to that question.

We used 2 completely separate repositories : one was the project wide repository and the other was our own personal repository (we were using rcs at the time).

We would check into our personal repository very regularly, pretty much each time you saved your open files. As such the personal repository was basically a big, long ranging, undo buffer.

Once we had a chunk of code that would compile, tested ok and was accepted as being ready for general use it was checked into the project repository.

Unfortunately this system relied on the use of different VCS technologies to be workable. I've not found any satisfactory method of achieving the same results while using two of VCS of the same type (eg. two subversion repositories)

However, I have had acceptable results by creating "personal" development branches in a subversion repository - checking into the branch regularly and then merging into the trunk upon completion.

2
votes

If you're working on a branch which won't be released, a commit is always safe.

However, if you are sharing it with other developers, committing non-working code is likely to be a bit annoying (particularly if it's in an important place). Normally I only commit code which is effectively "working" - not that it's been fully tested, but that I've ascertained that it does actually compile and not fail immediately.

If you're using an integrated bug tracker, it may be helpful to do separate commits if you've fixed two bugs, so that the commit log can go against the right bugs. But then again, sometimes one code change fixes two bugs, so then you just have to choose which one to put it against (unless your system allows one commit to be associated with multiple bugs)

2
votes

I still believe in the phrase 'commit often, commit early'. I prefer decentralized VCS like Mercurial and there's no problem to commit several things and push it upstream later.

This is really a common question, but the real question is: Can you commit unfinished code?

2
votes

Whenever you finish some code that works and won't screw anyone else up if they get it in an update.

And please make sure you comment properly.