Git Recovery Guide - Fix Common Git Mistakes

Git Recovery Guide

Fix common Git mistakes and recover from disasters

Even experienced developers make Git mistakes. This guide covers common scenarios and step-by-step solutions to recover from them.

Critical Recovery Scenarios

I reset hard but need some files back Critical
Scenario
git reset --hard HEAD~3

You did a hard reset but later realized you needed changes from those commits.

Solution: Use git reflog to find the lost commits and restore files from them.

# Find the lost commits git reflog abc1234 HEAD@{0}: reset: moving to HEAD~3 def5678 HEAD@{1}: commit: Important feature ghi9012 HEAD@{2}: commit: Bug fixes # Restore files from specific commit git restore --source=def5678 path/to/important-file.txt
Example
git reset --hard HEAD~1 # Accidentally wiped new feature git reflog | grep "Add login" # Find commit hash (e.g., abc1234) git restore --source=abc1234 src/login.js # Recover the file
I pushed sensitive/accidental files Critical
Scenario
git push origin main

You pushed API keys, passwords, or other sensitive data to a remote repository.

Solution: Use git filter-repo to completely remove the file from history.

# 1. Remove file from history (install git-filter-repo first) git filter-repo --path secrets.txt --invert-paths # 2. Force push (warn your team first!) git push --force # 3. Everyone else must reclone or reset their repos git fetch origin git reset --hard origin/main
Example
# After pushing config.json with passwords: git filter-repo --path config.json --invert-paths git remote add origin <url> # Required after filter-repo git push --force
I pushed sensitive/accidental files Critical
Scenario
git push origin main

You pushed API keys, passwords, or other sensitive data to a remote repository.

Solution: Use git filter-repo to completely remove the file from history.

Use git filter-repo to safely and permanently remove sensitive files from Git history. This version includes backup, selective path removal, and team-safe practices.

# 0. Backup your repo first git clone --mirror . ../repo-backup.git # 1. Remove one or more files/folders from history git filter-repo \ --path secrets.txt \ --path passwords.json \ --invert-paths # 2. Optional: Remove files by regex pattern (e.g., all *.env files) git filter-repo --invert-paths --path-glob '*.env' # 3. Clean references and reflog (safeguard for old objects) git reflog expire --expire=now --all git gc --prune=now --aggressive # 4. Force push rewritten history to remote git push --force --all git push --force --tags # 5. Everyone else must reclone or hard-reset git fetch origin git reset --hard origin/main
Example: Remove config.json and secret.env
git filter-repo --path config.json --path secret.env --invert-paths git reflog expire --expire=now --all git gc --prune=now --aggressive git push --force --all git push --force --tags # Team members must reclone to avoid conflicts
I committed wrong files Caution
Scenario
git add .

You added everything including debug logs or files that shouldn't be committed.

Solution: Unstage the unwanted files and make a clean commit.

# Unstage specific files git restore --staged *.log git restore --staged temp.txt # Now commit only intended files git commit -m "Real changes"
Example
git reset --soft HEAD~1 # Undo commit but keep changes git restore --staged unwanted_file.txt # Unstage the file git commit -m "Clean commit" # Recommit
I need to undo a public commit Caution
Scenario
git push origin main

You pushed a commit that has bugs or issues and need to undo it.

Solution: Use git revert to create a new commit that undoes the changes.

# Revert the last commit git revert HEAD # Revert a specific commit git revert abc1234 # Push the revert git push origin main
Example
# After bad commit abc123: git revert abc123 # Creates new revert commit git push # Safe for shared branches
I lost changes after merge conflict Critical
Scenario
git merge feature

Conflict resolution went wrong and you lost important changes.

Solution: Use ORIG_HEAD to revert to pre-merge state.

# Revert to pre-merge state git reset --merge ORIG_HEAD # Alternatively, if you've done other operations since git reflog git reset --hard HEAD@{1}
Example
git merge feature # Conflicts appear # Accidentally accepted wrong changes git reset --merge ORIG_HEAD # Back to square one
I committed to wrong branch Caution
Scenario
git checkout main git commit -m "Feature X"

You made commits to the wrong branch and need to move them.

Solution: Use cherry-pick to move the commit, then reset the original branch.

# Move commit to correct branch git checkout feature git cherry-pick main # Remove from wrong branch git checkout main git reset --hard HEAD~1
Example
# Commit made on main instead of feature-branch: git branch feature-branch # Create if doesn't exist git checkout feature-branch git cherry-pick main git checkout main git reset --hard HEAD~1
I accidentally deleted a branch Caution
Scenario
git branch -D feature

You deleted a branch that hadn't been merged yet.

Solution: Use reflog to find the last commit on the deleted branch.

# Find the last commit on the deleted branch git reflog abc1234 HEAD@{0}: checkout: moving from feature to main def5678 HEAD@{1}: commit: Finalize feature # Recreate the branch git branch feature def5678
# Find the commit where the branch last existed git reflog | grep "feature" abc1234 HEAD@{2}: commit: Feature implementation # Recreate the branch from that commit git branch feature abc1234

Nuclear Scenarios

The Nuclear Reset Extreme
Scenario
git reset --hard origin/main

You lost days of uncommitted work after a hard reset.

Solution: Use git's internal file system check to find lost blobs.

# Search for lost data git fsck --lost-found # Look for blobs (file contents) git show [blob-hash] # Search for specific content git fsck --lost-found | grep "blob" | xargs -I{} sh -c 'git show {} | grep -q "unique string" && echo {}'
The Accidental API Key Leak Extreme
Scenario

You pushed API keys or credentials to a public repository.

Solution: Use filter-repo to purge the file and rotate all exposed keys.

# Purge file from all history git filter-repo --path .env --invert-paths # Force push to all branches git push --force --all # Then rotate all exposed keys immediately! # Notify anyone who cloned the repository
The Wrong Force Push Extreme
Scenario
git push --force

You force pushed and overwrote teammate's work.

Solution: Use reflog to find pre-force-push state and restore it.

# Find pre-force-push state git reflog abc1234 HEAD@{0}: push --force def5678 HEAD@{1}: pull origin main # Reset to before the force push git reset --hard HEAD@{1} # Force push again to restore git push --force
The Repository Corruption Extreme
Scenario

Your repository has become corrupted with file system errors.

Solution: Use git's built-in repair tools to attempt recovery.

# Check repository integrity git fsck --full # Attempt to repair git gc --prune=now # Reclone from remote if all else fails cd .. git clone [repository-url] new-repo cp -R new-repo/.git old-repo/
Recovering from a bad rebase Critical
Scenario
git rebase main

Your rebase went wrong and you lost commits or have conflicts you can't resolve.

Solution: Abort the rebase and restore from the original branch.

# Abort the rebase git rebase --abort # If that doesn't work, reset to original state git reflog git reset --hard ORIG_HEAD # Or restore from a backup branch if you made one git checkout -b recovered-feature backup/feature-branch
Recovering stashed changes Safe
Scenario
git stash drop

You accidentally dropped a stash that contained important changes.

Solution: Use git fsck to find dangling commits, then recover from them.

# Find dangling commits (including stashes) git fsck --unreachable | grep commit | cut -d' ' -f3 # Check each commit to see if it's your stash git show <commit-hash> # Once found, create a branch from it git branch recovered-stash <commit-hash> # Or apply it directly git merge <commit-hash>

Undo & Rewrite History

I want to undo the last commit Caution
Scenario
git commit -m "Broken feature"

You made a commit that introduced bugs and want to undo it.

Solution: Use git reset to remove the commit while keeping changes.

# Keep changes in working directory git reset --soft HEAD~1 # Discard changes completely git reset --hard HEAD~1 # If already pushed, use revert instead git revert HEAD
I want to split a commit Caution
Scenario
git commit -m "Multiple changes"

You made a commit with multiple unrelated changes and want to split it.

Solution: Use interactive rebase to edit the commit.

