Git Pitfall Guide: Common Errors and How to Fix Them
Git is powerful, which means mistakes can be devastating. This article covers the pitfalls I have fallen into and the ones you are likely to encounter, along with how to fix them.
Pitfall One: git push --force Deleted Someone Code
This is the easiest and most severe mistake to make.
You rebased your branch and the push was rejected (because the remote history no longer matches your local history). In a rush, you added --force and pushed.
Result: all your colleagues commits on the remote branch were overwritten by yours.
How to avoid it: Never use --force on shared branches (main, develop). Your own feature branch is fine, but only if no one else works on it. Use --force-with-lease instead of --force — it checks that no one else has pushed changes before overwriting. This is a simple safety net that prevents most force-push disasters.
How to fix it: If you just force pushed, use git reflog to find the overwritten commit, then:
git reset --hard abc1234
git push --force
This only works if your colleagues have not pulled the overwritten code. If they have, it gets more complicated and requires team coordination. Communicate with your team immediately, share the correct commit hash, and have everyone reset their branch to that point.
Pitfall Two: Committed Sensitive Information
You forgot to remove the database password from a config file and pushed it. By the time you remember, the password is already in the GitHub history.
How to avoid it: Store sensitive data in environment variable files (.env) and exclude them in .gitignore. If you have not pushed yet, amend the commit:
git add .
git commit --amend -m "original message"
amend overwrites the most recent commit, replacing the version with the password.
Also consider using git-secrets, a tool that prevents you from committing sensitive information. It scans commits for common patterns like API keys and passwords.
If you already pushed: amend plus force push is needed to overwrite the remote. But a safer approach is using git filter-repo to completely remove the file from history:
git filter-repo --path filename --invert-paths
Note: filter-repo rewrites all commit history. Everyone needs to re-clone the repository. This is not a light operation, so prevention is far better.
GitHub also offers secret scanning that proactively detects common key formats in public repositories and notifies you. Enable this feature in your repository settings.
Pitfall Three: Committed Large Files
You committed a 500MB video file. Pushing is painfully slow, and this file will live in the repository history forever, downloaded on every clone.
How to avoid it: Use Git LFS (Large File Storage) for large files. After installing LFS:
git lfs install
git lfs track "*.mp4"
git add .gitattributes
LFS stores large files on a separate server; Git only keeps a pointer. Common patterns to track with LFS: *.psd, *.zip, *.mp4, *.bin, *.pdf.
How to fix it: If a large file is already in history, use filter-repo to remove it:
git filter-repo --path big-file.avi --invert-paths
GitHub also provides a warning when you try to push files larger than 50MB, and rejects files larger than 100MB entirely. Use this as a safety net.
Pitfall Four: git reset --hard Lost Your Code
You made many changes in the working directory, felt it was too messy, and ran git reset --hard. All working directory changes are gone.
How to avoid it: Before running reset --hard, check for uncommitted changes. If unsure, run git stash first.
How to fix it: If the changes were staged with git add, use git fsck to recover:
git fsck --lost-found
This places recoverable lost objects in .git/lost-found.
If the changes were never staged, Git has no record of them. They are truly gone. This is why I recommend frequent add and committing — more saves are always better than fewer.
Additional Recovery Options
If you committed the changes and then reset, the commits may still be recoverable via git reflog. The reflog keeps track of HEAD movements for 30-90 days by default.
git reflog
git reset --hard <commit-hash-from-reflog>
Pitfall Five: Multiple People Changed the Same File
You changed line 1 of file A; a colleague changed line 10. You pushed first. When they pulled, there was a conflict. They were not sure how to resolve it and deleted your changes, keeping only theirs.
How to avoid it: Divide work by file when possible. If multiple people must edit the same file, communicate ahead of time. Pull frequently to minimize divergence.
How to fix it: If code was incorrectly overwritten, use git reflog to find your commit and cherry-pick it back:
git cherry-pick your-commit-id
Also, configure a merge tool to make conflict resolution less error-prone. Tools like VS Code's built-in merge editor, Beyond Compare, or Meld provide a visual interface that makes it clearer what will be kept and what will be discarded.
Pitfall Six: Committed on the Wrong Branch
You meant to commit on the feature branch but forgot to switch and committed directly to main.
How to fix it: Move the commit to the correct branch:
git checkout feature
git checkout -b temp-branch # make sure not to lose the commit
git checkout main
git reset --hard HEAD~1 # undo the commit on main
git checkout temp-branch # return to feature branch
Alternatively, cherry-pick the commit to the correct branch and reset it from main. Moving branches around is one of Git's strengths -- don't fear it, just understand what each command does.
Pitfall Seven: Detached HEAD State
You checked out a specific commit (e.g., git checkout abc1234) and made some commits. When you switch to another branch, those commits seem to disappear.
How to avoid it: If you need to look at a specific commit, create a branch from it first: git checkout -b temp-branch abc1234. Any commits you make will now be on the new branch.
How to recover: Use git reflog to find the lost commits and create a branch from them.
A Core Principle
Most Git operations are reversible if you know how. For uncertain operations, check first or back up. A simple backup is copying the entire project folder:
cp -r my-project my-project-backup
With a backup, you can experiment freely. If something goes wrong, delete it and start over.
Wrapping Up
Git pitfalls mostly come from "destructive" operations: force, reset, and filter. Remember one rule: never do destructive operations on shared branches. On your own branch, you can experiment freely.
One more good habit: try important operations in a test repository first. Confirm it works before running it on the real thing.
When in doubt, remember that Git is designed to be safe. Most operations can be undone, especially if you haven't pushed yet. Take a breath, read the commands carefully, and remember that git reflog is your safety net for most mistakes.
The single most valuable Git habit I have developed over the years is to run a quick check before every potentially destructive command. Before git push --force, I verify which branch I am on. Before git reset --hard, I run git status to confirm there is nothing I want to keep. Before git branch -d, I check that the branch has been merged. Ten seconds of checking has saved me hours of recovery work, and the peace of mind alone makes it a habit worth developing from Day One. If you work in a team that uses a forking workflow — where each developer works in their own fork of the repository rather than sharing branches directly — many of these pitfalls become less likely because nobody has write access to the main repository's shared branches. However, the same principles still apply locally: always double-check before running a destructive command, and remember that git reflog is your friend whenever something goes wrong. A final piece of advice that I wish I had known earlier is to set up Git aliases for your most common safety-check commands. For example, you can create an alias git safe-reset that runs git status and shows a confirmation prompt before executing the actual reset, or an alias git which-branch that clearly displays the current branch name and its tracking status. These small workflow adjustments embed safety checks into your daily routine, making it nearly impossible to accidentally run a destructive command on the wrong branch or without realizing the consequences.
The cardinal rule of Git can be summarized in one sentence: never perform a destructive operation that you would not be comfortable explaining to a colleague during a code review.
One of the highest leverage Git skills that most developers never learn is creating effective aliases. Well designed aliases can save dozens of keystrokes per hour and make complex operations accessible to team members who do not use Git daily. Start with these essentials: git lg for a compact graph based log view, git undo for soft resetting the last commit while preserving changes, and git last for viewing the diff of the last commit instantly. Store aliases in your global gitconfig so they are available across all projects. The key principle of effective aliasing is capturing operations you perform at least daily but find verbose or forgettable under pressure. Aliases turn muscle memory into single keystrokes, reducing cognitive load and making version control feel more like a natural extension of your thinking about the problem you are actually trying to solve.
