Whenever you get into an undesirable state, you usually want to undo whatever you just did. Sometimes it's very easy, e.g. if you created an object, to undo that you just delete the object. Sometimes git explicitly tells you what to do, e.g. if you are in the middle of a merge and you want to cancel it, it tells you to run `git merge --abort`. Sometimes it's not quite as easy, but still straightforward to google what to do, e.g. if you merged or committed to a branch, you just have to look up (or remember) the command to manually set what commit a branch points to.
However, in my experience the most difficult "weird state" to get out of is when you do something that removes/rewrites history. For example: deleting branches, rebasing, squashing, or accidentally getting rid of a reference while attempting to solve some other problem. The root issue is that you want to find a commit that seems like it no longer exists. If you rebase, the branch now points to a new commit that has ansestors you don't want, but the old commit is gone. The "secret" is that all commits that ever existed still exist, you just can't find them in `git log` because the pointers to them are gone. `git reflog` helps solve this by giving you a list of all commits that HEAD has ever pointed to.
git checkout cool-branch # HEAD points to commit abc123
git rebase main # HEAD and cool-branch point to commit def456, but you realize you don't want that rebase
git reflog # reflog tells you that the commit you were just on is abc123
git reset --hard abc123 # HEAD and cool-branch now point to abc123. You've Ctrl+Z'd the rebase
I just copy paste this and put it in my "break glass in case of emergency" folder. I have many snippets there. This is a good one. I usually refer to the log but reflog is really the "undo" for anything.
However, in my experience the most difficult "weird state" to get out of is when you do something that removes/rewrites history. For example: deleting branches, rebasing, squashing, or accidentally getting rid of a reference while attempting to solve some other problem. The root issue is that you want to find a commit that seems like it no longer exists. If you rebase, the branch now points to a new commit that has ansestors you don't want, but the old commit is gone. The "secret" is that all commits that ever existed still exist, you just can't find them in `git log` because the pointers to them are gone. `git reflog` helps solve this by giving you a list of all commits that HEAD has ever pointed to.