LearnAI ToolsCareerPractice BuildsPlayDevelopmentContact
Lesson 816 min read

Merging Branches and Resolving Conflicts

Combine branches with git merge, understand fast-forward and three-way merges, and resolve merge conflicts calmly, step by step.

On this page 12 sections

Introduction

Branches are only useful if you can bring their work back together. git merge combines the history of another branch into the one you are on. Most merges are completely automatic. Occasionally, two branches change the same lines in different ways, and Git asks you to decide — a merge conflict. Conflicts look scary the first time, but resolving one is just editing a file.

What You Will Learn
  • The difference between fast-forward and three-way merges.
  • How to delete a branch after merging it.
  • How to read conflict markers and resolve a conflict.
  • Habits that make conflicts rare and small.

Fast-Forward Merges

To merge a branch, switch to the branch that should receive the changes — usually main — and merge the other branch into it. Priya is on main and merges her contact page:

git merge feature/contact-page
Output

Click Run to see what this code prints.

“Fast-forward” means main had not moved since the branch was created, so Git simply slid the main label forward to the branch’s latest commit. No new commit was needed and the history stays a straight line.

Deleting a Merged Branch

git branch -d feature/contact-page
Output

Click Run to see what this code prints.

Deleting a merged branch only removes the label; the commits are part of main now. -d refuses to delete a branch whose work has not been merged, protecting you from losing commits. -D forces the deletion — use it only when you really mean to throw that work away.

Three-Way Merges

Next, Priya starts a dark mode on a new branch and commits it. Before merging it, she adds a projects page directly on main. Now both branches have new commits, so a fast-forward is impossible:

git switch -c feature/dark-mode
# ...edit style.css...
git commit -am "Add dark mode"
git switch main
# ...create projects.html...
git add projects.html
git commit -m "Add projects page"
git merge feature/dark-mode
Output

Click Run to see what this code prints.

Git compared three snapshots — the common starting point and the tip of each branch — combined the changes, and created a merge commit with two parents. (Git briefly opens your editor so you can change the default message “Merge branch 'feature/dark-mode'”; saving and closing accepts it.) The graph now shows the split and the join:

git log --oneline --graph -5
Output

Click Run to see what this code prints.

When Branches Conflict

Git can combine changes to different parts of a file automatically. But on a new branch fix/heading, Priya changes the heading to “Hi, I'm Priya Sharma”, while on main she changes the same line to “Hello! I'm Priya”. Git cannot know which version is right:

git merge fix/heading
Output

Click Run to see what this code prints.

git status
Output

Click Run to see what this code prints.

Nothing is broken and nothing is lost. The merge is simply paused, waiting for you. both modified lists the files that need your decision.

Reading Conflict Markers

Git writes both versions into the file, surrounded by markers:

cat index.html
Output

Click Run to see what this code prints.

MarkerMeaning
<<<<<<< HEADStart of your version — the branch you are on (main)
=======Divider between the two versions
>>>>>>> fix/headingEnd of the incoming version from the branch you are merging
Mini Challenge · Predict the Output

You are on main and run git merge feature/footer. In the conflict, which version appears between <<<<<<< HEAD and =======?

Choose one answer

Resolving the Conflict

Open the file and edit it into the final version you want, deleting all three marker lines. You can keep one side, the other, or combine them — Priya combines them:

index.html (resolved)
<h1>Hello! I'm Priya Sharma</h1>

Then tell Git the conflict is resolved by staging the file:

git add index.html
git status
Output

Click Run to see what this code prints.

Finish the merge with git commit. --no-edit accepts the default merge message:

git commit --no-edit
Output

Click Run to see what this code prints.

git log --oneline --graph -4
Output

Click Run to see what this code prints.

Changed Your Mind?

While a merge is paused, git merge --abort cancels it and puts everything back exactly as it was before you started. VS Code also highlights conflicts with “Accept Current / Accept Incoming / Accept Both” buttons, which edit the markers for you.

Mini Challenge · Put It in Order

Put the steps for resolving a merge conflict in order.

  1. Run git status to list the conflicted files
  2. Run git merge and see the CONFLICT message
  3. Stage each resolved file with git add
  4. Finish the merge with git commit
  5. Edit each file into its final version and delete the markers

Avoiding Conflicts

  • Merge (or pull) the latest main into long-running branches often, so differences stay small.
  • Keep branches short-lived: a branch that lives for a day rarely conflicts.
  • Make focused commits that change only what the feature needs — reformatting a whole file causes conflicts for everyone.
  • Talk to your team when two people need to change the same file.

Common Mistakes

Avoid These Mistakes
  • Merging while on the wrong branch — check with git status or git branch first.
  • Leaving <<<<<<<, ======= or >>>>>>> lines in the file and committing them.
  • Forgetting to git add a resolved file, so Git still thinks it is in conflict.
  • Deleting a branch with -D before checking that its work was merged.

Frequently Asked Questions

Yes: git merge --no-ff <branch> always creates a merge commit. Some teams prefer this because the history then shows clearly where each feature started and ended.

It is the name of Git’s default merge strategy since Git 2.34. You do not need to configure anything — it is just Git telling you how it combined the changes.

git status will say “deleted by us” or “deleted by them”. Decide whether the file should exist: git add <file> keeps it, git rm <file> deletes it, then commit.

Key Takeaways

  • Switch to the receiving branch, then run git merge <other-branch>.
  • A fast-forward just moves the label; a three-way merge creates a merge commit with two parents.
  • Delete merged branches with git branch -d; -D forces deletion of unmerged work.
  • In a conflict, the HEAD section is your branch’s version and the other section is the incoming one.
  • Resolve by editing the file, removing the markers, running git add, then git commit (or git merge --abort to cancel).

Summary

You can now combine any branches and resolve conflicts with confidence. Merging is not the only way to bring work together, though. In the next lesson you will learn rebasing, which replays commits on top of another branch for a cleaner, straight-line history — and the one rule that keeps it safe.

Next Lesson →

Rebasing: Rewriting History Safely