Komitly
BlogPricing
Home/Blog/git merge vs git rebase: When to Use Each
BranchingIntermediate

git merge vs git rebase: When to Use Each

Komitly·February 26, 2026·10 min read
git mergegit rebasemerge conflictsbranch strategy
Loading article...

On this page

  • The problem: diverged branches
  • How merge works
  • How rebase works
  • Side-by-side comparison
  • When to use each
  • Merge preview in Komitly
  • The golden rule of rebase

Try it visually with Komitly

Stop memorizing commands. See your branches, commits, and merges in a beautiful visual interface.

Download Komitly — Free

Related articles

BranchingBeginner

Git Branches Explained: Create, Switch, and Manage

Understand Git branches from the ground up. Learn to create, switch, list, and delete branches with clear examples and visual explanations.

git branchgit switchgit checkout -b
7 min
BranchingBeginner

Resolving Merge Conflicts: A Step-by-Step Guide

Learn how to read and resolve Git merge conflicts with confidence. Understand conflict markers, resolve step by step, and use visual tools to make the process painless.

git mergegit merge --abortgit add
10 min
BasicsBeginner

git init: Creating Your First Repository

Learn how to create a Git repository from scratch. Understand what git init does, what's inside the .git folder, and how to make your first commit.

git initgit addgit commit
6 min

© 2026 Komitly

support@komitly.com
BlogPricingChangelogTermsPrivacy

The problem: diverged branches

Imagine you are working on a feature/login branch. While you were building the login page, a teammate pushed a security fix and a dependency update to main. Now the two branches have diverged — each has commits the other does not.

Diverged branches
d4e5f6aAdd login validationfeature/login
c3d4e5fStyle login form
f6a7b8cUpdate dependenciesmain
e5f6a7bFix security vulnerability
b2c3d4eRelease v1.0
a1b2c3dInitial commit

The graph above shows the situation. main moved forward with two commits (security fix, dependency update), and feature/login has its own two commits (style login form, add validation). They share a common ancestor at Release v1.0.

You need to bring these branches back together. Git gives you two strategies: merge and rebase. They achieve the same goal — combining work from two branches — but they do it in very different ways, and the resulting history looks different.

How merge works

A merge takes the two diverged branch tips and their common ancestor, and creates a new merge commit that ties everything together. This is called a three-way merge because Git looks at three snapshots: the common ancestor, the tip of the current branch, and the tip of the branch being merged.

Merging a branch
$ git merge feature/login

Hover over each part to see what it does

After the merge, the history looks like this:

After merge
g7h8i9jMerge branch 'feature/login' into mainmain
d4e5f6aAdd login validationfeature/login
c3d4e5fStyle login form
f6a7b8cUpdate dependencies
e5f6a7bFix security vulnerability
b2c3d4eRelease v1.0
a1b2c3dInitial commit

Notice the merge commit at the top. It has two parents — one from each branch. This is what makes it a merge commit. All the original commits remain exactly as they were: their hashes, dates, and messages are unchanged.

Key characteristics of merge

  • Non-destructive — existing commits are never modified. Their hashes stay the same.
  • Creates a merge commit — adds one extra commit to the history that records when the branches were combined.
  • Preserves context — you can always see when a feature branch was integrated and trace both lines of development.
  • Can make history noisy — in active repositories with many branches, frequent merge commits can clutter the graph.

How rebase works

Instead of creating a merge commit, rebase takes your feature branch commits and replays them on top of the target branch. The result is a perfectly linear history — as if the feature work was done after all the main branch changes, not in parallel.

Rebasing onto main
$ git rebase main

Hover over each part to see what it does

After the rebase, the commit graph is linear:

After rebase
x9y0z1aAdd login validationfeature/login
w8x9y0zStyle login form
f6a7b8cUpdate dependenciesmain
e5f6a7bFix security vulnerability
b2c3d4eRelease v1.0
a1b2c3dInitial commit

The feature branch commits now sit on top of the latest main commit. Notice that their hashes have changed — c3d4e5f became w8x9y0z and d4e5f6a became x9y0z1a. This is because rebase creates new commits with the same changes but different parents, which means different hashes.

Handling conflicts during rebase

Because rebase replays commits one by one, you might encounter conflicts at each step. Git pauses the rebase and lets you resolve the conflict before continuing:

Rebase conflict
$ git rebase main
CONFLICT (content): Merge conflict in src/auth.ts
error: could not apply c3d4e5f... Style login form
Resolve the conflict, then:
$ git add src/auth.ts
$ git rebase --continue
Or abort the entire rebase:
$ git rebase --abort

This is different from merge conflicts. With a merge, you resolve all conflicts at once in the merge commit. With a rebase, you might need to resolve conflicts multiple times — once for each commit being replayed. This can be more tedious, but it has an upside: each commit in the rebased branch is guaranteed to be a clean, working state.

Key characteristics of rebase

  • Produces linear history — no merge commits, no forks in the graph. The history reads like a simple list.
  • Rewrites commit hashes — every replayed commit gets a new hash. The content is the same, but the identity changes.
  • Conflicts per commit — you resolve conflicts as each commit is replayed, which can mean more conflict resolutions but cleaner individual commits.
  • Loses branch topology — after rebase, you cannot tell that the feature work was done in parallel. The history looks sequential.

