I have to be honest in the past something like 8 years ago I have spend some amount of time thinking when was the right to commit. Then as for any topic I read around and different source, and as everything this depends of the project, like a solo one, or with a Team. Indeed for this different cases, I have 2 different approach, both based on the principle to see who is going to review the commits: in the first case me of a version of me in the future or eventually another component of the Team in the future.
But then a connection of mine wrote me:
"At the moment I'm spending more time planning out a commit than actually writing code when adding a new feature. Less than two hours would be lucky, some times I'd spend a good part of the day without writing any code. This is making me unhappy, since I don't feel I'm productive enough (I'm living with my parents, and have never been employed as a programmer)"
If I don't do this amount of planning, I just end up writing code that will have to be undone before I commit, and this just messes up my project, because don't like wasting any code I've already written and try to recycle it as much as possible (my precious).
Someone said that programming isn't about how fast you can type, it's about how fast you can think. I'm not very good at thinking fast." ( Well I am the same).
I think I'm overly cautious making my productivity not economically viable, but even still its far too easy for me to waste a whole lot of time making a mess of my codebase."
This was what he told me and I though that at his stage I even didn't had much thoughts but at lower level.
My experience is that when coding for a living, especially as a junior in a team, typically not much design work is needed. This is because you'll be working in an existing code base. Chances are, you'll often be working on a feature that is similar to existing features, so you can look at those as an example. This is nowhere near as boring as it may sound; one can is learning plenty of things, still need to understand the examples and adapt them to suit your needs.
Designing something new can indeed be much harder, but it is also much rarer, especially when you're a junior developer, or let's say when you take the challenge to develop something on the side even adapting tutorials can be.
That is to say: in a typical junior-level development job, I don't think one run into the things this person was worried about. Or at least to a far smaller extent.
Planning and coding are very much iterative processes. You plan a bit, try to create some code with the planning in mind, which makes you realize that you overlooked something during planning, so you adjust the plan, code some more, rinse, repeat.
I like to think that this is also how artists work. It's a creative journey. Often messy, sometimes boring, sometimes exhilarating, sometimes frustrating. Sometimes you end up with something boring that just works, sometimes with something beautiful that doesn't work. And, every now and then, with something that works and is beautifully elegant.
""Someone said that programming isn't about how fast you can type, it's about how fast you can think. I'm not very good at thinking fast.""
Actually neither are most people, especially if they have to do the thinking without seeing any code. Coding helps to make things concrete. It may also obfuscate the bigger picture, so zooming in (code) and out (planning) is part of the iterative process.
It's also worth noting that people, after years of professional experience, develop a kind of muscle memory for specific approaches, and an instinct for applying these. Which is half the battle when making something new. You cannot be expected to have that already (nor should you expect it from yourself).
Unfortunately the "internet" show only ready "work" as YouTubers if they would make up stuff on the spot, type it in and are done. That is not how it goes.
They planned and practiced too beforehand or they show you things they have done hundreds of times before, that are in their routine.
When you see a musician play for one minute on YouTube it is safe to assume they spent days practicing, recorded tens of takes and ultimately picked the best one. And that is not counting the years they put in to get up to their level in the first place.
Writing software is a skill like any other that takes time to develop. And different people specialize in different things. And, in your particular specialty, there will likely always be some people who can do things quicker. If you are just starting with Git, I would recommend this free resource live project from manning Getting Started with Git or / after to get even more practice for advance topic and work in a Team and feel completely confident, I would recommend this other book Git in practice Deciding when and where to optimize is another thing. It seems many people tend to be obsessively working to satisfy own compulsive need to eradicate any imperfections. This is fine in the environment how many great creators started their career. The key but not easy to put in practice is to enjoy it and learn from it while no one is asking you when it's done yet.
My general approach is that code that just works (and is readable) and that apply to code style if one is working in a Team, is good enough.
If later on, new requirements or new features means that the code is no longer good enough, you can adjust it. That adjustability is the reason the world moved away from specialized hardware and embraced software (running on generic hardware).
My approach with unfinished "Classes" or "Component" that for example still miss the part for retrieve API or that "useEffect" to implement something that has to run only after first render or after a variable change, is to "stash", so I can recall that method / approach or part, where I put some effort but on overall still not working or not working as should or as I expect, anytime I need or integrate with a branch or another approach.
Indeed I see commits are not something you plan. Commits, especially in the early stages of figuring out a problem, are little more than save-points along a journey. Instead, spend time thinking about the problem.
Break big problems into little problems, and then break those down into smaller problems. This is one of the first rule and approach are taught at university or bootcamps, or at least it should be. At least it was at University of Bologna during my Java course.
Keep decomposing and digesting problems until your mind can see a single line of code.
Write that line of code. Keep writing code as you think. Mess up. Change the code. Change it 15 more times(stash it if some part works as your expected), if need be. Stop and commit when you feel like losing that code would be a big setback, or during a natural break in your rhythm of thought and writing code.
There is no general rule or guideline. When to commit is more a feeling than some methodological practice. Basically, if you think, "it would really suck to lose this code while I figure things out," then commit what you have. Just be sure to work in your own branch so no one else has to deal with whatever state your code is in.
Don't worry about whether the code works, compiles, or looks pretty. Many version control systems allow you to combine many messy commits into one clean, cohesive changeset.
Version control is a tool just as much as a text editor. Version control just happens to be really good at backing up your work.
So in general there should not really time planning a commit.
The approach should be to write code until you feel like you have something to lose, then commit those changes so you don't.
This topic is connect on the question of how many commits to do and also has to do with the great tooling and feature that git give to developers, and that is amazing tooling set.