Git Merging Branches and Resolving Conflicts: A Comprehensive Guide

Merging takes the changes from one branch and integrates them into another, typically bringing together different lines of development. While Git does an excellent job of merging changes automatically, there are times when it encounters conflicts that require human intervention to resolve.

Git Merging Branches and Resolving Conflicts: A Comprehensive Guide
Photo by Gabriel Heinzer / Unsplash~

When working with branches in Git, one of the most common tasks is merging. Merging takes the changes from one branch and integrates them into another, typically bringing together different lines of development. While Git does an excellent job of merging changes automatically, there are times when it encounters conflicts that require human intervention to resolve.

In this post, we’ll dive deep into:

  • What merging is in Git
  • Different types of Git merges
  • How to merge branches
  • How to resolve merge conflicts
  • Best practices for handling merges and conflicts

1. What Is Merging in Git?

In Git, merging is the process of combining changes from one branch into another. This usually happens when you’ve been working on a feature branch, and you want to integrate those changes back into the main (or master) branch, or vice versa.

A merge can be as simple as Git recognizing that there are no conflicting changes between branches and automatically combining them. However, if the same lines of code have been modified in both branches, Git will be unable to automatically reconcile them, and this is when merge conflicts arise.

The typical scenario looks like this:

  1. You create a feature branch off the main branch.
  2. You do some work on the feature branch and commit changes.
  3. Other people may be committing changes to main in the meantime.
  4. Eventually, you merge your feature branch back into the main branch, bringing your changes into the project’s main line of development.

2. Types of Git Merges

There are two main types of merges in Git: fast-forward merges and three-way merges. Which type of merge occurs depends on the relationship between the branches being merged.

2.1 Fast-Forward Merge

A fast-forward merge occurs when the branch you’re merging from is a direct descendant of the branch you’re merging into. In this case, Git simply moves the branch pointer forward, incorporating the changes.

Example:

Let’s say you branch off of main to create a feature-login branch. If no changes have been made to main while you were working on your feature-login branch, Git can simply move the main pointer to the latest commit on feature-login.

To perform a fast-forward merge:

git checkout main
git merge feature-login

In this case, no new commits are created, and Git just "fast-forwards" the main branch to point to the same commit as feature-login.

2.2 Three-Way Merge

A three-way merge is needed when the branches being merged have diverged. That is, new commits have been made to both branches, and Git must compare the two branches with their common ancestor to integrate the changes.

In a three-way merge, Git combines the changes from both branches and creates a new commit representing the result of the merge.

Example:

  1. The main branch has moved forward with other commits while you were working on the feature-login branch.
  2. When you try to merge feature-login back into main, Git can’t perform a fast-forward merge and must create a new merge commit that combines changes from both branches.

To perform a three-way merge:

git checkout main
git merge feature-login

3. How to Merge Branches in Git

Merging branches is a straightforward process, but it’s always a good idea to make sure your branches are up to date before merging to avoid potential conflicts.

3.1 Preparing for a Merge

Before you merge, ensure your branches are up to date:

  1. Check out the branch you want to merge into: You need to be on the branch that will receive the changes. In most cases, this will be main.
git checkout main
  1. Pull the latest changes from the remote repository to ensure that your local copy of the branch is up to date.
git pull origin main
  1. Ensure the branch you're merging is up to date. You can check out the branch you want to merge (e.g., feature-login) and run git pull to ensure it's up to date.
git checkout feature-login
git pull origin feature-login

3.2 Merging a Branch

Once both branches are up to date, you can merge the feature branch into your main branch. First, check out the branch you want to merge into (e.g., main), then use the git merge command.

Example:

git checkout main
git merge feature-login

If there are no conflicts, the merge will complete successfully, and Git will either perform a fast-forward merge or create a new merge commit, depending on the situation.

4. What Are Merge Conflicts?

A merge conflict occurs when Git can’t automatically merge changes from different branches because the same part of the code has been changed in both branches in incompatible ways. When this happens, Git requires human intervention to resolve the conflict.

Merge conflicts typically occur when:

  • Two developers have edited the same line of code in different ways.
  • One branch has deleted a file that another branch has modified.
  • Multiple developers have worked on the same sections of a project at the same time.

5. How to Resolve Merge Conflicts

5.1 Identifying a Merge Conflict

When Git encounters a merge conflict, it will stop the merge process and mark the files that need manual intervention. You will see a message similar to the following:

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

Git also adds conflict markers in the file where the conflict occurred.

Conflict Markers:

<<<<<<< HEAD
This is the content from the current branch (e.g., main)
=======
This is the conflicting content from the branch being merged (e.g., feature-login)
>>>>>>> feature-login

5.2 Resolving a Conflict in a Text File

To resolve the conflict, you must manually edit the file to decide which changes to keep. You can:

  • Choose the changes from the current branch (the content before =======).
  • Choose the changes from the branch being merged (the content after =======).
  • Or create a combination of both changes.

Example:

Here’s a conflict in a file called index.html:

<<<<<<< HEAD
<h1>Welcome to My Website</h1>
=======
<h1>Welcome to Our Project</h1>
>>>>>>> feature-login

To resolve this, you can manually edit the file:

<h1>Welcome to My Website - Login Feature</h1>

After resolving the conflict, remove the conflict markers (<<<<<<<, =======, and >>>>>>>), save the file, and mark it as resolved by adding it to the staging area:

git add index.html

5.3 Committing After Resolving a Conflict

Once all conflicts are resolved, and you’ve added the resolved files to the staging area, you can complete the merge by committing the changes:

git commit

Git will create a merge commit, and the conflict will be resolved. If you want to see which commits were merged, you can use:

git log --oneline --graph

This will show a graphical representation of your branch’s history, including the merge commit.

6. Merge Best Practices

Here are some best practices for merging and resolving conflicts:

  1. Pull frequently: Regularly pull changes from the remote repository to avoid large merges and reduce the chance of conflicts.
  2. Work in small increments: Smaller changes are easier to merge and debug.
  3. Communicate with your team: If you're working on critical sections of the codebase, let your team know to avoid conflicts.
  4. Use feature branches: Always create a new branch for every feature or fix to keep your work isolated and easier to manage.
  5. Test before merging: Always test your code before merging to ensure that your changes integrate smoothly with the existing codebase.

Conclusion

Merging branches and resolving conflicts are critical skills for working with Git, especially in collaborative environments. While Git is very efficient at handling merges, conflicts are inevitable when working in a team. By understanding the merge process, practicing conflict resolution, and following best practices, you can streamline your development workflow and reduce the complexity of merging.

Read next