When you want to bring changes from one branch into another, Git offers two tools: merge and rebase. They produce different histories, with different trade-offs.
Merge: preserve the real history
git merge takes both branches and creates a merge commit that unites their histories. The graph stays faithful to reality: you can see exactly when the branch diverged and when it was integrated.
The result in git log --graph looks like two parallel lines converging into one point. It is readable, traceable, and non-destructive.
Rebase: linearize the history
git rebase replays your commits on top of another branch. The result: a perfectly linear history, as if you had always worked after the latest commits on main.
Git moves each commit from my-feature one by one, replaying them after the last commit on main. The history becomes a straight line, without a merge commit.
Quick comparison
| Merge | Rebase | |
|---|---|---|
| History | Preserved, with merge commit | Linearized, commits rewritten |
| Safe on shared branch | Yes | No |
| Graph readability | Shows real branches | Clean and linear |
When to use which
- Merge: to integrate a feature into
main, to keep a clear trace of where things came from. The default choice in a collaborative context. - Rebase: to clean up the history of a local branch before opening a pull request. You "rebase onto main" so your PR applies cleanly on top of the latest code.
A common workflow: you work on my-feature, run git rebase main to stay up to date without a spurious merge commit, then open a PR. GitHub then merges with an official merge commit.
