Things I encourage:
Frequent local commits
This way you don't have to be bothered by changes others are making to the central repository while working on a handful of related tasks. It's a good idea to try to work on one task at a time and commit all changes at partitioned stopping points. A local commit doesn't have to build, just FYI, so a stopping point doesn't mean a build point nor a point that you can push centrally. There should be several of these in any given day. 2 hours is a good indicator that you might not be leveraging the power of frequent local commits. Once you have verified a set of changes works, save them away, otherwise run the risk of introducing bugs into it when working on the next task.
The notion of a task
By task I mean a related set of changes that can be completed in a few hours or less. In the same token don’t make your tasks so small that critically related changes aren’t grouped together. Use your intuition and the rest of these principles and I think you will find what is comfortable for you.
Sometimes one task explodes or unknowingly encompasses other tasks, at this point, try to get to a stopping point on part of the work you are doing and commit it so you can get that out of the way to focus on the remainder. This will often entail committing part of the work and continuing on the rest. Leverage Git's index (if you are using Git) to group and commit related changes while leaving the remaining work uncommitted.
Outstanding changes as a guide
If you don't commit often it might mean you are not leveraging your version control history to help guide your work. It's a great way to see what has changed and might be causing problems. The longer you wait, the more that has changed and the harder it is to test/debug what your changes are doing! This is a reason why I am so picky about my VCS tools on the client side and why I talk a lot about the quality of a diff tool and the ability to integrate that with a simple view of everything that has changed. This is why I love using TortoiseHg and SmartGit: they show changed files, a diff (or two way diff with SmartGit) of the current selected file and a commit message all in one window that I keep maximized on one monitor at all times.
Throw away / stash commits
There is extreme value in being able to throw away a commit (or stash it) that is getting out of hand. If you do not commit often you will have to isolate the work you want to commit from the work you want to throw away, which is time consuming, not fun and error prone. I find myself throwing away commits about once a week, especially when doing exploratory re-factoring. It's much easier if I can just revert all outstanding changes.
Sync with the central repository dailyThe rest of us depend on your changes. Don't let them sit on your computer longer than they have to. Waiting increases the chances of merge conflict which just decreases productivity. It also prohibits us from doing deploys when people say they are done but have not merged centrally. This should be done daily! Find a way to partition the work you are doing so that you can sync at least once daily.
Committing single files
Committing single files might indicate one waited too long and no longer understands all the changes involved. It may mean there were overlapping changes in single files that cannot be isolated. In either case, the suggestions above should help avoid this.
Committing frequently does not mean committing frequently right at the end of a day's work :)
It should be spaced out over the course of the day and several tasks.