Recovering From Common Git Mistakes
Introduction¶
Git rarely destroys data. Commits you can no longer see are usually still in the object database, reachable via the reflog, until garbage collection removes unreachable objects (default: ~90 days for reachable-from-reflog, 2 weeks for truly loose). Knowing the recovery path turns a panic into a one-liner.
The reflog¶
git reflog # every position HEAD has been in, newest first
git reflog show mybranch # same for a specific branch
a1b2c3d HEAD@{0}: reset: moving to HEAD~3
e4f5g6h HEAD@{1}: commit: Add feature
...
Recover to any state:
git reset --hard HEAD@{1} # go back to where you were before the reset
# or, non-destructively:
git branch recovered e4f5g6h
Scenario recipes¶
"I committed to the wrong branch"¶
# You committed to main, meant to be on a feature branch. Nothing pushed.
git branch feature # mark the current commit
git reset --hard HEAD~1 # move main back one (or --hard origin/main)
git switch feature # your commit is here
"I need to undo my last commit but keep the changes"¶
git reset --soft HEAD~1 # commit undone, changes staged
git reset HEAD~1 # commit undone, changes unstaged (mixed, the default)
git reset --hard HEAD~1 # commit undone, changes GONE (reflog still has them)
"I need to undo a commit that's already pushed / shared"¶
git revert <sha> # creates a NEW commit that inverts <sha>. Safe for shared history.
git revert -m 1 <merge-sha> # revert a merge commit (keep parent 1)
Don't reset + force-push a shared branch; revert is the shared-history tool.
"I deleted a branch"¶
git reflog | grep <branch-name> # find its last commit
# or:
git fsck --lost-found # dangling commits
git branch <branch-name> <sha>
"git stash pop had a conflict / I dropped a stash"¶
git fsck --no-reflog | awk '/dangling commit/ {print $3}' | \
xargs -n1 git log --oneline -1 # find the stash commit
git stash apply <sha>
"I amended a commit and lost the original"¶
git reflog # HEAD@{1} is pre-amend
git reset --hard HEAD@{1}
"My working directory changes vanished (never committed)"¶
If they were never git added, Git never saw them — not recoverable via Git.
If git added then lost (a bad checkout/reset --hard), dangling blobs may
exist:
git fsck --lost-found
ls .git/lost-found/other/ # blobs; inspect with git cat-file -p
Prevention: git stash before risky operations.
"I committed a secret"¶
# If NOT pushed and it's the last commit:
git rm --cached secrets.env
git commit --amend
echo "secrets.env" >> .gitignore
# If it's deeper in history or pushed — rewrite history:
git filter-repo --path secrets.env --invert-paths # (git-filter-repo, not filter-branch)
git push --force-with-lease
Rotate the secret regardless. Once pushed, assume it's compromised — history rewrites don't reach forks, caches, or anyone who already cloned.
Verification and troubleshooting¶
git status
git log --oneline --graph --all
git reflog
git fsck --full --no-reflog
reset --hardand the reflog entry is already gone — very recent GC, orgit gc --prune=nowwas run. Trygit fsck --lost-found.filter-repo"not a fresh clone" warning — it wants a clean mirror; heed it or pass--force, and re-clone elsewhere afterwards.- Force-push rejected — use
--force-with-lease; if it still refuses, someone pushed after you — fetch and reconcile first. - Recovered a commit but it's detached HEAD —
git branch <name>to keep it, otherwise the next GC reclaims it. - Team member's clone still has the secret after your history rewrite — they must re-clone or hard-reset their branches to the rewritten remote. And the secret is still burned — rotate it.
Related tools and reading¶
- On-site: Git command reference.
- Related posts: Git rebase vs merge, Handling secrets in CI without leaking them.
Stuck on something this site can't fix?Reach out to Prabath directly on LinkedIn.More in DevOps & CI/CD
OpenTelemetry for Distributed Tracing
A trace follows one request across services. OpenTelemetry is the vendor-neutral way to produce them — here's the model, the Collector, and sampling that won't bankrupt you.
October 24, 2026pre-commit Hooks That Actually Help
pre-commit runs checks before a commit lands, catching formatting, secrets, and syntax errors locally. Here's a config that helps without being annoying.
October 24, 2026Chaos Engineering Basics
Chaos engineering is controlled experiments that inject failure to verify your system tolerates it. Here's the method, safe blast radius, starter experiments, and game days.
October 24, 2026