Squashing combines multiple commits into one. Manual way: rebase -i, change pick to squash (keeps message) or fixup (discards).
Autosquash is the magic. When you spot a bug in commit abc123:
git commit --fixup=abc123 -am "actual fix"
Later, before pushing:
git rebase -i --autosquash HEAD~10
Git automatically reorders your fixup! commits next to their targets and marks them as fixup. One keystroke (save the editor) and you're done.
Set it as default behavior:
git config --global rebase.autosquash true
Pair with commit --fixup while reviewing your own PR — your final history reads as if you got it right the first time.
Autosquash rides on the interactive editor, so it cannot run in this terminal. The squash itself can, with no rebase at all: git reset --soft HEAD~3 puts the last three commits' changes back in the index, and one git commit replaces all three.