AlgoMaster Logo

Merging Basics

Last Updated: January 3, 2026

5 min read

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.

What is Merging?

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.

Understanding the Commit Graph

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 Merge Process

The merging process can be broken down into several steps, each critical for a successful integration.

  1. Identify the Branches: Determine which branch you want to merge into and which branch contains the changes.
  2. Perform the Merge: Use the git merge command to start the merge process. Git will automatically find the common ancestor and perform the three-way merge.
  3. Handle Merge Conflicts: If both branches have modified the same lines in ways that conflict, Git will pause the merge and mark the conflicts for you to resolve. This is the subject of later chapters, but it's important to know that conflicts can arise.
  4. Finalize the Merge: Once conflicts are resolved, you can complete the merge either by committing the changes or by continuing the operation if it was paused due to conflicts.

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.

Merge Commit vs. Fast-Forward

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.

Merge Commit

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.

Fast-Forward Merge

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.

Which One to Use?

  • A merge commit makes it explicit when a branch was merged and keeps branch structure visible.
  • A fast-forward keeps history clean and linear but hides the fact that there was a separate branch.

Many teams choose merge commits for long-running features and fast-forward merges for small, short-lived branches.

Best Practices for Merging

To maintain a clean project history and avoid complications, consider the following best practices:

  • Merge Frequently: Regularly merge long-lived branches into the main branch to minimize the chances of complex conflicts. Frequent integration makes it easier to resolve any issues that arise.
  • Use Descriptive Commit Messages: When creating merge commits, provide a clear message describing what changes are included. This helps others understand the context of the merge.
  • Keep Branches Short-Lived: Try to keep feature branches short-lived. This reduces the complexity of merges and helps maintain a clear project history.
  • Test Before Merging: Always run tests on the branch before merging to ensure that the combined code behaves as expected. This can prevent introducing bugs into the main codebase.
  • Use Pull Requests: When working in larger teams or open-source projects, consider using pull requests. They allow for code review and discussion before merging, improving code quality.

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.