Skip to content
Laviyx Learn

Try

Git and GitHub course menu

git rebase Explained: Rebase vs Merge

Learn what git rebase does, how it differs from git merge, how to update a feature branch, resolve rebase conflicts, use --force-with-lease, and the golden rule of rebasing.

Advanced8 min readUpdated
On this page

Your feature branch started from main, and main has moved on. You need to catch up. You can merge, or you can rebase.

What rebase does#

Rebasing takes your commits and replays them, one at a time, on top of another commit, as if you had started your work from there.

Text
Before:
A <--- B <--- E   main
        \
         C <--- D   add-cart

After git rebase main:
A <--- B <--- E   main
               \
                C' <--- D'   add-cart

C' has the same changes as C but is a new commit with a new ID, because its parent has changed.

Try it#

Here is the starting point:

Terminal
git log --oneline --graph --all
Output
* 872a14a Add about page
| * c875d86 Add cart totals
| * 5da6722 Add cart page
|/  
* 7821a43 Add home page

Switch to the feature branch and rebase it onto main:

Terminal
git switch -q add-cart
git rebase main
git log --oneline --graph --all
Output
Successfully rebased and updated refs/heads/add-cart.
* fed1c4d Add cart totals
* a457bdf Add cart page
* 872a14a Add about page
* 7821a43 Add home page

The history is now a straight line, and the commit IDs on add-cart have changed. If main merges the branch now, it is a simple fast-forward:

Terminal
git switch -q main
git merge add-cart
git log --oneline
Output
Updating 872a14a..fed1c4d
Fast-forward
 cart.html | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 cart.html
fed1c4d Add cart totals
a457bdf Add cart page
872a14a Add about page
7821a43 Add home page

Merge or rebase?#

git mergegit rebase
HistoryShows exactly what happened, with merge commitsA straight line
Existing commitsUnchangedRewritten with new IDs
ConflictsFixed onceMay need fixing once per commit
Safe on shared branchesYesNo

Both give the same final files. A common approach is to rebase your own feature branch to keep it tidy, and to merge into main through a pull request.

The golden rule#

Conflicts during a rebase#

Conflicts work like merge conflicts, but Git stops at each commit that has one:

Terminal
git rebase main
Output
Auto-merging title.txt
CONFLICT (add/add): Merge conflict in title.txt
error: could not apply 0f42e82... Add title A
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
hint: Disable this message with "git config set advice.mergeConflict false"
Could not apply 0f42e82... # Add title A

Fix the file, stage it, then continue. Do not run git commit:

Terminal
echo "Title A and B" > title.txt
git add title.txt
git rebase --continue
git log --oneline -n 2
Output
[detached HEAD 544d0bd] Add title A
 1 file changed, 1 insertion(+), 1 deletion(-)
Successfully rebased and updated refs/heads/update-title.
544d0bd Add title A
f8f5e02 Add title B

Git may open your editor so you can confirm the commit message. Save and close it to continue.

CommandWhat it does
git rebase --continueCarry on after fixing a conflict
git rebase --skipDrop the current commit
git rebase --abortCancel, and go back to how things were before

Pushing a rebased branch#

If you have already pushed your branch, a normal push is rejected after a rebase, because the history has changed. For your own branch, force the push safely:

Terminal
git push --force-with-lease

--force-with-lease refuses to overwrite the remote branch if it contains commits you have not seen, which protects a teammate's work. Plain --force has no such check.

Pull with rebase#

If you and a teammate both commit to a branch, this replays your unpushed commits on top of theirs, and avoids an extra merge commit:

Terminal
git pull --rebase

Common mistakes#

Practice#

Practice exercise

feature and main have each gained one commit. Rebase feature onto main, then print the graph of feature.

Show solution
Terminal
git switch -q feature
git rebase -q main
git log --oneline --graph
Output
* 6c48159 Feature work
* dd8004a Two
* ddbda7f One

Key takeaway#

Next: Interactive Rebase.

Finished this lesson?