Consider this scenario (this may or may not have happened to me 👀) - You check out a tag to do a prod release. The release is done and all looks good on prod. Now, you start working on a bug fix that’s been bothering your team for a while. After 4 hours and 200 LOC – it’s finally fixed. You commit your changes. Then you switch to a different branch to work on another feature. Git throws some warning, but that's just git being git 🤷, so you just ignore it. 2 hours later you want to create a pull request for the bug fix but can’t find the commit anywhere. Cue panic!
What happened here?
When you checkout a tag, you’re in a detached HEAD state.
You are in a 'detached HEAD' state. You can look around, make experimental
changes, commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.
If you want to create a new branch to retain the commits you create, you may
do so (now or later) by using -c with the switch command. Example:
git switch -c <new-branch-name>
Or undo this operation with:
git switch -
HEAD is a reference to your current position in the repo. When HEAD points to a branch, you’re in an attached HEAD state.
When HEAD points directly to a commit, you’re in a detached HEAD state.
When you commit in this state, your commits don’t belong to any branch. When you switch away from this detached head state, Git shows a warning asking you to create a branch to retain your commits.
Warning: you are leaving 1 commit behind, not connected to
any of your branches:
9f45edc dummy commit
If you want to keep it by creating a new branch, this may be a good time
to do so with:
git branch <new-branch-name> 9f45edc
If you don’t do that, your commits will not be part of any branch.
There are many ways to end up in a similar situation where you made some commits and you can’t find them at some later point. E.g. you made commits in a detached HEAD state and then forgot to create a branch, you did a git reset – hard origin/ and then realized that there were some commits that you wanted to keep, etc.
So are these commits lost forever? Nope. git reflog to the rescue.
What is Git reflog?
From the official docs:
Reference logs, or "reflogs", record when the tips of branches and other
references were updated in the local repository.
You can think of Git reflog as an audit log of everything that you do (to the HEAD reference) in Git like commit changes, switch branches, etc. You can recover almost anything you do in git using reflog with some caveats.
- Reflog is periodically trimmed so you might not be able to recover very old commits
- Reflog is local only so you’ll not be able to recover someone else’s commits from the origin
Now let’s take a look at how to recover lost commits using reflog
Find the commit using the git reflog command. Copy the commit hash from here once you’ve identified the commit you want to recover.
Cherry-pick that commit and add it to a branch using git cherry-pick
And just like that, you've recovered your lost work and saved hours that you would've spent redoing it!
Top comments (0)