{"post":{"slug":"how-to-fix-a-merge-conflict-2026","title":"How to fix a merge conflict in 2026","excerpt":"Merge conflicts are unavoidable on any active codebase. Understanding what the conflict markers mean and how to resolve them cleanly takes about ten minutes to learn.","category":"code","date":"March 31, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">M</span>erge conflicts look alarming the first time, but they are just Git's way of saying \"two changes touched the same lines and I need a human to decide the final version.\" The markers are structured; once you read them fluently, resolving a conflict is a five-minute task.\n\n## What changed in 2026\n\n- **`diff3` is now the recommended merge style** — Git 2.35+ accepts `git config --global merge.conflictstyle diff3`, and most teams have adopted it because it shows the common ancestor.\n- **VS Code and JetBrains ship excellent three-way merge editors** — the days of editing raw conflict markers in a terminal are optional.\n- **GitHub and GitLab both offer browser-based conflict resolution** for simple conflicts — fine for one-line changes, insufficient for logic conflicts.\n- **`git rerere` is underused** — it records your resolution and replays it automatically if the same conflict appears again (useful on long-lived feature branches).\n\n## Understanding conflict markers\n\n```\n<<<<<<< HEAD\nconst timeout = 5000;\n||||||| common ancestor  (only with diff3)\nconst timeout = 3000;\n=======\nconst timeout = 10000;\n>>>>>>> feature/longer-timeouts\n```\n\n- `<<<<<<< HEAD` — your current branch (what you have locally).\n- `||||||| common ancestor` — the original line both branches started from (only in `diff3` style).\n- `=======` — separator between the two versions.\n- `>>>>>>> feature/longer-timeouts` — the incoming branch you are merging in.\n\nThe common ancestor (`||||||| ...`) is the crucial part: it tells you what both sides were trying to change *from*, so you can understand intent, not just final values.\n\n## Enable diff3 (do this now, globally)\n\n```bash\ngit config --global merge.conflictstyle diff3\n```\n\nOr in `.gitconfig`:\n\n```ini\n[merge]\n    conflictstyle = diff3\n```\n\n## Step-by-step conflict resolution\n\n```bash\n# 1. Attempt the merge\ngit merge feature/longer-timeouts\n\n# 2. See which files have conflicts\ngit status\n# both modified:   src/config.ts\n\n# 3. Open each conflicted file and resolve\n# (edit in VS Code, IntelliJ, or your editor)\n\n# 4. After resolving, stage the file\ngit add src/config.ts\n\n# 5. Continue the merge\ngit merge --continue\n# (or git commit if --continue is not available)\n```\n\nFor rebase conflicts the flow is the same but uses `git rebase --continue` after each resolved commit.\n\n## Resolving in VS Code\n\nVS Code detects conflict markers and shows inline buttons:\n- **Accept Current Change** — keep HEAD (yours)\n- **Accept Incoming Change** — keep the incoming branch\n- **Accept Both Changes** — append both (rarely correct; review carefully)\n- **Compare Changes** — opens a side-by-side diff\n\nUse **\"Open Merge Editor\"** for a proper three-panel view: current, incoming, and the result you are editing.\n\n## Resolving with git mergetool\n\n```bash\ngit config --global merge.tool vimdiff   # or nvimdiff, meld, kdiff3, etc.\ngit mergetool\n```\n\n`vimdiff` opens three panes: LOCAL (yours), BASE (common ancestor), REMOTE (incoming), and the merged result below. Navigate with `[c` / `]c`; use `:diffget LO` or `:diffget RE` to pull from one side.\n\n## Shortcuts for obvious resolutions\n\n```bash\n# Take the entire file from our branch\ngit checkout --ours src/generated-lockfile.json\n\n# Take the entire file from the incoming branch\ngit checkout --theirs src/generated-lockfile.json\n\n# Stage after\ngit add src/generated-lockfile.json\n```\n\nUse `--ours` / `--theirs` only when you know the entire file should come from one side — common for lock files and generated files.\n\n## Common conflict scenarios\n\n| Conflict type | Best approach |\n| --- | --- |\n| Two developers edited the same function | Read both, write the merged intent manually |\n| Renamed variable in one branch | Accept the rename, propagate it to the other side |\n| Lock file (package-lock.json) | `--theirs` then run `npm install` to regenerate |\n| Generated code (protos, GraphQL types) | Regenerate from source; do not hand-edit |\n| CSS/formatting only | Accept either side; run formatter after |\n\n## Common mistakes\n\n**Staging without resolving.** `git add conflicted-file.js` when the file still contains `<<<<<<<` markers. Git will let you commit it; your CI will catch the syntax error — but later than ideal. Some editors warn; configure your linter to flag conflict markers.\n\n**Using `--theirs` everywhere to \"win fast\".** You silently discard your own changes. Read both sides.\n\n**Not running tests after resolving.** A syntactically correct merge can introduce a logical error — e.g., two developers each added an `if` branch with slightly different behavior; the merged result keeps both but the interaction breaks something.\n\n**Resolving a rebase conflict and forgetting `--continue`.** After `git add`, you must run `git rebase --continue`; if you run `git commit` instead you create an extra commit.\n\n## What to skip\n\n- **Browser-based conflict resolution for logic changes** — it is fine for a one-word rename but inadequate for multi-line function changes.\n- **Deleting conflict markers by hand without reading both sides** — you pick one version at random.\n- **Resolving conflicts in a shared branch by force-pushing** — it rewrites history for everyone on that branch.\n\n## FAQ\n\n**How do I abort a merge and go back to before it started?**\nRun `git merge --abort`. This resets the working tree to the state before `git merge` was run.\n\n**What is the difference between merge and rebase conflicts?**\nA merge conflict happens once at the merge commit. A rebase conflict can happen once per commit being replayed — a rebase of 10 commits might trigger 10 separate conflicts if the changes overlap each time.\n\n**How do I prevent conflicts in the first place?**\nShort-lived branches (< 2 days), small PRs, and pulling from the base branch frequently reduce conflict frequency. Feature flags let you merge incomplete work without conflicts in visible behavior.\n\n**What is `git rerere` and should I use it?**\n`git rerere` (REuse REcorded REsolution) records how you resolve a conflict and replays it automatically next time. Enable with `git config --global rerere.enabled true`. Useful on rebased feature branches that repeatedly conflict with main.\n\n## Where to go next\n\n- [How to undo a git commit in 2026](/blog/how-to-undo-a-git-commit-2026)\n- [How to squash commits in 2026](/blog/how-to-squash-commits-2026)\n- [How to set up pre-commit hooks in 2026](/blog/how-to-set-up-pre-commit-hooks-2026)","hue":320,"metaTitle":"How to Fix a Merge Conflict in 2026: Git Guide","metaDescription":"Step-by-step guide to resolving Git merge conflicts in 2026. Covers conflict markers, diff3 style, VS Code, IntelliJ, and common team workflows.","keywords":["how to fix a merge conflict 2026","git merge conflict resolution","git conflict markers explained","git diff3 merge style","vscode merge conflict","git mergetool 2026","git rebase conflict","git conflict resolution workflow","git checkout theirs ours","resolving merge conflicts git 2026"],"tldr":["**Conflict markers show you three versions** — HEAD (yours), the incoming branch, and the common ancestor in a diff3 merge.","**Always use diff3 style** — it adds the common ancestor to the conflict block, making the intent of both changes clear.","**Resolve in your editor or with git mergetool** — never edit conflict markers by hand without seeing both sides in context.","**Run tests after resolving** — a resolved conflict compiles but may break logic; tests catch it.","**Skip:** using git checkout --theirs on every conflict to \"win fast\" — you silently discard the other side's changes."],"readTime":"5 min read","wordCount":1005},"related":[{"slug":"what-is-a-merge-conflict-2026","title":"What is a merge conflict in 2026? Causes and how to fix it","excerpt":"A merge conflict happens when Git cannot automatically combine two sets of changes to the same lines. This guide explains why they occur and walks through resolving one calmly.","category":"code","date":"June 18, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":350},{"slug":"what-is-dependency-hell-2026","title":"What Is Dependency Hell in 2026? Causes and Fixes","excerpt":"Dependency hell is what happens when two things your project relies on need different, incompatible versions of the same underlying package. Here is why it still happens in 2026 and how to get out of it.","category":"code","date":"July 22, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":290},{"slug":"git-squash-vs-rebase-2026","title":"Git Squash vs Rebase in 2026: What Each One Does","excerpt":"Squashing collapses commits into one; rebasing replays commits onto a new base. Here is what each git command actually does, and when to reach for which one.","category":"code","date":"July 2, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":280}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"how-to-quit-a-job-gracefully-2026","title":"How to quit a job gracefully in 2026: leave well and protect your reputation","excerpt":"How you leave a job is remembered as clearly as how you performed it. Here is the 2026 playbook to resign professionally, protect your network, and exit cleanly.","category":"guides","date":"April 1, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":310},"older":{"slug":"how-to-fix-a-running-toilet-2026","title":"How to fix a running toilet in 2026: diagnose and repair in under an hour","excerpt":"A running toilet wastes 200+ gallons per day and the fix costs $10–25 in parts. Here is how to diagnose the cause and repair it yourself in 2026.","category":"guides","date":"March 31, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":150}}