| English | 中文 |
Before attempting recovery, first answer three questions:
Different answers require completely different handling methods.
| Current State | What to Do First | Recommended Handling | What to Avoid |
|---|---|---|---|
| Code not yet committed | git status, and if necessary git stash push -u |
Use git restore, git stash, or manually move files to preserve the current state |
Direct git reset --hard |
| Committed, not yet pushed | git log --oneline -5, git reflog -10 |
Can use reset, commit --amend, rebase -i to clean up local history |
Cleaning up without leaving a backup branch |
| Pushed, but no one is developing based on it | First confirm remote branch and team status | Prioritize git revert; if history must be rewritten, communicate first then push --force-with-lease |
Direct push --force |
| Pushed, and someone is developing based on it | First notify collaborators, confirm scope of impact | Use a new commit to fix, prioritize revert for public branches |
Rewriting public history |
| Secret has been committed | Immediately revoke and rotate secret | Then clean up Git history and platform cache | Ending with just a revert |
| Force push overwrote remote | Find someone who still has the correct commits or local reflog | Restore remote branch with correct commit | Continuing to stack commits on the wrong branch |
If you are unsure which category you belong to, execute only read-only commands first:
git status
git log --oneline --decorate -10
git reflog -10
git branch -vv
Do not rush to execute commands that alter the working tree or history.
Capture the current state first:
git status
git log --oneline --decorate -10
git reflog -10
If the working tree still has uncommitted code, temporarily save it first:
git stash push -u -m "backup-before-recovery"
You made a commit on main that originally belonged in a feature branch.
git status
git log --oneline -5
git branch feat/right-branch
git reset --hard HEAD~1
git switch feat/right-branch
This will preserve the current commit in a new branch and revert the original branch to its pre-commit state.
If already pushed, prioritize creating a new PR to fix it; do not directly rewrite public branch history.
You can:
git switch -c feat/right-branch <commit-sha>
git push -u origin feat/right-branch
Then undo it on the original branch using revert:
git revert <commit-sha>
git reflog
Find the position before the reset:
git reset --hard HEAD@{1}
If unsure, first create a backup branch:
git branch backup-before-recover HEAD@{1}
git reflog
git branch recovered-work <commit-sha>
git switch recovered-work
As long as the commit is still in the reflog, it can usually be recovered.
You can amend the history after confirming with the team:
git revert <commit-sha>
Prioritize using revert because it does not rewrite public history.
Do not just revert.
First revoke and rotate keys, then clean up history, see Remove Secret from History.
git reflog
git log --oneline --decorate -10
Have colleagues who still retain the old commits execute:
git log --oneline origin/main -10
git reflog -10
After finding the correct commit:
git push origin <good-sha>:main
If the branch is protected, it requires handling by an administrator or platform owner.
git log --oneline --merges -10
git revert -m 1 <merge-commit-sha>
-m 1 indicates keeping the perspective of the first parent branch, undoing the changes brought by the merged branch.
Do not carelessly run reset --hard on a main branch that has already been pushed and is being used by others.
Immediately revoke and rotate the secret.
Git history cleanup cannot make an already leaked token secure again.
Use git filter-repo or a secure processing flow provided by the platform.
See Remove Secret from History.
git rebase --abort
git status
git add <files>
git rebase --continue
git reflog
git reset --hard <before-rebase-sha>
For public commits, prioritize using:
git revert <commit-sha>
This adds a reverse commit, keeping history clear and collaborators safe.
git status
git clean -nd
git clean -fd
git restore <file>
git reset --hard
Confirm there are no local changes you need to preserve before executing.
| State | Priority Plan |
|---|---|
| Not committed | git stash or git restore |
| Committed, not pushed | reset, commit --amend, interactive rebase |
| Pushed, no one developing based on it | Can rewrite history after negotiation |
| Pushed, someone developing based on it | Prioritize git revert |
| Committed a secret | First rotate keys, then clean up history |