Rebasing Branches

Reviewed & published by Brayan K

Rebase is Git's tool for a clean, linear history — and one of the most misunderstood. By the end of this lesson you'll know how rebase differs from merge, how to replay your feature branch onto main, how to handle conflicts mid-rebase, and the one golden rule that keeps it safe.

Part of the free Git course at LearnCodingFast — hands-on lessons with worked examples and the output they print, plus practice exercises and a quick quiz.

What You'll Learn

1️⃣ Rebase vs Merge

Both merge and rebase integrate one branch into another, but they leave different histories. Merge preserves both lines and may add a two-parent merge commit. Rebase replays your commits on top of the target's tip as new commits, producing a single linear line with no merge commit. Same end result in your files, very different-looking history.

# MERGE and REBASE both integrate one branch into another, but the
# history they leave behind is different.
#
# Start: main moved on AND your feature has its own commits
#
#         A---B---C  main
#              \
#               D---E  feature
#
# MERGE (git switch main; git merge feature) keeps both lines and adds a
# merge commit M with two parents:
#
#         A---B---C-------M  main
#              \         /
#               D---E---/   feature
#
# REBASE (git switch feature; git rebase main) REPLAYS D and E on top of
# C as brand-new commits D' and E', giving a straight line:
#
#         A---B---C---D'---E'  feature (linear, no merge commit)

2️⃣ Rebasing a Feature onto main

The everyday use of rebase: keep your feature branch current. Switch to the feature branch and run git rebase main. Git replays your commits on top of main's latest tip, rewriting them with new hashes. The result is a tidy, linear history — and a later merge into main can often fast-forward.

# Replay your feature branch onto the latest main.

# 1) Make sure main is up to date (in a real project: git switch main; git pull)
# 2) Switch to your feature branch
git switch feature

# 3) Rebase it onto main — D and E become new commits on top of main's tip
git rebase main

# The commits are REWRITTEN (new hashes), and history is now linear.
git log --oneline --graph --all

3️⃣ Handling Conflicts Mid-Rebase

Because rebase replays commits one at a time, a conflict can pause it partway. Fix the conflict markers in the file, stage it with git add, then run git rebase --continue — not git commit. If you'd rather give up entirely, git rebase --abort returns the branch to exactly where it started.

# A rebase replays commits one by one, so a conflict can stop it midway.

git rebase main
#   CONFLICT (content): Merge conflict in app.js

# 1) Open the file, fix the conflict markers (<<<<<<<, =======, >>>>>>>)
# 2) Stage the resolved file
git add app.js

# 3) Continue the rebase (do NOT run git commit here)
git rebase --continue

# Changed your mind mid-rebase? Bail out and return to the start:
git rebase --abort

4️⃣ The Golden Rule

Never rebase commits you've already pushed and shared. Rebasing rewrites those commits into new ones with different hashes, so anyone who already pulled the originals ends up with a diverged history and painful conflicts. The safe pattern: rebase your own local, unpushed branches; use merge for anything public.

# 🏆 THE GOLDEN RULE OF REBASING:
#   Never rebase commits that you have already pushed and shared.
#
# Rebasing REWRITES commits (new hashes). If teammates already pulled the
# old commits, your rewritten branch no longer matches theirs.

# ✅ SAFE — your own LOCAL, unpushed feature branch:
git switch feature
git rebase main

# ❌ DANGEROUS — a branch others have pulled, or the public main:
#   git switch main
#   git rebase feature      # rewrites shared history — don't

# Rule of thumb: rebase private work, MERGE public work.

Your turn. Bring a feature branch up to date on top of main. Fill in the two blanks.

# 🎯 YOUR TURN — replace each ___ then run it in your terminal.
# Goal: bring your feature branch up to date on top of main, linearly.

# 1) Switch to your feature branch
git switch ___                 # 👉 your feature branch's name

# 2) Replay its commits on top of the latest main
git ___ main                   # 👉 the command that replays commits

# 3) Confirm the history is now a straight line
git log --oneline --graph --all

# ✅ Expected: "Successfully rebased ..." and a single straight line of
#    commits with feature sitting directly on top of main.

Common Errors (and the fix)

Pro Tips

📋 Quick Reference

CommandPurpose
git rebase mainReplay current branch onto main
git rebase --continueProceed after resolving a conflict
git rebase --abortCancel and restore the pre-rebase state
git rebase --skipSkip the current conflicting commit
git log --oneline --graph --allConfirm the resulting history shape

Mini-Challenge: Straighten a Diverged Branch

No commands given this time — just the plan. Diverge two branches, then rebase to make the history linear.

# 🎯 MINI-CHALLENGE: clean up a diverged feature branch.
# No commands given — just the plan. Run each step in your terminal.
#
# 1. From main, create feature and make 2 commits on it
# 2. Switch back to main and make 1 commit there (now they've diverged)
# 3. Draw the graph — confirm the branches forked
# 4. Switch to feature and rebase it onto main
# 5. Draw the graph again — confirm it's now ONE straight line
#
# ✅ Expected: after the rebase, "git log --oneline --graph --all" shows a
#    single linear history with feature on top of main.

