How I Recover from Common Git Mistakes

Most Git mistakes are recoverable. The difficult part is choosing a command that fixes the right layer—working tree, staging area, commit, or branch—without deleting something else.

Before using reset --hard or clean, make a copy of work you cannot reproduce. The safer commands come first below; the destructive reset is deliberately last.

Find a commit that seems lost

git reflog records where HEAD and local branch references have pointed. I use it when a reset, rebase, or deleted branch makes a commit look lost.

git reflog
# Find the entry before the unwanted operation, then create a recovery branch.
git branch recovery HEAD@{index}

Creating a branch is safer than immediately resetting your current one. Once you have inspected recovery, you can decide whether to reset, cherry-pick, or keep it.

Add a forgotten change to the last commit

If the last commit is still local, stage the missing file and amend it:

git add path/to/file
git commit --amend --no-edit

Amending rewrites the commit. Avoid it after pushing to a branch other people may already use; a small follow-up commit is usually less disruptive there.

To change only the last commit message, run:

git commit --amend

Move a local commit off the wrong branch

Suppose the latest commit belongs on a feature branch but was made on main. First create the correct branch at the current commit, then move main back:

git branch feature-name
git reset --hard HEAD~
git switch feature-name

This assumes the working tree is clean and the commit has not been shared. If it has already reached a shared main, keep its history intact and revert it there after cherry-picking it to the right branch:

git switch feature-name
git cherry-pick <commit>
git switch main
git revert <commit>

See changes that are already staged

Plain git diff shows unstaged changes. After git add, use:

git diff --staged

I run this before committing. It shows exactly what the next commit will contain.

Undo an older shared commit

git revert creates a new commit that reverses another one, so it is usually the right choice for shared history:

git log --oneline
git revert <commit>

Review the result carefully. Reverting an old commit may conflict with later work that changed the same lines.

Restore one file from an older commit

Modern Git has a command that says exactly what it does:

git log -- path/to/file
git restore --source=<commit> -- path/to/file
git add path/to/file
git commit -m "Restore file from <commit>"

The older git checkout <commit> -- path/to/file syntax still works, but restore is clearer.

Make a local branch match its remote

This removes local commits, working-tree changes, and untracked files. I would only use it after confirming the branch name and saving anything important elsewhere.

git fetch origin
git switch main
git reset --hard origin/main
git clean -d --force

Before the final command, git clean -d -n previews what would be deleted. That one dry run can save files Git does not track and therefore cannot recover.

The pattern behind all of these fixes is simple: inspect first, preserve a reference when possible, and use destructive commands only after the target is unambiguous. Git usually keeps more recovery information than it first appears to.