Skip to main content

Merging Branches and Resolving Conflicts

Now that you're comfortable working with branches, it's time to learn how to bring your work together. In this lesson, you'll learn how to merge branches and handle the inevitable conflicts that arise when multiple changes affect the same code.

Learning Goals:

  • Understand different merge strategies
  • Perform fast-forward and three-way merges
  • Identify and resolve merge conflicts
  • Use Git's conflict resolution tools effectively

Understanding Merge Types

Git offers several ways to combine branches, but the two most common are fast-forward and three-way merges.

Fast-Forward Merge

A fast-forward merge occurs when the target branch has no new commits since you created your feature branch. Git simply moves the pointer forward.

Fast-forward merge example
# Create and switch to a feature branch
git checkout -b feature/login

# Make some changes and commit
echo "// login functionality" > login.js
git add login.js
git commit -m "Add login functionality"

# Switch back to main and merge
git checkout main
git merge feature/login

When successful, you'll see: Fast-forward

Three-Way Merge

When both branches have new commits, Git performs a three-way merge, creating a new "merge commit" that combines both histories.

Three-way merge example
# On main branch
echo "// main update" > main.js
git add main.js
git commit -m "Update main"

# On feature branch
git checkout feature/login
echo "// enhanced login" >> login.js
git add login.js
git commit -m "Enhance login"

# Merge feature into main
git checkout main
git merge feature/login

This creates a merge commit with the message: Merge branch 'feature/login'

tip

Use git merge --no-ff to always create a merge commit, even when fast-forward is possible. This preserves branch history in your log.

Handling Merge Conflicts

Conflicts occur when Git cannot automatically reconcile changes from different branches. Let's create and resolve a common conflict scenario.

Creating a Conflict

Setting up a conflict
# On main branch
git checkout main
echo "function calculate() {\n return 1 + 1;\n}" > math.js
git add math.js
git commit -m "Add calculate function"

# On feature branch
git checkout -b feature/calculator
echo "function calculate() {\n return 2 * 2;\n}" > math.js
git add math.js
git commit -m "Update calculate to multiplication"

# Back to main for merge
git checkout main
echo "function calculate() {\n return 10 - 5;\n}" > math.js
git add math.js
git commit -m "Update calculate to subtraction"

Now attempt the merge:

git merge feature/calculator

You'll see conflict output:

Auto-merging math.js
CONFLICT (content): Merge conflict in math.js
Automatic merge failed; fix conflicts and then commit the result.

Resolving the Conflict

Check the status and examine the conflicted file:

git status

Open math.js to see the conflict markers:

math.js with conflict markers
function calculate() {
<<<<<<< HEAD
return 10 - 5;
=======
return 2 * 2;
>>>>>>> feature/calculator
}

Edit the file to resolve the conflict:

math.js after resolution
function calculate() {
return 10 - 5; // Keep main version
}

Complete the resolution:

Completing conflict resolution
git add math.js
git commit -m "Resolve merge conflict, keep subtraction logic"
warning

Always remove the conflict markers (<<<<<<<, =======, >>>>>>>) when resolving conflicts. Git will refuse to complete the merge if they remain.

Using Merge Tools

Git provides visual tools to help resolve conflicts. Configure and use them:

Configuring merge tool
# Configure VS Code as merge tool (example)
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd "code --wait $MERGED"

# Launch merge tool during conflict
git mergetool

Common Pitfalls

  • Forgetting to commit changes: Ensure all changes are committed before merging
  • Aborting merges incorrectly: Use git merge --abort to cleanly cancel a conflicted merge
  • Resolving conflicts incorrectly: Test your resolved code before committing
  • Merging the wrong direction: Always merge feature branches into your main branch, not vice versa
  • Ignoring merge commits: They're important historical markers in your repository

Summary

You've learned how to merge branches using both fast-forward and three-way strategies, identify when conflicts occur, and resolve them using Git's conflict markers and tools. Remember that conflicts are normal in collaborative development and represent opportunities to discuss and improve code together.

Quiz

Merging and Resolving Conflicts – Quick Check

What type of merge occurs when the target branch has no new commits since the feature branch was created?

Question 1/5