Last Updated: January 3, 2026
The git merge command is a powerful feature that allows developers to combine changes from different branches within a Git repository.
While the concept of merging may seem straightforward, understanding the intricacies of how Git performs the merge operation can greatly improve your workflow and help you avoid common pitfalls.
At a high level, git merge combines the changes from one branch into another. The branch you're merging from is often referred to as the "source branch," while the branch you're merging into is called the "target branch." When you execute a merge, Git creates a new commit that represents the combined changes.
This operation relies heavily on Git's internal structure, which consists of three key components: commits, trees, and blobs. Changes in Git are tracked through commits, which form a directed acyclic graph (DAG). Each commit points to its parent commit, and together, they create the history of your project.
When you run git merge, Git is tasked with taking the snapshot of the source branch and applying it to the target branch. The complexity arises from the need to reconcile differences between the two branches, especially when changes have occurred in both branches.
The merge process can be broken down into several steps. Let's take a look at how Git handles this operation under the hood.
Before merging, Git finds a common ancestor between the two branches, known as the merge base. This is the last commit that both branches share. The merge base is crucial because it allows Git to compare the changes made in both branches since that point.
You can visualize this with a simple commit graph:
In this example, the merge base for merging feature into main is commit B.
Once Git identifies the merge base, it creates a new commit that incorporates changes from both branches. This commit will have two parents: the latest commit from the target branch and the latest commit from the source branch.
When you execute:
Assuming there are no conflicts, Git creates a merge commit, which effectively combines the changes from both branches.
While Git strives to automatically merge changes, conflicts may arise if both branches have modified the same line of code differently. In such cases, Git will pause the merge process and prompt you to resolve the conflicts manually.
You can visualize conflicts as:
In this diagram, M represents the merge commit that cannot be completed until conflicts are resolved. Once you resolve the conflicts and stage the changes, you can finalize the merge by creating the commit.
Understanding how to effectively use git merge in various scenarios can significantly enhance your workflow. Here are several common scenarios you may encounter.
When developing a new feature, it's standard practice to create a separate branch. Once the feature is complete, you would merge it back into the main branch.
For example:
This sequence allows you to isolate feature development while keeping the main branch stable.
In many teams, merging is done through pull requests (PRs). A developer creates a PR to propose changes from their branch into a target branch, usually main. This offers a chance for code review and automated testing before finalizing the merge.
Once the PR is approved, a typical workflow would involve:
This method promotes collaboration and ensures code quality through peer reviews.
Git provides different strategies for merging, which can be chosen explicitly. The default strategy is the recursive strategy, but you might encounter situations where you want to specify another method, such as ours or theirs.
To use a specific strategy, you can run:
In this case, the ours strategy would ignore changes from the feature-branch in favor of keeping the current branch's content.
To maintain a smooth workflow and avoid complications, following best practices for merging is essential.
Regularly pull changes from the main branch into your feature branches. This practice reduces the likelihood of conflicts when it's time to merge.
When creating a merge commit, include a message that explains the purpose of the merge. This helps maintain a clear project history.
Always review the changes that will be merged before executing the merge. You can use git log or git diff to inspect the differences.
If possible, run your test suite or build process after merging but before pushing the changes to the remote repository. This ensures that the merged code functions as expected.
Even with best practices, issues can arise during merges. Here are some strategies to help you recover.
If you realize that a merge was a mistake, you can use git reset to revert to the state before the merge:
This command resets your branch to the commit before the merge. Be cautious, as this will discard any uncommitted changes.
If you've already pushed the merge and need to undo it, you can use git revert:
This command creates a new commit that reverses the changes introduced by the merge.
Now that you understand the intricacies of git merge, you are ready to explore the concept of fast-forward merges. In the next chapter, we will look at how this merging technique differs from the standard merge process and when to utilize it for a cleaner commit history.