Agreed with interactive rebase, but what of reflog? I've checked that for commit hashes when things have gone very wrong but I don't know many commands.
It allows you to observe and interact with the history of refs like HEAD, so superficially destructive operations like amending a commit can be recovered, reverted, etc. It's kind of like meta-git, allowing version control operations on the version control system. It's a lifesaver when you botch a merge or something and allows you to do "destructive" operations fearlessly (up to a point, you can munge a git repo pretty bad if you try hard enough).
Interactive rebase is something I use a lot, but I should look into improving its ergonomics; sometimes I just want to apply the current changes to a previous commit. I did have a shortcut / script the one time but it was very finnicky and fragile.
https://github.com/mystor/git-revise is great for just this. Of course there's also `git commit --fixup=<commit>` and `git rebase --autosquash` if you don't want to install extra software. But the ergonomics of `git revise` are better.
I've also tried git-absorb before. It was buggy at least back then. Uninstalled when it crashed and lost my changes, and even reflog didn't help.