Git is powerful because it lets you rewrite or discard state. That also means some commands deserve a pause.
Run:
git status
git diff
git diff --staged
git log --oneline --decorate -10Ask:
- Is the work committed?
- Is the commit already pushed/shared?
- Am I trying to undo content, undo history, or merely unstage something?
- Do I know which branch I am on?
These usually preserve history or uncommitted work when used correctly:
git restore --staged <file> # unstage, keep working-tree edit
git stash # temporarily save tracked changes
git revert <commit> # make a new commit that undoes an old commit
git reflog # inspect recent HEAD/reference movementsThese are not magic. Read the command output and inspect afterward.
Pause before using:
git restore <file>
git reset --hard <commit>
git clean -fd
git push --forcegit restore <file> can permanently discard uncommitted edits. reset --hard can overwrite both the index and working tree. clean -fd removes untracked files/directories. Force-pushing can rewrite shared remote history.
If you find a commit in git reflog that you want to preserve, prefer creating a recovery branch first:
git switch -c recovery-branch <commit-hash>Now the commit has a named branch pointing to it while you inspect what happened.
Rewriting your own unpublished commits can be useful. Rewriting commits other people may already depend on requires coordination.
Do not use the simplistic rule "rebase is always dangerous." The real boundary is shared history.
When something looks wrong:
- Stop typing commands.
- Run
git status. - Inspect the graph:
git log --oneline --graph --decorate --all. - Check
git reflogif a commit seems missing. - Create a recovery branch before experimenting further.
Panic causes more damage than Git does.