Git merge conflict markers committed to repo – how to undo
You accidentally committed conflict markers like <<<<<<< and =======. Here's the fastest way to find, remove, and prevent them.
You committed the conflict markers – here's the fix
You opened a PR, or maybe you just pushed, and someone points out you left <<<<<<< and ======= in the code. We've all done it. Merge conflict noise that you resolved in your editor but forgot to clean up before staging. Git doesn't stop you – it treats those markers as plain text. So now they're in your history.
What's actually happening here is simple: during a merge or rebase, Git inserts markers around conflicting hunks. You fix the file, but maybe you only saved, not staged the clean version. Or you git add the resolved file but a second conflicting file slipped through. Either way, the marker strings are now in a commit.
The fastest fix: find the markers, then rewrite history if you haven't pushed, or revert the commit if you have. Let's get specific.
Cause #1: You haven't pushed yet – rewrite the last commit
If the commit with markers is only local, the fix is painless. Use git reset to unwind and re-commit cleanly.
# Find the last commit's hash
$ git log --oneline -1
# Soft reset to unstage but keep your changes
$ git reset --soft HEAD~1
# Now check for markers in your working tree
$ grep -rn '<<<<<<<\|=======\|>>>>>>>' . --include='*.py' --include='*.js' --include='*.ts' --include='*.java' --include='*.go' --include='*.rb' --exclude-dir=node_modules --exclude-dir=.git
# If grep returns nothing, you're clean – re-stage everything
$ git add .
$ git commit -m "fix: resolve merge conflicts correctly"
The reason git reset --soft HEAD~1 works: it moves the branch pointer back one commit but leaves the index (staging area) and working directory untouched. Your fixed files are still there, just uncommitted. You get a second chance to stage only the clean versions.
If you see markers in the grep output, open those specific files, remove the marker lines (the <<<<<<<, =======, and >>>>>>> lines), save, then git add and commit.
Cause #2: You've already pushed – revert the commit
Once a commit with markers reaches a shared branch (main, develop, or a PR branch others might pull), rewriting history with reset is a bad idea. You'll cause pain for everyone else. Instead, use git revert.
# Find the offending commit
$ git log --oneline
abc1234 Merge branch 'feature-x'
# Revert that specific commit
$ git revert abc1234 --no-edit
# Push the revert
$ git push origin main
What git revert does: it creates a new commit that undoes all changes from the target commit. Your history stays linear and everyone's local repos stay compatible. The markers vanish from the codebase on the next pull.
But wait – what if the commit with markers also contained legitimate code you want to keep? The revert will undo everything in that commit. That's fine as long as the legitimate code was from the merge resolution itself. If you need to preserve some changes, revert first, then re-apply the good parts with git cherry-pick from a previous commit.
Cause #3: You want the markers gone from history entirely (squash or rewrite)
This is for when the markers are buried in a branch you haven't merged to main yet, or you're cleaning up a messy history before a PR. Use an interactive rebase to squash or edit the offending commit.
# Start interactive rebase for last 5 commits
$ git rebase -i HEAD~5
# In the editor, change 'pick' to 'edit' on the commit with markers
# Save and exit
# Now Git stops at that commit. Remove markers from files:
$ grep -rn '<<<<<<<\|=======\|>>>>>>>' . --include='*' --exclude-dir=.git
# Fix files, then:
$ git add .
$ git commit --amend --no-edit
$ git rebase --continue
The edit action in rebase -i lets you alter a specific commit without affecting later ones. After you amend and continue, the markers are gone from that commit's snapshot. This is the cleanest approach if you control the branch – no revert noise, no extra commits.
Preventing it from happening again
The real fix is a pre-commit hook that rejects files containing conflict markers. Here's a minimal bash hook for .git/hooks/pre-commit:
#!/bin/bash
# Reject commit if any staged file contains merge conflict markers
if git diff --cached --name-only | xargs grep -l '<<<<<<<\|=======\|>>>>>>>' 2>/dev/null; then
echo "ERROR: Merge conflict markers found in staged files. Remove them before committing."
exit 1
fi
exit 0
Make it executable: chmod +x .git/hooks/pre-commit. This works because git diff --cached --name-only lists exactly the files that will go into the commit, and grep -l returns a non-zero exit code when it finds markers, which triggers the exit 1.
For a team-wide solution, use pre-commit framework with the merge-conflict hook. Add this to your .pre-commit-config.yaml:
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
hooks:
- id: check-merge-conflict
That hook checks for markers in staged files and blocks the commit. No thinking required.
Quick-reference summary table
| Situation | Command | Effect |
|---|---|---|
| Not pushed yet | git reset --soft HEAD~1 |
Uncommits, keeps changes staged – re-commit clean |
| Already pushed | git revert <hash> |
Creates new commit undoing the markers |
| Deep in local branch history | git rebase -i with edit |
Rewrites history to remove markers from the commit |
| Prevent future slips | pre-commit hook with check-merge-conflict |
Blocks commit if any staged file has markers |
Don't beat yourself up over a stray marker. It happens. What matters is catching it early and knowing which tool to reach for. The pre-commit hook is your long-term insurance.
Was this solution helpful?