# Start interactive rebase git rebase -i HEAD~5 # Mark the commit to split with 'edit' # When rebase pauses at that commit: git reset HEAD~1 # Add changes incrementally and commit git add file1.txt git commit -m "First change" git add file2.txt git commit -m "Second change" # Continue the rebase git rebase --continue
I want to reorder commits Caution
Scenario

You want to change the order of commits in your history.

Solution: Use interactive rebase to reorder commits.

# Start interactive rebase git rebase -i HEAD~5 # In the editor, reorder the commit lines as desired # Save and exit - Git will replay commits in new order # Resolve any conflicts that arise git add [conflicted-files] git rebase --continue
I want to squash multiple commits Caution
Scenario

You have multiple small commits that should be combined into one.

Solution: Use interactive rebase to squash commits.

# Start interactive rebase git rebase -i HEAD~4 # Mark commits with 'squash' or 'fixup' to combine them # Save and exit, then edit the final commit message # Force push if already on remote git push --force-with-lease

Branching Issues

I want to rename a branch Safe
Scenario

You want to rename a local or remote branch.

Solution: Use git branch -m for local, and push changes for remote.

# Rename local branch git branch -m old-name new-name # Rename remote branch git push origin :old-name new-name git push origin -u new-name
I want to find when a bug was introduced Safe
Scenario

You need to identify which commit introduced a bug.

Solution: Use git bisect to perform a binary search through history.

# Start bisect session git bisect start # Mark current commit as bad git bisect bad # Mark a known good commit git bisect good abc1234 # Git will checkout middle commit - test it # Mark as good or bad, repeat until found # End bisect session git bisect reset
I want to recover a deleted file Safe
Scenario

You deleted a file and want to restore it from history.

Solution: Use git checkout to restore from a specific commit.

# Find when the file existed git log -- path/to/file # Restore from last known commit git checkout abc1234 -- path/to/file # Or restore from branch before deletion git checkout HEAD~1 -- path/to/file
I want to see changes before pulling Safe
Scenario

You want to review what changes will come in before pulling.

Solution: Use git fetch followed by git log to see incoming changes.

# Fetch remote changes without merging git fetch origin # See what's changed git log HEAD..origin/main --oneline # See actual changes git diff HEAD origin/main

Advanced Scenarios

Advanced Git Revert Techniques Caution
Scenario
git revert abc123

You need to undo changes from a specific commit but with more control.

Solution: Use advanced revert options for different scenarios.

# Revert a merge commit git revert -m 1 MERGE_COMMIT_HASH # -m 1 keeps main branch's changes # Revert a range of commits git revert OLDER_COMMIT..NEWER_COMMIT # Reverts range (excludes OLDER_COMMIT) # Revert without committing immediately git revert -n abc123 # Changes staged but not committed # Partial revert git revert -n abc123 git reset # Unstage changes if needed git add -p # Selective staging git commit -m "Partial revert"
Example
# Revert multiple commits in one go: git revert --no-commit abc123 def456 git commit -m "Revert two problematic commits" # View revert changes before committing: git revert -n abc123 && git diff --cached
Merge Conflict Resolution Caution
Scenario
git merge feature

You encounter merge conflicts that need to be resolved.

Solution: Step-by-step conflict resolution process.

# Step 1: Pull latest changes (you may see the conflict message) git pull # Step 2: Open the conflicted file, look for: # <<<<<<< HEAD # your changes # ======= # their changes # >>>>>>> branch-name # Step 3: Manually edit & resolve, remove the conflict markers. # Step 4: Add the resolved file git add file.txt # Step 5: Commit the resolution git commit -m "Resolved merge conflict in file.txt"
Non-Fast-Forward Push Error Caution
Scenario
git push origin main

You get a "non-fast-forward" error when trying to push.

Solution: Pull and merge remote changes before pushing.

# Step 1: Pull and merge remote changes git pull origin main # Step 2: Resolve any merge conflicts if needed # Step 3: Push again git push origin main # Alternative (if rebasing): git pull --rebase origin main git push origin main
Committing Large or Sensitive Files Critical
Scenario
git add .

You committed a large file, secret keys, .env, or wrong files.

Solution: Remove the file from history and prevent future commits.

