DevToolBoxGRATIS
Blog

Git Rebase vs Merge: Quando usare quale (con esempi visivi)

10 min di letturadi DevToolBox

The rebase vs merge debate is one of the most common discussions in Git workflow. Both commands integrate changes from one branch into another, but they do it in fundamentally different ways. Understanding when to use each is crucial for maintaining a clean, navigable project history.

How Git Merge Works

Git merge creates a new "merge commit" that ties together the histories of both branches. It preserves the complete history and chronological order of commits.

When you run git merge feature, Git finds the common ancestor of both branches, then creates a new commit that combines the changes from both.

          A---B---C  feature
         /         \
    D---E---F---G---H  main (merge commit)

$ git checkout main
$ git merge feature

How Git Rebase Works

Git rebase moves (or "replays") your commits on top of another branch. It rewrites commit history to create a linear sequence of commits.

When you run git rebase main from your feature branch, Git takes each commit in your branch, temporarily removes it, updates your branch to match main, then re-applies each commit one by one on top.

Before rebase:
          A---B---C  feature
         /
    D---E---F---G  main

After rebase:
                    A'--B'--C'  feature
                   /
    D---E---F---G  main

$ git checkout feature
$ git rebase main

Visual Comparison

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘              MERGE RESULT                 โ•‘
โ•‘                                           โ•‘
โ•‘    D---E---F---G---H  main                โ•‘
โ•‘         \       /                          โ•‘
โ•‘          A---B---C  feature               โ•‘
โ•‘                                           โ•‘
โ•‘  โœ“ Preserves all commits                  โ•‘
โ•‘  โœ“ Shows merge point                      โ•‘
โ•‘  โœ— Non-linear history                     โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘              REBASE RESULT                โ•‘
โ•‘                                           โ•‘
โ•‘    D---E---F---G---A'--B'--C'  main       โ•‘
โ•‘                                           โ•‘
โ•‘  โœ“ Clean linear history                   โ•‘
โ•‘  โœ“ Easy to read                           โ•‘
โ•‘  โœ— Rewrites commit hashes                 โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

When to Use Merge

  • Public/shared branches โ€” Merge never rewrites history, so it is safe for branches others are working on.
  • Preserving context โ€” The merge commit shows when a feature branch was integrated and by whom.
  • Team collaboration โ€” When multiple people work on the same branch, merge avoids conflicts from history rewriting.
  • Release branches โ€” Merging release branches preserves the exact integration point.
# Merge with merge commit (recommended for main)
$ git checkout main
$ git merge --no-ff feature
$ git push origin main

When to Use Rebase

  • Feature branches (before merging to main) โ€” Rebase creates a clean linear history before the final merge.
  • Keeping up to date โ€” Rebase your feature branch onto the latest main to get new changes without merge commits.
  • Before PR submission โ€” A rebased branch with clean commits is easier to review.
  • Cleaning up local commits โ€” Interactive rebase lets you squash, reorder, and edit commits before sharing.
# Update feature branch with latest main
$ git checkout feature
$ git rebase main

# If conflicts occur, resolve them, then:
$ git add .
$ git rebase --continue

Interactive Rebase: Squash, Fixup, Reorder

Interactive rebase (git rebase -i) is one of the most powerful Git features. It lets you modify commits before sharing them.

$ git rebase -i HEAD~4

# Editor opens:
pick a1b2c3d Add user authentication
pick e4f5g6h Fix typo in auth
pick i7j8k9l Add password validation
pick m0n1o2p Fix lint error

# Change to:
pick a1b2c3d Add user authentication
fixup e4f5g6h Fix typo in auth       # merge into previous, discard message
pick i7j8k9l Add password validation
fixup m0n1o2p Fix lint error          # merge into previous, discard message

# Result: 2 clean commits instead of 4

# Commands:
# pick   = use commit as-is
# squash = merge into previous commit, keep message
# fixup  = merge into previous commit, discard message
# reword = use commit but edit message
# drop   = remove commit entirely

The Golden Rule: Never Rebase Public Branches

If a branch has been pushed and others are working on it, DO NOT rebase it. Rebase rewrites commit hashes, which means other developers will have divergent histories and will face painful merge conflicts.

Golden Rule: Only rebase commits that have NOT been pushed to a shared remote, or that only you are working on.