Side-by-side comparison

Here is a direct comparison of the two strategies:

Aspectgit mergegit rebase
History shapeNon-linear (diamond/fork pattern)Linear (straight line)
Extra commitsCreates a merge commitNo extra commits
Original hashesPreservedChanged (new hashes)
Conflict resolutionOnce, in the merge commitPer replayed commit
Safe for shared branchesYesNo (rewrites history)
Best forIntegrating completed featuresKeeping local branches up to date

Neither strategy is universally better. They solve different problems and are often used together in the same workflow.

When to use each

Use merge when...

  • Integrating a completed feature into main — the merge commit serves as a clear marker that a feature was completed and integrated.
  • Working on shared branches — if other people have pulled the branch, merge is the safe choice because it does not rewrite history.
  • You want an audit trail — merge commits record exactly when branches were combined, which is useful for debugging and compliance.
  • Pull request workflows — most teams merge PRs rather than rebase them, because it preserves the review context.

Use rebase when...

  • Keeping a feature branch up to date — while you work on a feature, you can regularly rebase onto main to incorporate upstream changes and avoid a big conflict at the end.
  • Cleaning up before merging — use git rebase -i (interactive rebase) to squash, reorder, or edit commits before submitting a pull request.
  • You prefer a linear history — some teams require a linear main branch for readability. Rebase before merge achieves this.
  • Working on a local, unpushed branch — if no one else has seen your commits, rewriting history is perfectly safe.

A common workflow: rebase then merge

Many teams combine both strategies. While developing a feature, you rebase your branch onto main to stay up to date. When the feature is done, you merge it into main (often via a pull request). This gives you the best of both worlds: clean individual commits from rebase, plus a merge commit marking when the feature landed.

bash
git checkout -b feature/login\n# ... write code, make commits ...
bash
git fetch origin\ngit rebase origin/main
bash
git rebase -i origin/main
bash
# On GitHub / in Komitly:\n# Create PR -> Review -> Merge

Merge preview in Komitly

One of the trickiest parts of merging is not knowing what will happen until you actually run the command. Will it be a clean merge? Will there be conflicts? Which files are affected?

Komitly solves this with a merge preview that runs a dry-run merge in memory before touching your working directory. When you initiate a merge, Komitly first shows you a prediction of the result:

Komitly — Merge Preview
feature/loginintomain
m1n2o3pMerge 'feature/login' into main (preview)main (predicted)
d4e5f6aAdd login validationfeature/login
c3d4e5fStyle login form
f6a7b8cUpdate dependenciesmain
e5f6a7bFix security vulnerability
b2c3d4eRelease v1.0
a1b2c3dInitial commit
src/login.tsxclean merge
src/auth.tsclean merge
package.jsononly in main

The merge preview categorizes every affected file:

  • Clean merge (green) — the file was modified in both branches but Git can combine the changes automatically
  • Conflict (red) — the file has overlapping changes that require manual resolution
  • Only in source (purple) — the file was only changed in the feature branch
  • Only in target (blue) — the file was only changed in the target branch

If conflicts are detected, you can see exactly which files will conflict before running the merge. This lets you prepare — you might choose to resolve issues in the feature branch first, or switch to a rebase strategy to handle conflicts one commit at a time.

Komitly also supports visual rebase planning. You can drag and drop commits to reorder them, mark commits for squash, and see a conflict prediction for each step of the rebase — all before executing it.

The golden rule of rebase

Never rebase commits that have been pushed to a shared remote branch.

This is the single most important rule to internalize about git rebase. The reason comes down to what rebase actually does: it creates new commits with new hashes. If someone else has already pulled the original commits, their history and yours will diverge in a confusing way.

Here is what happens when you violate this rule:

The danger of rebasing shared branches
$ git rebase main
Successfully rebased and updated refs/heads/feature/login.
$ git push
! [rejected] feature/login -> feature/login (non-fast-forward)
error: failed to push some refs to 'origin'
Rebase rewrote history. You would need --force to push.
This is dangerous if others have pulled this branch!

After a rebase, git push fails because your local history no longer matches the remote. The only way to push is with --force (or the safer --force-with-lease). But if a teammate already has the old commits, force-pushing will cause them to see duplicate or missing commits, broken merges, and general confusion.

When force-push is acceptable

Force-pushing after a rebase is fine in exactly one scenario: when you are the only person working on the branch. This is common for personal feature branches that exist only as draft pull requests. In that case:

bash
# Safe: use --force-with-lease instead of --force\n# It will fail if someone else pushed to the branch\ngit push --force-with-lease

--force-with-lease is a safer alternative to --force. It checks that the remote branch is still where you expect it to be. If someone else pushed a commit since your last fetch, the push is rejected — protecting you from accidentally overwriting their work.

A simple decision framework

bash
git rebase main
bash
git rebase main\ngit push --force-with-lease
bash
git merge main

Merge and rebase are not competitors — they are complementary tools. Rebase keeps your local work clean and up to date. Merge records the integration of completed work into shared branches. Use the right tool for each situation, respect the golden rule, and your Git history will be both clean and trustworthy.