Last Updated: January 3, 2026
Merging code changes is a fundamental part of working with Git.
When collaborating on software projects, multiple developers often contribute to the same codebase. Merging allows these contributions to be integrated, creating a unified version of the code.
Merging in Git is the process of integrating changes from one branch into another. Branches in Git are simply pointers to specific commits, allowing developers to work on features, fixes, or experiments in isolation. When it’s time to combine those changes, Git performs a merge operation.
At its core, merging is about combining changes from different lines of development. This can happen in various ways, depending on the situation.
By default, Git uses a three-way merge strategy to combine changes. This involves using the latest common ancestor of the two branches being merged along with the changes made in each branch.
To visualize how merging works, it helps to understand the commit graph. Each commit in Git is represented as a node in this graph. When you create a branch, it points to a specific commit. As new commits are added, the branch pointer moves forward, showcasing the evolution of the code.
Here’s a simple representation:
In the example above:
main has commits A, B, and C.feature diverges from commit B and adds commits D and E.When you merge feature back into main, Git needs to reconcile the differences between commits C and E, using commit B as the common base.
The merging process can be broken down into several steps, each critical for a successful integration.
git merge command to start the merge process. Git will automatically find the common ancestor and perform the three-way merge.Let’s see how this works in practice.
If there are no conflicts, Git will create a new commit that combines changes from both branches. If there are conflicts, Git will notify you to resolve them.
When merging, Git can handle the integration in two main ways: creating a merge commit or performing a fast-forward merge. Both end up with the same code, but the history looks different.
A merge commit is created when the branches have diverged (both branches have new commits). Git can’t just “move a pointer,” so it creates a new commit that has two parents: one from the main branch and one from the feature branch.
Here:
A → B → C is the history on main.C → D → E is the history on feature.M is the new merge commit that ties both histories together and has two parents: C and E.This keeps a clear record of when and how the branches were integrated.
A fast-forward merge happens when the target branch (for example, main) has no new commits since the feature branch was created. In that case, Git doesn’t need a merge commit; it simply moves the branch pointer forward.
After a fast-forward merge, main just points to E. No extra merge commit is created, and the history stays perfectly linear.
Many teams choose merge commits for long-running features and fast-forward merges for small, short-lived branches.
To maintain a clean project history and avoid complications, consider the following best practices:
In the next chapter, we will dive deeper into the git merge command itself, examining its options and how to apply them in various scenarios.