Every time I accidentally git commit --amend instead of a normal git commit I have to google git reset --soft HEAD@{1} to save the day.
Imagine you have a file called foo.txt and your Git history looked like this:
A -> B -> C (HEAD)
Let's see each commit we made:
A == foo
B == FOO
C == Foo
The following examples explain the different reset flags:
git reset --soft B == move HEAD to B but keep C's changes staged (i.e. added to the index)
git reset --mixed B == move HEAD to B but keep C's changes unstaged (--mixed is the DEFAULT)
git reset --hard B == move HEAD to B but completely delete C (you've lost those changes forever)
NOTE: If you accidentally
git commit --amendtheHEAD, then you can undo that usinggit reset --soft HEAD@{1}. The--softmeans the changes you made are kept staged (ready for an actualgit commit) while theHEAD@{1}means setHEADto what it was before the accidental--amend. This meansHEAD@{1}is NOT the same thing asHEAD~1, which gives you the commit that is the parent node of the commit thatHEADis currently pointing to. The referenceHEAD@{1}is actually able to get back what we want because what it references is actually sourced fromgit reflog, which if you rungit reflogyou'll see the output shows an index for each recorded change.
If you want to clean up a PRs commits, then run:
git reset origin/main
Then your changes will still exist, but will just be unstaged (as --mixed is the default behaviour). You can now git add --patch cleanly.