The first is to keep a log of what you are working on. For me, that's lots of small and dumb commits.
The second is to provide a story for review.
Most of the time, when the change you are putting out for review is small and simple, you can just put it all into a single commit.
Sometimes, your change is more complicated and it makes sense to break it into a series of related commits. Along the line of 'first do the refactor that makes the complicated change simple, then make the simple change'.
Your job as an author is to hide the ugly reality of how you actually came up with the change, and present the reviewer a sanitised view of reality. Reviewing code is hard, so it's best to make it as easy as possible.
Why wouldn't you use a local branch (or something?) for your ugly commits and then merge everything from that branch into the main shared branch when you're done?
Because then you're going to merge in the ugly commits and make everyone who needs to look at the history in the future have to work that much harder to understand what's going on.
The first is to keep a log of what you are working on. For me, that's lots of small and dumb commits.
The second is to provide a story for review.
Most of the time, when the change you are putting out for review is small and simple, you can just put it all into a single commit.
Sometimes, your change is more complicated and it makes sense to break it into a series of related commits. Along the line of 'first do the refactor that makes the complicated change simple, then make the simple change'.
Your job as an author is to hide the ugly reality of how you actually came up with the change, and present the reviewer a sanitised view of reality. Reviewing code is hard, so it's best to make it as easy as possible.