# your commands here

🎉 Lesson Complete!

Practice quiz

What does git rebase do?

  • Deletes a branch
  • Merges two branches with a merge commit
  • Replays your commits on top of another branch's tip
  • Pushes to the remote

Answer: Replays your commits on top of another branch's tip. Rebase moves your branch's commits so they sit on top of the target branch.

How does rebase differ from merge in the history it produces?

  • Rebase produces a LINEAR history; merge can add a merge commit
  • Rebase adds a merge commit; merge stays linear
  • They produce identical history
  • Rebase deletes history

Answer: Rebase produces a LINEAR history; merge can add a merge commit. Rebase rewrites commits onto a new base for a straight line; merge may create a two-parent merge commit.

To replay your feature branch onto the latest main, you run...

  • git rebase feature (while on main)
  • git merge --rebase
  • git reset main
  • git rebase main (while on feature)

Answer: git rebase main (while on feature). From your feature branch, git rebase main replays feature's commits on top of main.

Do rebased commits keep their original hashes?

  • Yes, always
  • No — they're rewritten, so they get new hashes
  • Only the first one changes
  • Only on the remote

Answer: No — they're rewritten, so they get new hashes. Rebase creates new commits with new hashes because their base (parent) changed.

What is the GOLDEN RULE of rebasing?

  • Never rebase commits you've already pushed/shared
  • Always rebase main
  • Rebase before every commit
  • Rebase only on Fridays

Answer: Never rebase commits you've already pushed/shared. Rebasing rewrites history, which breaks collaborators who already have those commits.

Why does rebasing shared commits cause problems?

  • It's slow
  • It deletes files
  • Teammates' history diverges from your rewritten commits
  • It can't be pushed at all

Answer: Teammates' history diverges from your rewritten commits. Others still have the old commits; your new hashes no longer match, causing conflicts.

A good use of rebase is...

  • Rebasing the public main branch
  • Updating your LOCAL feature branch onto the latest main before merging
  • Rebasing a teammate's branch
  • Rebasing every release tag

Answer: Updating your LOCAL feature branch onto the latest main before merging. Rebasing your own unpushed feature branch onto main gives a clean, up-to-date history.

If a rebase hits a conflict, which command continues after you fix it?

  • git rebase --skip-all
  • git merge --continue
  • git commit --rebase
  • git rebase --continue

Answer: git rebase --continue. After resolving and staging the conflict, git rebase --continue proceeds.

How do you abandon a rebase and return to where you started?

  • git reset --hard
  • git rebase --abort
  • git rebase --undo
  • Ctrl+C only

Answer: git rebase --abort. git rebase --abort restores the branch to its pre-rebase state.

After a successful `git rebase main` on feature, what often happens on main?

  • main is deleted
  • main rewinds
  • A later git merge of feature into main can fast-forward (linear)
  • Nothing can be merged

Answer: A later git merge of feature into main can fast-forward (linear). Because feature now sits directly on top of main, merging it can fast-forward cleanly.

Continue this course

Frequently asked questions

What is the difference between rebase and merge?

Both combine work from two branches. Merge keeps both lines of history intact and, when they've diverged, records a merge commit with two parents — an honest record of when things came together. Rebase instead replays your branch's commits on top of the target branch's tip, rewriting them as new commits to produce a single straight line. Merge preserves history exactly; rebase rewrites it for cleanliness.

Does rebasing lose my commits?

No — your commits' changes are preserved, but the commits themselves are rewritten with new hashes because their parent (base) changed. So you keep all your work; what changes is the commits' identity and position in history. If a rebase ever goes wrong, git rebase --abort returns you to exactly where you started, and git reflog can recover the originals.

What's the golden rule of rebasing?

Never rebase commits you've already pushed and shared. Rebasing rewrites those commits into new ones with different hashes, so any teammate who already pulled the originals now has a history that diverges from yours, causing painful conflicts. The safe pattern is: rebase your own local, unpushed branches; use merge for anything already public.

A rebase stopped with a conflict — what do I do?

Rebase applies your commits one at a time, so a conflict pauses the process. Open the conflicted file, resolve the <<<<<<< / ======= / >>>>>>> markers, then stage it with git add. Crucially, don't run git commit — instead run git rebase --continue to move on to the next commit. If you'd rather give up, git rebase --abort restores the branch to its pre-rebase state.

When should I rebase instead of merge?

Rebase shines for keeping a local feature branch current: before merging your feature into main, rebase it onto the latest main so your work sits cleanly on top and the eventual merge can fast-forward. Use merge when integrating shared branches or when you want history to faithfully record that two lines of work came together. A common team policy is rebase locally, merge to share.

Related lessons