This is why I have started to commit at the end of the work on the component I'm working on. This means I could do changes without the head-ache of correcting previous commit.
In my opinion, this can be a big mistake if you are working in a team. It's a particularly big mistake when one works part time on task A, part time on task B, part time on task C, etc. (my life), while the rest of the team is blazing away. You're likely to get conflicts galore on trying to merge your work into the overall project if you wait a few weeks or longer to ensure your code works perfectly. (Aside: Your code is never perfect.)
It's much better to commit locally extremely often and merge the larger work into your branch somewhat frequently. On a fast-moving project, I commit several times a day and merge once per day, minimum. Frequent merges mean that you can go talk to the person who wrote the code that broke your code and perhaps come to an agreement. Infrequent merges mean that those changes that broke your code are most likely locked in stone.
My first commit with regard to some task is typically pseudo code that compiles (the pseudo code is almost all comments) but that fails every test. When I leave project A to work on project B, I'll commit and merge. When I come back to project A, the first thing I do is to pull the development branch into my local repo and then merge that into my feature branch. As a result I rarely see conflicts.
A lot of code means a lot of bugs.
That's not necessarily true. What is true is that a lot of untested, unreviewed, and sloppily written code means a lot of bugs. That might be okay if what you're writing is code where errors don't have much of a cost (but that also means it doesn't have much value). If you're writing software where errors can cost millions of dollars or even worse can kill, you simply do not want to do that. There are techniques, some old, some very new, that let one write code that is mostly error-free.