Currently, I am comfortable enough with squashing commits in my
workflow that I can’t think of an immediate need.
When first working with squashing commits, I definitely did the wrong
thing and had to “redo” work lost to git rebase -i…
After doing research into git, I realize it is possible to recover
If you know the squashed commit you want to recover:
run: $ git show <squashed commit's SHA>, which will display the
commit details, with individual blobs (that’s the git term for a
from step 1, extract out the SHA for the change you want to recover
and run: $ git cat-file -p <file change SHA> > new_file.txt,
which will put the contents of the file change into new_file.txt
Let’s say a git repository (that has no downstreams!) has the
And to keep the repository history clean, I squash the last two
commits, bc6c & 0b70 into the feature change: ad92.
I would run the following command:
and then the log would look like:
Sweet, nice and clean, ready for PR, right?
Pushing up the branch and the continuous integration server throws an
Looks like there’s important work in a squashed commit!
Normally, I’d just redo the work and swear I would never rebase again
and force everyone to accept all my commits, even my WIP. If
anyone complains about my commits, I’d just stand my ground and not
I didn’t do that and doubled down on squashing my commits.
And today, there’s a way to recover the squashed commit.
Let’s say the important work is in the 0b70 commit. It’s squashed,
so it’s lost to the ether, right?
Well, no. git maintains all the commits, even when squashing. The
blob is still in your commit history, accessing it is just trickier.
To see all the commits, run: $ find .git/objects -type f
See, the 0b70 is still there, even when we told git to squash!
The object, 0b70 is a commit object in git, to check, run: $ git
cat-file -t <SHA>
You can’t recover a commit, but you can recover a blob… so using $
git show <commit sha> reveals:
And tada, the commit shows the file changes involved. The important
part is locating what changes are on the second_file.txt, which is
the only change in the commit.
The change to second_file.txt in this commit has SHA of:
2077dd0. Checking the git object type using $ git cat-file -t <SHA> reveals:
So, to recover the change, use: $ git cat-file -p <SHA> >
recover_file.txt, which will recover the file from the commit into
Tada! We have recovered the squashed commit’s file!
Even when a commit is squashed, it’s still recoverable as the data
is in the commit history.
Once you know the SHA of the blob you want to recover, use: $ git
cat-file -p <SHA> > recover_file.txt.
Whew, I wish I knew this when I started squashing commits. It would
have saved me rewriting work twice!