Every Developer's Git Error Ritual
Type the exact error text into a search engine, open four Stack Overflow tabs, skim past three answers that don't quite match your situation, and eventually find the one that does. This happens to junior and senior developers alike — Git's error messages are accurate but rarely self-explanatory about why something is blocked or what to do next.
Here are the five that come up constantly, explained properly.
1. "error: failed to push some refs"
error: failed to push some refs to 'https://github.com/you/repo.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally.
What it means: the remote branch has commits your local branch doesn't have — usually because someone else pushed since you last pulled, or because you pushed from a different machine. Git refuses to overwrite history it doesn't know about.
Fix: pull the remote changes in first, then push:
git pull
git push
If git pull produces a merge conflict, resolve it (see below) before pushing. If you specifically want to preserve a linear history instead of a merge commit, git pull --rebase replays your local commits on top of the remote ones instead of merging.
What not to do: reach for git push --force as a first instinct. Force-pushing overwrites the remote branch with your local one — including discarding any commits the remote has that you don't. On a shared branch, that can silently delete a teammate's work. Reserve force-pushing for branches only you use.
2. Merge Conflict
Auto-merging src/app.js
CONFLICT (content): Merge conflict in src/app.js
Automatic merge failed; fix conflicts and then commit the result.
What it means: Git found a common ancestor between the two branches (unlike error #3 below), but both branches changed the same lines of the same file since that ancestor, and Git can't automatically decide which version is correct.
Fix: open the conflicting file — Git marks the conflicting sections directly in the file:
<<<<<<< HEAD
your version of the line
=======
their version of the line
>>>>>>> branch-name
Edit the file to keep whichever content is correct (removing the <<<<<<<, =======, >>>>>>> markers), then:
git add src/app.js
git commit
For conflicts in generated or binary files where you know which side should simply win entirely, git checkout --ours <file> or git checkout --theirs <file> resolves it without manual editing.
3. "fatal: refusing to merge unrelated histories"
fatal: refusing to merge unrelated histories
What it means: this is different from a normal merge conflict. Git looked for a common commit ancestor between the two histories and found none at all — the two branches don't share any origin. This typically happens when you're combining two repositories that were genuinely separate projects, or re-initializing a repo and trying to merge in an old clone that no longer shares history with the new one.
Fix: if you're certain this merge is intentional (it usually is when this error fires — you know you're combining two separate projects), explicitly allow it:
git merge other-branch --allow-unrelated-histories
Expect a genuine merge conflict resolution step afterward, since Git now has to reconcile two histories with zero shared context.
4. Detached HEAD State
Note: switching to '3f2a1b9'.
You are in 'detached HEAD' state...
What it means: you checked out a specific commit hash (or a tag) instead of a branch. HEAD — Git's pointer to "what you're currently looking at" — is now pointing directly at a commit instead of at a branch reference. You can look around and even make commits, but those commits aren't attached to any named branch.
The risk: if you make new commits while detached and then switch to another branch without doing anything else, those detached commits become unreachable by name — Git's garbage collector will eventually clean them up, and they're effectively lost.
Fix, if you want to keep any work done in this state: create a branch right where you are, before switching away:
git switch -c recovered-work
Fix, if you just want to get back to normal: switch back to a real branch:
git switch main
5. "fatal: not a git repository (or any of the parent directories): .git"
What it means: every Git command works by walking upward from your current directory looking for a .git folder. This error means it walked all the way up without finding one — you're either not inside a repository at all, or the .git folder was deleted or never created.
Fix: confirm what's actually there:
ls -la # macOS/Linux
dir /a # Windows
If there's genuinely no .git folder and this should be a new repository:
git init
If you meant to be inside an existing project, double check you're actually in the right directory — pwd (or cd alone on Windows) confirms your current path.
Quick Reference
| Error | Root cause | Fix |
|---|---|---|
| failed to push some refs | Remote has commits you don't have locally | git pull (or --rebase), then push |
| Merge conflict | Both branches changed the same lines | Edit conflict markers, git add, git commit |
| refusing to merge unrelated histories | No common ancestor between the histories | git merge --allow-unrelated-histories |
| Detached HEAD | Checked out a commit/tag instead of a branch | git switch -c <name> to save work, or git switch main |
| fatal: not a git repository | No .git folder found in this directory tree | git init, or cd to the correct folder |
Look Up the Right Command Without Guessing
ToolNinja's Git Command Generator → covers 65+ common Git operations — search by what you're trying to do in plain English and get the exact command, with warnings on the destructive ones before you run them.
Sources: