What's Actually Happening
You're attempting to merge a branch, but Git cannot automatically resolve the conflicts between your changes and the incoming changes. The merge stops mid-process, leaving conflict markers in your files. In some cases, subsequent operations fail because the repository is in an unresolved merge state.
The Error You'll See
During a merge:
Auto-merging src/app.js
CONFLICT (content): Merge conflict in src/app.js
Automatic merge failed; fix conflicts and then commit the result.When trying to commit without resolving:
error: Committing is not possible because you have unmerged files.
hint: Fix them up in the work tree, and then use 'git add <file>'
hint: to mark as resolved and use 'git commit' to finalize the merge.When trying other operations during a merge:
fatal: You have not concluded your merge (MERGE_HEAD exists).
Please, commit your changes before you merge.Why This Happens
Git merge conflicts occur when: - The same lines are modified differently in both branches - One branch deletes a file while the other modifies it - Both branches add files with the same name but different content - Binary files are modified in both branches - File renames conflict with modifications
Git marks these conflicts but cannot automatically decide which version to keep.
Step 1: Identify Conflicted Files
Check the current merge status:
git statusLook for files marked as "both modified" or "unmerged":
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/app.js
both modified: config/settings.json
deleted by them: src/old-module.jsStep 2: View Conflict Details
For a detailed view of conflicts:
git diff --name-only --diff-filter=UTo see the actual conflicts in a file:
git diff src/app.jsStep 3: Understand Conflict Markers
Open a conflicted file to see markers:
<<<<<<< HEAD
const value = 100;
=======
const value = 200;
>>>>>>> feature-branch<<<<<<< HEADmarks your current branch's version=======separates the versions>>>>>>> feature-branchmarks the incoming branch's version
Step 4: Resolve Conflicts Manually
Edit each conflicted file, removing markers and keeping the correct code:
nano src/app.jsChoose one version, combine both, or write something new:
// Combined solution
const value = process.env.PRODUCTION ? 200 : 100;After editing, remove all conflict markers.
Step 5: Stage Resolved Files
Mark each file as resolved:
git add src/app.js
git add config/settings.jsonFor deleted file conflicts, choose to keep or remove:
```bash # Keep the file (their deletion) git rm src/old-module.js
# Or keep your version git add src/old-module.js ```
Step 6: Use Git Tools for Resolution
Git provides tools to help resolve conflicts:
Checkout one side completely:
```bash # Keep your version git checkout --ours src/app.js
# Keep their version git checkout --theirs src/app.js ```
Or use the merge tool:
git mergetoolStep 7: Verify All Conflicts Are Resolved
Check for any remaining conflicts:
git diff --checkNo output means all conflicts are resolved.
Check staging status:
git statusAll conflicted files should now be in "Changes to be committed".
Step 8: Complete the Merge
Commit the merge resolution:
git commit -m "Merge feature-branch into main, resolve conflicts in app.js and settings"Git automatically generates a merge commit message with details about the merged branches.
Step 9: Handle Aborted Merges
If you need to start over:
git merge --abortThis cancels the merge and returns to the pre-merge state.
If abort doesn't work (older Git versions):
git reset --hard HEADVerify the Fix
Confirm the merge is complete:
git statusYou should see:
On branch main
nothing to commit, working tree cleanVerify the merge commit:
git log --oneline -3You should see your merge commit in the history.
Test that the code works:
npm test
# or
make testFor future merges, consider using git rerere (reuse recorded resolution) to automatically apply previous conflict resolutions:
git config --global rerere.enabled true