Merge — what it is, how merge works and merging strategies

Author: IT Sectr Published: 2026-08-01 Reading time: 9 min

Merge is a Git branch merging operation that combines changes from two different development lines into one target branch. Unlike rebase, merge preserves the full branching history by creating a special merge commit with two parents. According to the official Git documentation (2026), merge is the safest way to join branches because it does not rewrite history and allows you to track when and which branches were merged. It is the standard choice for merging in public branches such as main, develop, and release.

Key Takeaways

  • Merge — merging branches by creating a merge commit that preserves the history of both branches.
  • Merge commit — a special commit with two parents that records the merge event.
  • Merging strategies — recursive, octopus, ours, squash — each suited for different scenarios.
  • Conflicts — occur when the same lines are changed in both branches and require manual resolution.
  • Safety — merge does not modify existing commits, so it is safe for public branches.

What is merge in Git

Merge is the git merge command that combines changes from the specified branch into the current one. Git finds the common ancestor (base commit), calculates the diff of each branch relative to the ancestor, and creates a merge commit containing the combined set of changes. The result is that the target branch receives all changes from the merged branch.

Syntax: while on the target branch (e.g., main), execute git merge feature. Git automatically creates a merge commit if there are no conflicts. The default merge commit message reads: “Merge branch 'feature' into main”. You can change the message using the -m flag or edit it in the opened editor.

Merge is a non-destructive operation. Unlike rebase, merge does not touch existing commits: they keep the same hashes, authors, and dates. This makes merge the only safe way to merge branches that multiple developers are working on simultaneously. If something goes wrong, merge can be canceled with git merge --abort.

bash
# Switch to target branch
git checkout main

# Merge feature branch
git merge feature

# Result — merge commit with two parents
git log --oneline --graph

# Merge with custom message
git merge feature -m "feat: integrate authentication module"

Merge types: regular, squash, fast-forward

Git supports three merging modes that are chosen based on the desired outcome. Regular merge (default) creates a merge commit. Squash merge combines all commits from the feature branch into one. Fast-forward moves the branch pointer without creating a commit, if possible. The choice of mode depends on the team's workflow and history rules.

Regular merge (--no-ff) — creates a merge commit even if the merge could be done as fast-forward. Recommended for the main branch: a merge commit clearly marks the feature integration point and makes it easy to revert all feature branch changes with a single merge commit revert. GitHub uses this mode by default when merging PRs with the Merge button.

Squash merge (--squash) — collects all commits from the feature branch into a single commit in the target branch. Useful when the draft history of the feature branch should not pollute main. Drawback: the link to the original commits is lost — you cannot see how the feature was developed step by step. GitHub uses this mode when selecting “Squash and merge” in a PR.

Fast-forward (--ff) — if the target branch has no new commits since the feature branch diverged, Git simply moves the pointer forward without creating a merge commit. The history stays linear. The --no-ff flag forces a merge commit, while --ff-only will error out if fast-forward is not possible.

bash
# Force merge commit (recommended for main)
git merge --no-ff feature

# Squash merge — all commits into one
git merge --squash feature
git commit -m "feat: add authentication"

# Fast-forward only if possible
git merge --ff-only feature

# Abort conflicted merge
git merge --abort

Git merging strategies

Merging strategies determine the algorithm that Git uses to combine changes. Each strategy suits different scenarios. Git automatically selects the appropriate strategy, but developers can specify it explicitly using the --strategy flag. Understanding strategies helps predict Git's behavior during complex merges.

Recursive — the default strategy for merging two branches. Git finds the common ancestor, computes changes in each branch, and merges them. If a common ancestor is found, recursive correctly handles file renames and additions. During conflicts, recursive can use additional options: ours (automatically pick our version) and theirs (pick their version).

Octopus — for merging more than two branches simultaneously: git merge feature1 feature2 feature3. Octopus does not support conflict resolution — all conflicts must be resolved before invoking the command. It is rarely used, mainly for merging several independent branches that are guaranteed not to conflict (e.g., different modules).

StrategyNumber of branchesConflict resolution
Recursive2Automatic + ours/theirs options
Octopus3+No — all conflicts must be resolved beforehand
OursAnyAlways picks our version, ignores foreign changes
Subtree2For subtree merges

Ours — a special strategy that completely ignores changes from the merged branch and keeps the current content of the target branch. A merge commit is created, but the content remains unchanged. Useful when you need to record the fact of a merge in history but actually reject all changes from the other branch.

Resolving merge conflicts

Merge conflict occurs when the same lines of a file were changed differently in both branches. Git cannot automatically determine which version is correct and pauses the merge. A conflict can also arise when a file is renamed in one branch and modified in another, or when the same file is simultaneously deleted and modified.

Resolution process: Git marks conflicted files with markers. The file shows sections with <<<<<<< HEAD (our version), ======= (separator), and >>>>>>> feature (their version). The developer manually edits the conflicted section, selects the desired lines from both versions, removes the markers, saves the file, and adds it to the index with git add.

