Last updated: Apr 13, 2025
Table of Contents
- 1. Introduction: Oops, I Did It Again!
- 2. Mistake: Committed to the Wrong Branch
- 3. Mistake: Forgot to Add Files to Last Commit
- 4. Mistake: Typo in the Last Commit Message
- 5. Mistake: Accidentally Deleted a Branch
- 6. Mistake: Committed Sensitive Data
- 7. Mistake: Messy Commit History / Need to Rebase
- 8. Mistake: Force Pushed Over Shared Work
- 9. Mistake: Lost Changes withgit reset --hard
- 10. Conclusion: Git Happens
1. Introduction: Oops, I Did It Again!
Git is an incredibly powerful version control system, but with great power comes the potential for making
mistakes. Whether you’re a beginner or a seasoned developer, accidentally committing to the wrong branch,
making a typo in a commit message, or needing to undo changes is a common experience. Fortunately, Git
provides robust tools to recover from most common mishaps.
This guide covers some of the most frequent Git mistakes and provides practical steps on how to fix them.
Remember to always understand what a command does before running it, especially those that modify history!
2. Mistake: Committed to the Wrong Branch
You made one or more commits, only to realize you were on main (or another incorrect branch)
instead of your feature branch (e.g., feature/my-new-thing).
The Fix: Move the commits to the correct branch.
Make sure your intended branch exists. If not, create it from the current state:
# Create the new branch pointing to the current commit
git branch feature/my-new-thing
Reset the incorrect branch (e.g., main) back to where it should be (before your erroneous
commits). Replace N with the number of commits you made incorrectly.
# Reset main back N commits, keeping the changes in your working directory
git reset HEAD~N --soft
OR if you haven’t pushed and want to discard the commits from main entirely
git reset HEAD~N --hard # Be careful with --hard!
Alternatively, find the commit hash main should point to using git log and reset
to that:
git reset <correct_main_commit_hash> --soft
(If you used --soft reset and have changes staged) Clean up the staging area:
git reset HEAD
Stash any uncommitted changes you want to keep but move:
git stash
Checkout the correct branch:
git checkout feature/my-new-thing
Apply the stashed changes (if you stashed any):
git stash pop
If you used --soft reset in step 2, your changes are now in the working directory on the
correct branch. Add and commit them:
git add .
git commit -m “Your commit message”
If you made multiple commits initially, you might need to recommit them individually or combine them.
Now, your incorrect branch is back to its proper state, and your commits are on the correct feature branch.
3. Mistake: Forgot to Add Files to Last Commit
You made a commit, but realized you forgot to include one or more files, or missed a change in an existing
file.
The Fix: Amend the last commit.
Important: Only do this if you haven’t pushed the commit to a shared remote repository yet!
Stage the missing file(s) or changes:
git add forgotten_file.txt
git add modified_file.js
Amend the previous commit, adding the newly staged changes without changing the commit message:
git commit --amend --no-edit
Your last commit now includes the forgotten files/changes.
4. Mistake: Typo in the Last Commit Message
You just committed, but noticed a typo or error in the commit message.
The Fix: Amend the last commit message.
Important: Only do this if you haven’t pushed the commit to a shared remote repository yet!
Run the amend command:
git commit --amend
This will open your default text editor with the previous commit message.
Correct the message in the editor, save, and close the editor.
Alternatively, provide the new message directly:
git commit --amend -m “Your corrected commit message”
The commit message is now fixed.
5. Mistake: Accidentally Deleted a Branch
You deleted a local branch (e.g., using git branch -d or git branch -D) but
realized you still needed it.
The Fix: Use the reflog.
Git keeps a log of where HEAD and branch references have pointed (the reflog). You can usually find the last
commit of the deleted branch there.
View the reflog to find the last commit hash of the deleted branch:
git reflog
Look for entries like
checkout: moving from
associated with the
Once you find the correct commit hash (e.g., a1b2c3d), recreate the branch pointing to that
commit:
git checkout -b
Your branch is now restored to its previous state.
6. Mistake: Committed Sensitive Data
You accidentally committed passwords, API keys, or other sensitive files.
The Fix (Complex & Requires Caution): Remove the data from history.
WARNING: Rewriting repository history is dangerous, especially if the repository is shared.
It invalidates existing clones for collaborators. Always back up your repository before attempting this.
Simple git commit --amend or git reset only works if the sensitive commit is the
very last one and hasn’t been pushed.
Remove the file from your current working directory and stage the removal if it’s still
present. Add the file path to your .gitignore file to prevent re-committing it.
Use a history rewriting tool: The recommended tool is git filter-repo (a
replacement for the older, complex git filter-branch). BFG Repo-Cleaner is another option.
Using git filter-repo (Example: Remove a file named
secrets.yml):
Install git-filter-repo first if you haven’t already
(Follow instructions from its official repository)
Run filter-repo to remove the file from all commits
git filter-repo --path secrets.yml --invert-paths
Using BFG Repo-Cleaner (Example: Remove a file named secrets.yml):
Download bfg.jar first
Create a bare clone (important!)
git clone --mirror git://example.com/my-repo.git
Run BFG
java -jar bfg.jar --delete-files secrets.yml my-repo.git
Go into the cleaned repo and run gc
cd my-repo.git
git reflog expire --expire=now --all && git gc --prune=now --aggressive
Push the cleaned history (DANGEROUS - coordinate with team!)
cd …
git push --force # Or preferably, coordinate and have everyone re-clone
Invalidate Secrets: Crucially, any committed secrets (API keys, passwords) must be
considered compromised. Immediately revoke or change them. Removing them from Git history does not make
them secure again if they were ever public.
Coordinate with Team: If the repo is shared, inform collaborators. They will likely need
to re-clone or perform complex fetch/rebase operations. Force pushing (git push --force or
–force-with-lease) will be necessary to update the remote repository with the rewritten
history.
7. Mistake: Messy Commit History / Need to Rebase
Your feature branch has many small, “work-in-progress” commits, or it has fallen behind the main branch and
has many merge commits cluttering the history.
The Fix: Interactive Rebase (git rebase -i).
Important: Avoid rebasing commits that have already been pushed and shared with others on a
collaborative branch, as it rewrites history.
Identify the base commit onto which you want to rebase or clean up commits after. This is often the
commit where your feature branch diverged from the main branch (e.g., main or
develop).
Start the interactive rebase:
git rebase -i <base_commit_hash_or_branch_name>
Example: Rebase current branch onto ‘main’
git rebase -i main
An editor will open listing the commits since the base. You can:
pick: Use the commit as is.
reword (or r): Edit the commit message.
edit (or e): Stop to amend the commit (change content and message).
squash (or s): Combine this commit with the previous one (merges changes and
combines messages).
fixup (or f): Combine like squash, but discard this commit’s message.
drop (or d): Delete the commit entirely.
Reorder lines to change commit order.
Save and close the editor. Git will apply the changes. Resolve any conflicts that arise during the
process. Use git rebase --continue after resolving conflicts, or
git rebase --abort to cancel.
Interactive rebase is powerful for cleaning up local history before merging or creating a pull request.
8. Mistake: Force Pushed Over Shared Work
You used git push --force on a shared branch and overwrote commits made by others.
The Fix: Coordination and potentially restoring commits.
Prevention is key! Avoid using git push --force on shared branches. Use
git push --force-with-lease instead, which checks if the remote branch has changed since your
last fetch, preventing accidental overwrites.
Stop! Inform your collaborators immediately.
Find Lost Commits: Ask collaborators if they have the lost commits locally. They might be
able to push them back up to a new branch. The reflog on the server (if accessible) or collaborators’
local reflogs might also contain the lost commit hashes.
Restore Commits: If someone has the commits, they can create a new branch from the lost
commit hash and push it. Then you can merge or cherry-pick those commits back into the shared branch.
# Collaborator finds lost commit hash ‘xyz123’
git checkout -b recovery-branch xyz123
git push origin recovery-branch
On the main machine/branch
git fetch origin
git merge origin/recovery-branch # Or cherry-pick specific commits
Rebase Your Work: Your local work might now need to be rebased onto the restored branch
history using git pull --rebase before you can push again normally.
Recovering from a bad force push requires careful coordination.
9. Mistake: Lost Changes withgit reset --hard
You ran git reset --hard and realized it discarded local changes (committed or uncommitted) that
you actually needed.
The Fix: Check the reflog (immediately!).
git reset --hard moves the branch pointer and discards changes in the working directory and
staging area. If the changes were committed before the reset, they might still be recoverable via the
reflog.
Immediately run git reflog:
git reflog
Look for the commit hash representing the state before you ran git reset --hard.
If you find the commit hash (e.g., a1b2c3d): You can restore your branch to
that state:
git reset --hard a1b2c3d
Or, create a new branch from that commit to inspect it without changing your current branch:
git checkout -b recovery-branch a1b2c3d
If changes were uncommitted: Unfortunately, git reset --hard discards
uncommitted changes permanently. Git doesn’t track them. Your only hope might be filesystem recovery tools
or IDE local history features (if available), but don’t count on it. Be very careful with
git reset --hard!
10. Conclusion: Git Happens
Making mistakes with Git is a normal part of the development process. The key is not to panic. Git provides
powerful tools like --amend, rebase, reset, and especially the
reflog, which act as safety nets for many common errors.
Understanding these recovery techniques can save you significant time and stress. Always try to understand
what a command does before executing it, especially commands that modify history or involve force pushing.
When in doubt, create backup branches or consult the extensive Git documentation.