iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

git rebase

git rebase replays your commits on top of another base. The result is a linear history with no merge commits — cleaner log, but rewrites SHAs and (if pushed) breaks others.

Plain + interactive + golden rule

EXAMPLE
# 1) Rebase feature onto the latest main
git switch feature/add-cart
git fetch origin
git rebase origin/main
# Replays each commit on feature on top of origin/main.
# Resolve conflicts as they appear:
#   git status
#   <edit files>
#   git add <files>
#   git rebase --continue
#   git rebase --abort    # bail out, return to pre-rebase state

# 2) Interactive rebase — edit history
git rebase -i origin/main
# Opens an editor with:
#   pick a3b1c2d  add cart UI
#   pick 9f4e1b2  fix bug
#   pick 0a8c5d1  rename function
# Change `pick` to:
#   r  reword     - keep the commit, edit the message
#   e  edit       - stop here to make changes / amend
#   s  squash     - combine into the previous commit (keep message)
#   f  fixup      - combine into the previous commit (drop this message)
#   d  drop       - throw the commit away
# Reorder lines to reorder commits.

# 3) Squash a feature into one commit before merging
git rebase -i origin/main
# Mark all but the first as `squash` or `fixup`
# Final result: one clean commit on the branch

# 4) Move a branch onto a different base
git rebase --onto new-base old-base feature/foo
# Replays only commits between old-base and feature/foo, onto new-base
# Use case: you branched off the wrong place

# 5) Pull-with-rebase — keeps history linear
git pull --rebase
# Or set globally:
git config --global pull.rebase true
git config --global rebase.autoStash true

# 6) Autosquash workflow — fix commits, squash later
git commit --fixup <SHA>      # creates 'fixup! <original subject>'
git rebase -i --autosquash origin/main
# Editor opens with fixups pre-arranged below their target — confirm and exit

# 7) The GOLDEN RULE
#   Never rebase commits you've ALREADY pushed AND others may have pulled.
#   Rebase rewrites SHAs; collaborators see divergent histories and their next push fails.
#   Exception: solo branches that nobody else has touched.

# 8) When you must rebase a pushed branch — force push SAFELY
git push --force-with-lease
# Refuses to push if the remote moved since your last fetch (catches teammates' pushes)
# Always prefer --force-with-lease over plain --force.

# 9) Recover from a botched rebase
git reflog                   # shows every HEAD movement
# 0f3a91e HEAD@{0}: rebase finished: returning to refs/heads/feature
# 7d2b8c1 HEAD@{1}: rebase: ...
git reset --hard HEAD@{4}    # jump back to the pre-rebase state

# 10) Rebase vs Merge — pick one team policy
# Rebase (linear history):
#   git rebase main → git push --force-with-lease (PR squash-merges)
# Merge (preserve branches):
#   git merge main → git push (regular merge or merge commit)
# Mixing both makes git log unreadable.

# 11) rerere — git remembers your conflict resolutions
git config --global rerere.enabled true
# Re-applies the same fix automatically next time the same conflict appears

# 12) Inspect what a rebase will do (dry run)
git log --oneline origin/main..HEAD       # commits that will be replayed

Why it matters

The golden rule of rebase: never rewrite history that’s already shared. --force-with-lease is the only force-push you should ever use — it refuses if a teammate pushed first.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
git switch feature
git rebase main         # replay feature on top of main
git rebase --continue   # after resolving conflicts
Try it Yourself »

Discussion

Loading…