# Step 1: Unstage specific file git reset HEAD path/to/file # Step 2: Or remove from commit history (if committed) git rm --cached path/to/file # Step 3: Commit the removal git commit -m "Removed sensitive file" # Step 4: Push the change git push origin branch-name # If already pushed: # Step 1: Remove the file from history git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch path/to/file" \ --prune-empty --tag-name-filter cat -- --all # Step 2: Force push (team must re-clone or reset) git push origin --force --all
Fixing Commit Messages and Authors Safe
Scenario
git commit -m "Fix bug"

You made a typo or wrong message in the last commit.

Solution: Amend the commit to fix the message or author.

# Step 1: Edit last commit message git commit --amend -m "Corrected commit message" # Step 2: Push (if already pushed, use force) git push --force origin branch-name # For Author: git commit --amend --author="New Name "
Working on Wrong Branch Caution
Scenario
git checkout main

You worked on main or the wrong branch instead of a feature branch.

Solution: Move commits to correct branch and reset the original.

# Step 1: Create a new branch from current state git checkout -b feature-branch # Step 2: Reset main back (keep it clean) git checkout main git reset --hard origin/main # Step 3: Push your new feature branch git push origin feature-branch

Emergency Recovery Scenarios

Recovering After a Hard Reset Critical
Scenario
git reset --hard HEAD~5

You did a hard reset but later realized you needed those commits!

Solution: Use git reflog to find and recover lost commits.

# Find lost commits git reflog # Look for entries like: # abc1234 HEAD@{2}: commit: Add payment gateway # Recover specific files git checkout abc1234 -- src/payment.js # Get single file # Recover entire commit git branch temp-recovery abc1234 git cherry-pick abc1234..abc1234 # Apply to current branch # Verify changes git diff temp-recovery # Compare with recovered branch
Removing Sensitive Data After Push Critical
Scenario
git push origin main

You later found API keys in config.yml after pushing to remote.

Solution: Use git-filter-repo to completely purge the file from history.

# Install git-filter-repo (more powerful than BFG) brew install git-filter-repo # macOS # Purge file from all history git filter-repo --path config.yml --invert-paths # Force push to all branches git push origin --force --all git push origin --force --tags # Team cleanup (everyone must): git fetch origin git reset --hard origin/main
Splitting a Bad Commit Caution
Scenario
git commit -m "Everything"

You made a commit with mixed features and bugfixes that should be separate.

Solution: Use interactive rebase to split the commit into logical pieces.

# Interactive rebase git rebase -i HEAD~5 # Mark commit with "edit": edit abc1234 Everything pick def5678 Other commit # Reset and recommit git reset HEAD~1 git add -p # Stage changes piecemeal git commit -m "Feature A" git commit -m "Bugfix B" # Continue rebase git rebase --continue
The Wrong Branch Disaster Critical
Scenario
git checkout main git merge feature

You merged a feature branch into main instead of the development branch.

Solution: Undo the merge and redo it properly on the correct branch.

# Undo merge git reset --hard ORIG_HEAD # Redo properly git checkout dev git merge feature # Cleanup main (if already pushed) git checkout main git revert -m 1 abc1234 # Revert merge commit
Recovering a Deleted Branch Caution
Scenario
git branch -D experimental

You deleted a branch but later realized it had critical code.

Solution: Use git's file system check to find and recover the deleted branch.

# Find dangling commits git fsck --lost-found # Identify the branch head git show abc1234 # Check likely commits # Recreate branch git branch experimental abc1234
Git Won't Let Me Push Caution
Scenario
git push origin main

You get a "non-fast-forward" error when trying to push changes.

Solution: Understand why it's happening and resolve properly.

# Understand why: git fetch origin git log --graph --oneline origin/main..main # Rebase properly: git rebase -i origin/main # Force push safely: git push --force-with-lease
Pro Tip

Before doing any destructive operations, create a backup branch: git branch backup/before-dangerous-operation. This gives you a safe point to return to if things go wrong.

Safety Measures

Always use git push --force-with-lease instead of --force. It will fail if the remote has new commits that you haven't fetched, preventing you from overwriting your teammates' work.