git rebase Explained: Rebase vs Merge, Conflicts and the Golden Rule

Rebase is one of Git’s most powerful and most misunderstood commands. In this lesson you will see exactly what rebasing does, rebase a feature branch, handle conflicts, compare rebase with merge and learn the golden rule that keeps teams safe.

Advertisement

📖 What You’ll Learn: how rebase replays commits, rebasing a feature branch on main, continue, skip and abort, rebase vs merge, the golden rule and force-with-lease, pull –rebase, useful variations like –onto and –autostash, and undoing a rebase with reflog.


🧬 What Does git rebase Do?

git rebase moves a branch so that it starts from a different commit, usually the latest main. Git takes your branch’s commits, sets them aside, updates the base, and replays your commits one by one on top.

Before:                                After: git switch feature && git rebase main
          C3 ── C4 ← feature                               C3' ── C4' ← feature
         /                                                /
C1 ── C2 ── C5 ── C6 ← main            C1 ── C2 ── C5 ── C6 ← main

The replayed commits (C3', C4') have the same changes but new hashes, because their parent changed. The result is a straight, linear history, as if you had started your work after C6.


▶️ Rebasing Step by Step

git switch feature/login-tests
git fetch
git rebase origin/main          # or: git rebase main (after updating main)
Successfully rebased and updated refs/heads/feature/login-tests.

Then fast-forward main (or open a pull request):

git switch main
git merge feature/login-tests    # a fast-forward: no merge commit needed

🧯 Conflicts During a Rebase

Because commits are replayed one at a time, you may resolve conflicts for each commit:

git rebase main
# CONFLICT (content): Merge conflict in tests/login.spec.ts
# fix the file, then:
git add tests/login.spec.ts
git rebase --continue
CommandWhat it does
git rebase --continueContinue after resolving the current commit’s conflicts
git rebase --skipDrop the current commit and continue
git rebase --abortStop and return to the state before the rebase

How to resolve the conflict itself is explained in Resolve Merge Conflicts.


⚖️ Rebase vs Merge

git mergegit rebase
HistoryPreserved exactly, with merge commitsRewritten into a straight line
Commit hashesUnchangedNew hashes for rebased commits
Merge commitsYes (unless fast-forward)No
Conflict resolutionOnce, for the whole mergePossibly once per replayed commit
Safe on shared, pushed branches✅ Yes❌ Not without coordination
Reading historyShows when branches were integratedClean and easy to follow
Typical useIntegrating finished features into mainUpdating your own feature branch with main

A common team approach: rebase your own feature branch on main to keep it up to date and clean, then merge it into main through a pull request.


⚠️ The Golden Rule of Rebasing

⚠️ Common mistake: Do not rebase commits that other people have based work on. Rebasing changes commit hashes; teammates who pulled the old commits will get duplicated commits and confusing conflicts. Rebase only local commits or branches that only you use.

If you rebase a branch you already pushed (your own feature branch), the remote rejects a normal push. Update it safely:

git push --force-with-lease

🔁 Pull with Rebase

Instead of creating “Merge branch ‘main’ of github.com…” commits every time you pull, replay your local commits on top of the remote:

git pull --rebase
git config --global pull.rebase true    # make it the default (optional)

See git fetch vs git pull.


🛠️ Useful Variations

git rebase -i HEAD~3                       # interactive: squash, reword, reorder (next module)
git rebase --onto main old-base feature    # move a branch to a new base, skipping old-base's commits
git rebase main --autostash                # stash uncommitted changes automatically during the rebase

Interactive rebase gets its own lesson in Advanced Git.


🛟 Undo a Rebase

If a rebase went wrong after it finished, find the branch’s previous position in the reflog and reset to it:

git reflog
# a1b2c3d HEAD@{5}: checkout: moving from main to feature/login-tests
git reset --hard HEAD@{5}

More in git reflog.


📝 Assignment

  1. Create feature/rebase-demo from main and make two commits. Make one commit on main.
  2. Rebase the feature branch onto main and compare git log --oneline --graph --all before and after. Note the changed hashes.
  3. Fast-forward main to the rebased branch.
  4. Repeat, creating a conflict on purpose, and resolve it with git rebase --continue.
  5. Start another rebase and cancel it with git rebase --abort.
  6. Push a feature branch, rebase it, and update the remote with --force-with-lease.

❓ FAQ

🤔 What does git rebase do?

It replays the commits of your branch on top of another branch (or commit), giving them a new base and new hashes, which produces a linear history.

🤔 What is the difference between git merge and git rebase?

Merge combines branches and keeps history as it happened, with merge commits. Rebase rewrites your branch’s commits on top of the target, creating a straight history without merge commits.

🤔 When should I not use git rebase?

Do not rebase commits that are on a shared branch others are using, such as main or a branch your teammates pulled.

🤔 How do I abort a rebase?

git rebase --abort returns everything to how it was before the rebase started.

🤔 Why do I need to force push after a rebase?

Rebasing changes commit hashes, so the remote branch no longer matches. Use git push --force-with-lease for your own branch.


🎯 Next Steps

🎬 Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

4 thoughts on “git rebase Explained: Rebase vs Merge, Conflicts and the Golden Rule”

Leave a Comment