I've been working primarily in public, shared repositories for almost 25 years with open source projects that have used cvs, svn, and git. A big step is to let go of the fear that you might be embarrassed by what you commit. That is partly about managing your own anxieties and partly about developing a culture that supports people and recognizes nobody is perfect. Still, there is a real part where you learn from mistakes and get better at making low-embarrassment commits over time. A team has to expect this when onboarding newer participants and mentor and support appropriately.

A second, equally important step is to adopt tools and methods which allow the appropriate amount of build and test for your team. If you insist on full continuous-integration and an always-working master branch, you had better make sure people can run build-and-test cycles from a working copy, prior to any commit. On the other hand, if you have focused on automated build-and-test being driven by commits, you had better adopt an appropriate branch and merge strategy to tolerate the fact that untested things are going to be committed as a regular event!

With git, I think the disconnect people have is that you should not be rebasing or amending history that you have already shared. Someone following along in a shared repo should never have the rug pulled out from them, putting their own tools into a broken state. I would much rather see an uglier commit history than feel like I am being gaslit by transient errors and here-today, gone-tomorrow commits. Depending on your exact tools, sharing might mean pushes to the central repo or everything in your own self-hosted repo that you allow others to see, even read-only.

If using a sharing model like github, that means you could feel free to rebase or amend only the batch of changes since your last push to upstream. Nobody looks at your own local clone of the repo. Every push should monotonically move the history forward in a way that all observers will see the same way. I wouldn't care if you amended commits before you pushed them, since I could never see the earlier drafts. I also would not care if there are some buggy commits in your personal working branch, as long as you address them with further commits before attempting a pull request or other merge to a shared integration branch. But, I should never be able to pull twice in any available branch and face a bizarre merge-conflict because you amended something in between my pulls.

Also, many teams can benefit from earlier sharing to avoid different private efforts from diverging too far and creating larger integration headaches or dead ends. Seeing individual commits that expose developer thought process can also help with communicating new ideas or identifying potential problems. Large rebases can interfere with this. Some organizations also will find it easier to do disaster mitigation if they know that all work products are pushed regularly (e.g. daily) to a shared repository, rather than having to worry about many distributed repos holding sole copies of new work. Such shared, periodic snapshots put an upper bound on how much work product you might be able to amend/rebase without sharing.