HALP!
If you've just lost some work in Git, and you're trying to recover your lost commits, this page is for you. Maybe you tried a rebase, or got lost in a bunch of merge conflicts, and Git didn't do what you thought it was going to do, and now you can't see the commit that holds your last several hours worth of work.
Don't Panic.
Odds are, you didn't do anything exotic. Your commit is probably still sitting there on disk, but you just can't see it.
Figure out where you are right now
I'm going to assume you're on a branch. You can confirm this by typing git status
in your repo. The very first line should say "On branch master" (or "On branch very-important-branch" or whatever the name of the branch you're on is). If not, please make a backup of your directory before proceeding and try to get some expert help! I can't cover all the possibilities in a document like this, and I'd hate to lead you further astray at this point.
If the second line doesn't say "nothing to commit (working directory clean)", you have some unsaved changes. You might be able to save them by using 'git stash', or you might want to copy some files out somewhere else if you're really paranoid. Or, you just may not care...
If you were in the middle of a rebase and something weird happened, you may be able to just type git rebase --abort
and get back to a known-good state. First, though, just try scrolling back in your history; Git will print a message telling you what to do every time it stops during a rebase.
If you tried a merge and got stuck resolving nasty merge conflicts, git status
may include a message like "Unmerged paths:" followed by a list of files. If you just want to back out of the merge, you can probably use git reset
to get back. If you're really sure you don't need any of the current working state (i.e., you started the merge from a clean working state), git reset --hard
may be what you want.
If you did a merge and it appears to have worked successfully, but now you want to undo it, just use git reset --hard [SHA]
to point your branch back at the commit it was on right before you did the merge. (You should be able to see this in the output from git log
, or your visualizer, but if not, read on.)
Finding your lost commit
Whatever branch you're on, here's the good news: Git keeps track of every commit that that branch has ever pointed to. It does this in what's called the 'reflog' (that's short for "reference log") for your branch, which lives in the following plain-text file: [repository-root]/.git/logs/refs/heads/[branch-name]. The reflog for the master branch is in .git/logs/refs/heads/master, and the reflog for very-important-branch is in .git/logs/refs/heads/very-important-branch, and so on.
So. Take a deep breath, go to the root of your repository at the command line, and type this: cat .git/logs/refs/heads/master
You should see a bunch of lines of the form:
[old SHA1] [new SHA1] [Author] [Timestamp] [Commit message]
The newest lines are at the bottom. From here, you should be able to find the line containing the commit message for the commit that you'd really really like to get back. The second column in that line is the SHA1 that you want. Highlight that sucker and copy it to your clipboard.
Getting your work back
This is going to be a bit anticlimactic, but here's what you do:
git checkout deadbeef # where 'deadbeef' is the SHA1 you just found and copied
git branch i_want_this_code_back
If you're using a visualizer like GitX or gitk, switch back over to it and refresh its view. (You may also need to tell it to display all local branches.) Or, do git log --pretty=oneline --abbrev-commit --branches=* --graph --decorate
if you're old school. Your commit should be visible again, with an 'i_want_this_code_back' branch next to it.
Wrapping up
I hope this has been helpful. Either way, please drop me a line via email or Twitter and let me know if there are ways I can improve this guide.
Once your heart rate slows down a bit, you may want to take a look around this site. The whole thing shouldn't take more than an hour to read through, but if you're in a hurry, check out the TL;DR page.
Elsewhere on the Internets, check out The Illustrated Guide to Recovering Lost Commits With Git when you have half an hour to work through the examples.
Happy hacking!
-Sam
- About This Site
- Git Makes More Sense When You Understand X
- Example 1: Kent Beck
- Example 2: Git for Ages 4 and Up
- Example 3: Homeomorphic Endofunctors
- Example 4: LSD and Chainsaws
- The Internet Talks Back!
- Graph Theory
- Seven Bridges of Königsberg
- Places To Go, and Ways to Get There
- Nodes and Edges
- Attaching Labels to Nodes
- Attaching Labels to Edges
- Directed Versus Undirected Graphs
- Reachability
- Graphs and Git
- Visualizing Your Git Repository
- References
- The Reference Reference
- Making Sense of the Display
- Garbage Collection
- Experimenting With Git
- References Make Commits Reachable
- My Humble Beginnings
- Branches as Savepoints
- Use Your Targeting Computer, Luke
- Testing Out Merges
- Rebase From the Ground Up
- Cherry-Picking Explained
- Using 'git cherry-pick' to Simulate 'git rebase'
- A Helpful Mnemonic for 'git rebase' Arguments
- The End