Merge — what it is, merge types and how it works

Author: IT Sectr Published: 2026-05-10 Reading time: 10 min

Merge is an operation in Git that combines changes from one branch into another, creating a merge commit. Git supports several strategies: fast-forward (linear history), three-way merge (with a merge commit) and squash merge (compressing all commits into one). According to git-scm.com, 2025, merge remains the most used code integration mechanism in team Git development.

Key Takeaways

  • Merge — a branch merging operation in Git with or without a merge commit
  • Fast-forward merge — linear merging without an additional commit when there is no divergence
  • Three-way merge — creates a merge commit when branches diverge
  • Squash merge — compresses all branch commits into one before merging
  • Conflicts occur when the same lines are changed in both branches

What is Merge?

Merge is a fundamental operation in Git that combines changes from one branch (source) into another (target). As a result of merging, the target branch receives all commits from the source branch that were not yet in it. Depending on the situation, Git can perform a merge in three different ways.

The main value of merge is preserving history: a merge commit records the fact of branch merging, preserving information about when and which branches were merged. This facilitates change auditing, regression searching, and understanding development chronology. In large projects, merge commit is the standard way of code integration.

According to GitLab Flow, merge commits are used in 73% of teams working with Git. Alternative approaches (rebase, squash) are preferred by teams focused on linear history. The choice of strategy depends on team size, release frequency and accepted project conventions.

When Merge Occurs

Merge is required when a developer has finished working on a feature and wants to integrate it into develop or main. A typical scenario: a developer created a feature branch from develop, worked on it for several days, and during that time new commits from other team members appeared in develop. Before merging, the changes need to be combined — and merge is used for this.

Without merge, it is impossible to collaboratively work on a single codebase in Git. Every time two developers simultaneously make changes to one codebase, their branches diverge. Merge is the only way to bring these changes back together without data loss.

Types of Merging in Git

Git supports three types of merge, each designed for its own scenario. The choice of merge type affects commit history, rollback convenience, and log readability.

Fast-forward merge

Fast-forward occurs when the target branch has had no new commits since the source branch was created. In this case, Git simply moves the target branch pointer forward to the last commit of the source branch. The history remains linear, without a merge commit.

bash
# Fast-forward merge: develop hasn’t changed since feature creation
git checkout develop
git merge feature/new-login

# Result: the develop pointer moved to the end of feature
# No merge commit was created

Fast-forward is convenient for short-lived branches where a developer worked alone. But this approach has a drawback: information that the branch existed is lost — all commits look as if they were made directly to develop.

Three-way merge

Three-way merge is performed when both branches have new commits after the point of divergence. Git creates a separate merge commit with two parents, which records the fact of branch merging. This approach is recommended for feature branches in team development.

bash
# Forced three-way merge with --no-ff flag
git checkout develop
git merge --no-ff feature/new-login

# A merge commit was created with the default message
# You can set your own message via -m
git merge --no-ff feature/new-login -m "Merge feature/new-login into develop"

The --no-ff flag guarantees the creation of a merge commit, even if fast-forward is possible. This is a best practice for preserving branching information in a project.

Squash merge

Squash merge compresses all commits of the source branch into one and applies it to the target. The feature history is lost — one commit with all changes ends up in the branch. This is convenient when detailed commits in a feature branch do not add value to the overall history.

bash
# Squash merge: all feature commits are squashed into one
git checkout develop
git merge --squash feature/experimental
git commit -m "feat: experimental login flow (squashed)"

Squash is suitable for drafts, experimental branches, and situations where it is important to maintain a clean history. The downside is that the connection to the original commits is lost, making it harder to roll back individual changes.

Ours and Theirs Strategies

Ours and Theirs are two special merge strategies in Git. Ours completely ignores changes from the source branch, keeping only what is in the target. Theirs, on the contrary, accepts the source branch version in any conflict. These strategies are useful when merging large amounts of code when it is known in advance which version should prevail.

How Merge Works

The merge mechanism in Git is based on comparing three points: the common ancestor (merge base), the state of the source branch, and the state of the target branch. Git finds the merge base — the last commit common to both branches — and calculates what changes occurred in each branch after divergence.

  • Step 1 — Git determines the merge base: the last commit present in both branches
  • Step 2 — Git builds two diffs: from merge base to source and from merge base to target
  • Step 3 — Git tries to apply both sets of changes to the merge base
  • Step 4 — If the changes do not conflict — merge completes automatically
  • Step 5 — If there is a conflict — Git stops and requests resolution