# โŒ DANGEROUS: Rebasing a shared branch
$ git checkout main
$ git rebase feature  # NEVER do this!

# โœ… SAFE: Rebasing your own feature branch
$ git checkout my-feature    # only I work on this
$ git rebase main            # safe!
$ git push --force-with-lease origin my-feature

Merge vs Rebase: Complete Comparison

CriteriaMergeRebase
HistoryNon-linear, preserves branchesLinear, clean
Commit hashesPreservedChanged (new hashes)
Conflict resolutionOnce (in merge commit)Per commit (may resolve multiple times)
TraceabilityHigh (merge commit shows context)Medium (linear but no branch info)
SafetySafe (no history rewrite)Risky (rewrites history)
For shared branchesโœ…โŒ
For personal branchesโœ…โœ…
ReversibilityEasy (git revert)Harder (requires reflog)
git bisectHarder (non-linear)Easier (linear history)

Common Git Workflows

Feature Branch Workflow

Create a feature branch, develop, rebase onto main, then merge with --no-ff. This gives a linear history with clear merge points.

$ git checkout -b feature/login
# ... develop ...
$ git rebase main              # clean up history
$ git checkout main
$ git merge --no-ff feature/login  # merge with commit
$ git branch -d feature/login

Gitflow Workflow

Uses develop, feature, release, and hotfix branches. Always merge (never rebase) between long-lived branches.

# Always merge between long-lived branches
$ git checkout develop
$ git merge --no-ff feature/login
$ git checkout release/1.0
$ git merge --no-ff develop
$ git checkout main
$ git merge --no-ff release/1.0
$ git tag v1.0

Trunk-Based Development

Short-lived feature branches (< 1 day). Rebase onto main frequently, merge quickly. Favored by high-performing teams.

# Short-lived branch, rebase often
$ git checkout -b fix/typo
# ... quick fix ...
$ git rebase main
$ git checkout main
$ git merge fix/typo    # fast-forward
$ git push

Dangerous Scenarios

ScenarioRiskPrevention
Rebase main/masterEveryone's history breaksNever rebase main
Rebase shared feature branchCollaborators face divergent historyUse merge for shared branches
git push --forceOverwrites remote changesUse --force-with-lease instead
Wrong conflict resolution during rebaseCode loss or corruptionReview each conflict, use git rebase --abort to restart
Rebase branch with merge commitsMerge commits flattened, confusingUse --rebase-merges or avoid

Frequently Asked Questions

Can I undo a rebase?

Yes. Use git reflog to find the commit hash before the rebase, then git reset --hard <hash> to restore it. The reflog keeps a record of all HEAD movements for 90 days by default.

Should I rebase or merge when updating my feature branch?

If you are the only person working on the feature branch, rebase is preferred for a cleaner history. If others are also working on it, use merge to avoid rewriting shared history.

What is git pull --rebase?

Instead of merging the remote branch into your local branch (creating a merge commit), git pull --rebase replays your local commits on top of the remote changes. It keeps your history linear.

What happens if I rebase a branch that has been pushed?

You will need to force push (git push --force-with-lease). Anyone who has pulled the old commits will have divergent history and will need to reset or re-clone. This is why you should only rebase branches that you alone work on.

Is squash merge the same as rebase + squash?

Similar result, different mechanism. GitHub's "Squash and merge" button squashes all commits into one and creates a merge commit. Rebase -i with squash lets you choose which commits to combine and gives you more control.

Which is better for open source contributions?

Most open source projects prefer rebased, clean commits. Before submitting a PR, rebase onto the latest main and squash fixup commits. This makes the PR easier to review and the history cleaner.

๐• Twitterin LinkedIn
รˆ stato utile?

Resta aggiornato

Ricevi consigli dev e nuovi strumenti ogni settimana.

Niente spam. Cancella quando vuoi.

Prova questi strumenti correlati

๐Ÿ”€Git Command Generator.gi.gitignore GeneratorยฑText Diff Checker

Articoli correlati

Git Commands Cheat Sheet: Comandi essenziali per ogni sviluppatore

Cheat sheet completo dei comandi Git: setup, branching, merging, rebasing, stashing e workflow avanzati.

Git cherry-pick, revert e reset spiegati

Impara quando usare git cherry-pick, revert e reset. Differenze, casi d'uso e considerazioni sulla sicurezza.