For visual conflict resolution, Git supports mergetool — an external comparison tool. Popular mergetools: Meld, KDiff3, Beyond Compare, VS Code (built-in conflict editor). Mergetool displays three panels: our version, their version, and the result. The developer visually selects code blocks for inclusion in the final file.

bash
# Start merge and detect conflict
git merge feature
# CONFLICT (content): Merge conflict in src/main.swift

# Check conflicted files
git status

# Open visual mergetool
git mergetool

# After resolution — add and commit
git add src/main.swift
git commit

# Abort merge
git merge --abort

When to choose merge over rebase

Merge is preferable to rebase in several key situations. First: when working with public branches accessible to other developers. Merge does not rewrite history, so colleagues can synchronize safely. Rebasing a public branch creates divergent history and causes conflicts for everyone who already has the old commits.

Second situation: when finishing a feature branch. Most teams prefer merge (with the --no-ff flag) into main to capture the feature integration moment. This simplifies history navigation and makes it easy to revert an entire feature with a single git revert of the merge commit. GitHub Flow by default offers three merge options: simple merge, squash merge, and rebase merge.

Third situation: when working with a reviewed pull request. GitHub and GitLab offer a merge button with different options. Merge (Create a merge commit) — full history with a merge commit. Squash and merge — clean history without development details. Rebase and merge — linear history without a merge commit, but with commit rewriting. The choice depends on team rules.

  • Public branches (main, develop) — only merge, never rebase.
  • PR completion — merge with --no-ff to mark the integration point.
  • Branches with others' commits — merge does not rewrite others' work.
  • Before release — merge is safer because it has fewer risks.
  • Shared branch — if multiple developers work on a branch, merge is mandatory.

Best practices for branch merging

First rule: always be on the latest version of the target branch before merging. Run git checkout main && git pull before merging the feature branch. This minimizes conflicts and ensures the merge commit contains all the latest changes. If the target branch has moved forward significantly, first run git merge main inside the feature branch to resolve conflicts in its context.

Second rule: test the code after merging. Merging can change behavior even if there were no conflicts. The CI/CD pipeline should run tests on the merge commit before sending to production. Some teams use merge gates — mandatory checks that block the merge until they pass.

Third rule: document merge commits. The standard message “Merge branch 'feature' into main” is not very useful. It is recommended to add a description of what was merged: “Merge authentication module: login, registration, password recovery”. This simplifies history analysis and regression searching. In large projects, merge commits are automatically generated from the PR title.

  • Up-to-date — before merging, ensure the target branch is updated (git pull).
  • Testing — CI/CD should run tests on the resulting merge commit.
  • Descriptive messages — specify in the merge commit which feature was merged.
  • Frequency — merge feature branches as early and often as possible (one week maximum).
  • Reverting — git revert of a merge commit rolls back the entire feature.

Frequently Asked Questions

What does it mean to merge branches in Git?

Merge means executing git merge to combine changes from one branch into another. The result is a merge commit that records the merge event and contains changes from both branches. This is the primary way to integrate feature branches into main, develop, or release in Git Flow.

How does squash merge differ from regular merge?

Squash merge combines all commits from the feature branch into a single commit in the target branch, losing the intermediate development history. Regular merge creates a merge commit while preserving all feature branch commits. Squash merge gives a clean history but does not allow tracking the step-by-step development of the feature.

How to resolve a merge conflict in Git?

Open the conflicted file, find sections with <<<<<<< HEAD and >>>>>>> markers. Edit the content, keeping the needed lines from both versions, remove the markers. Save the file, run git add and git commit. You can use git mergetool for visual resolution.

When to use merge instead of rebase?

Merge is always used for public branches (main, develop, release) because it does not rewrite history. Rebase is applied in personal feature branches before they are published. Once a branch has become part of the shared repository and colleagues have accessed it, only merge is allowed.

How to undo a merge in Git?

Before the merge is complete (during a conflict) — git merge --abort cancels the merge entirely. After completion — git revert <merge-commit-hash> -m 1 creates a reverting commit. The -m 1 flag specifies which parent branch to keep (the target one). Git revert is safer than git reset for published branches.

Summary

  • Merge — safe branch merging that preserves history and creates a merge commit with two parents.
  • Merging modes — regular (--no-ff), squash (--squash), and fast-forward (--ff) for different purposes.
  • Strategies — recursive (default), octopus (3+ branches), ours (ignoring foreign changes).
  • Conflicts — resolved manually by editing marked sections or using mergetool.
  • Safety — merge does not modify existing commits, so it is safe for public branches.
  • Squash merge — combines all commits into one, losing intermediate development history.
  • Undoing merge — git revert of a merge commit with the -m 1 flag for safe rollback of published changes.

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