Git uses a three-way merge algorithm that considers not only the two compared file versions, but also their common ancestor. Thanks to this, Git can automatically resolve situations where changes in one branch do not affect modified areas of the other — even if both files were modified.

How merge works: an example

Consider a scenario: two developers are working on different files in one feature branch. The first changed LoginActivity.kt, the second changed ProfileFragment.kt. When they merge their changes, Git sees that the changes affected different files and performs the merge automatically, without human intervention.

If both developers changed LoginActivity.kt, but in different methods — Git will also handle it automatically, merging changes line by line. A conflict only occurs if both changed the same lines or if one deleted code that the other changed.

Resolving Merge Conflicts

A merge conflict occurs when Git cannot automatically merge changes because both branches modified the same lines differently. In this case, Git marks the conflicting areas in files and awaits manual resolution from the developer.

Conflict areas are marked with special markers: <<<<<<< HEAD shows code from the target branch, ======= is the separator, >>>>>>> source-branch shows code from the source branch. The developer must manually choose which version to keep or combine them.

bash
# 1. Run merge and see the conflict
git merge feature/new-login
# Output: CONFLICT (content): Merge conflict in LoginActivity.kt

# 2. View the list of files with conflicts
git status
# both modified: src/ui/login/LoginActivity.kt

# 3. Resolve the conflict: edit the file, remove markers
# 4. Add the resolved file and finish the merge
git add src/ui/login/LoginActivity.kt
git merge --continue
# or: git commit (without --continue)

There are tools for resolving conflicts: git mergetool opens a visual merger (Meld, Beyond Compare, VS Code). Many developers prefer to resolve conflicts in the IDE — IntelliJ IDEA and Android Studio provide a built-in tool with three-panel comparison that greatly simplifies this process.

Tips for resolving conflicts: always understand what each side of the conflict does, do not delete someone else’s code without understanding its logic, and if the conflict is too complex — involve the authors of both branches in a joint resolution.

Merge vs Rebase: When to Choose What

The choice between Merge and Rebase is one of the most common architectural decisions in Git. Both approaches combine changes, but do it differently: merge preserves branching history, rebase rewrites history making it linear.

  • Merge — preserves context: you can see when and from which branch a merge was made. Better for public branches (develop, main) and teamwork
  • Rebase — creates a clean linear history without extra merge commits. Better for personal feature branches before review
  • Rule: never rebase public branches that other developers are using

Many teams use a hybrid approach: rebase to bring the feature branch up to date with develop (git rebase develop), then merge with the --no-ff flag to record the merge. This gives a clean history within the feature and informative merge points at the develop level.

Frequently Asked Questions

What is the difference between merge and merge --no-ff?

Without --no-ff Git performs a fast-forward merge if possible — it simply moves the branch pointer. With --no-ff Git always creates a merge commit, preserving branching information. Recommended for feature branches in team development.

What to do if a merge conflict is very large?

Use git mergetool or a built-in IDE tool. If the conflict involves dozens of files — the branches may have diverged too much. In this case, discuss the merge plan with the team, possibly splitting it into several stages.

Can a merge be cancelled?

Yes: git merge --abort cancels the merge if it has not yet completed (conflict). If the merge is already complete — use git reset --hard HEAD~1 or git revert -m 1 <merge-commit> for a safe rollback.

Should a merge commit be created for every feature?

Recommended for teamwork. A merge commit records the merge fact, contains references to both branches, and simplifies history understanding. For personal or experimental branches, squash merge or fast-forward is acceptable.

How does merge work with binary files?

Git cannot automatically merge binary files — it selects one version entirely. For binary files (images, .aab, .apk) it is recommended to minimize parallel changes and use Git LFS for large files.

Summary

  • Merge — a basic Git operation for combining changes from one branch into another
  • Fast-forward — linear merging without a merge commit when there is no divergence
  • Three-way merge — creates a merge commit with two parents, preserves context
  • Squash merge — compresses all branch commits into one, losing feature history
  • Conflicts occur when the same lines are changed and are resolved manually
  • Merge differs from Rebase: the former preserves branching, the latter makes history linear
  • For public branches merge with --no-ff is recommended, for personal — rebase or squash

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also