The git rebase command is an advanced operation that allows rewriting the repository’s history, changing the “base” of your current branch to move its commits and apply them sequentially onto the tip of another branch.
So far, the only way we’ve seen to merge code is git merge. Merge is a conservative and safe operation because it respects history as it happened: if two branches advanced in parallel, Git joins them by creating a “merge commit.”
But sometimes history is… ugly. Branches that go in and out, commits with messages like “typo,” “fix,” “wip,” and a graph that looks like a plate of spaghetti and things you want to forget…
To solve this, Git offers us a tool to rewrite history: git rebase.
It is one of Git’s most powerful and elegant utilities, but it is also the most dangerous. Today we will learn how to use it without destroying your work or your teammates’ work.
What is “Re-basing”?
To understand it, let’s look at the name. Re-base, meaning “Change the base.”
Let’s see it with an example.
You create a feature branch from main (at commit A).
You make two commits on your branch (X and Y).
Meanwhile, someone updates main with new commits (B).
Your feature branch originates from commit A. Its base is A.
If we do a traditional Merge, Git creates a merge commit that joins Y and B. The history forks and then joins.
But if we do a Rebase, we tell Git: “Take my commits X and Y from here, and paste them as if they had been born from commit B.”
We are changing the origin point of our branch (and that’s why it’s called rebase).
Rebase vs Merge
Why would we want to complicate our lives by moving commits?
| Feature | git merge | git rebase |
|---|---|---|
| Approach | Preserve history exactly as it happened | Achieve a linear and clean history |
| Result | Graph with forks and merges (Merge Commit) | A single straight line, simulating sequential work |
| Advantage | Safe and non-destructive operation. | Impeccable history (git log), without useless integration commits |
| Disadvantage | Can generate a noisy history (“Guitar Hero effect”) | Rewrites history. Can break the team’s code |
How to do a Rebase
The syntax is simple. If you are on your feature branch and want to update with the latest from main:
git switch feature
git rebase main
What happens internally:
Git “lifts” your commits (X, Y) and saves them temporarily.
Updates your feature branch to point to the same as main (commit B).
Re-applies (“Replay”) your commits one by one onto the new base.
During this process, conflicts may arise. If that happens, Git will stop at each conflicting commit, ask you to resolve it, and then you will continue with git rebase --continue.
Disclaimer incoming
Since Rebase re-applies commits, it generates new Hashes. For Git, the original commit X and the rebased commit X' are two different things.
And we have already learned the most important rule in previous articles.
NEVER perform operations that rewrite history on public branches, including rebase.
If you rebase main on your computer and push it (forcing):
- You have changed history.
- Your teammates still have the “old” history on their computers.
- When they try to sync, Git will see two divergent and incompatible histories 💥.
- The result will be chaos of duplicate commits and horrible conflicts (and they will send a horse head to your house).
When SHOULD you use Rebase?
On local branches or on remote branches that only you use.
- To clean up your
featurebranch before making a Pull Request. - To update with
mainwhile working alone.
