Git Rebase Model: Transplanting Commits onto a New Base
Understand Git rebase as a local history transformation that selects commits after an upstream boundary and reapplies them onto a new base, creating new commit identities.
Advanced
Rebase transplants commits onto a new base
Git rebase reapplies a sequence of commits on top of another base tip. The original commits are not moved in place. When a commit is replayed with a different parent, Git creates a new commit object, so its object ID normally changes.
git log --oneline --graph --decorate --all
git merge-base main topic
git rebase mainQuick check
What is the central operation performed by rebase?
A topic branch has commits after it diverged from main.Those commits are replayed onto the selected base.
The upstream boundary determines the commits to replay
In the common form `git rebase main`, the named upstream provides the new base and the boundary used to identify commits that are on the current branch but not reachable from that upstream. Advanced options such as `--fork-point` can alter selection; they are intentionally outside this foundational model.
git merge-base main topic
git log --oneline main..topic
git switch topic
git rebase mainQuick check
In ordinary `git rebase main`, what does `main` provide?
The topic branch contains commits not reachable from main.The selected topic changes are replayed onto the main tip.
Replayed commits receive new identities
A commit identity includes its parent relationship. Replaying a commit onto a different parent therefore creates a different commit object even when the patch and message are equivalent. The old commit can remain addressable as an object for some time, but the branch name points to the new replayed tip.
old=$(git rev-parse HEAD)
git rebase main
new=$(git rev-parse HEAD)
printf 'old=%s\nnew=%s\n' "$old" "$new"
git merge-base --is-ancestor main "$new"Quick check
Why does a replayed commit normally have a different object ID?
The original topic commit has its original parent.The replayed commit has the selected new base as its parent and therefore a new ID.
A successful rebase moves the rebased branch locally
Rebase is a local history transformation. After the replay succeeds, the rebased branch name moves to the new tip. Other branch names do not move merely because one branch was rebased, and no remote repository is updated by rebase itself.
before=$(git rev-parse topic)
git switch topic
git rebase main
after=$(git rev-parse topic)
printf 'before=%s\nafter=%s\n' "$before" "$after"Quick check
What does a successful rebase move?
The topic branch points at its original tip.The topic branch points at the new replayed tip.
An empty replay can simply advance the branch to the base
If there are no commits to replay, Git does not need to invent new commits. The operation can complete with the branch aligned to the selected base. This is different from a non-empty replay where commit identities are recreated.
git switch topic
git rebase main
git rev-parse HEAD
git merge-base --is-ancestor main HEADQuick check
What can happen when there are no commits left to replay?
The selected changes are already contained by the new base.No new replayed commits are necessary.
Rebase does not publish rewritten history
Rebase does not fetch, merge, or push by itself. If a rewritten branch has already been published, updating the corresponding remote ref is a separate operation and may encounter the non-fast-forward safety boundary covered in Phase 6.
git rebase origin/main
git rev-parse HEAD
git rev-parse origin/main
git status --short --branchQuick check
Which statement correctly describes rebase's remote boundary?
A local branch is being rebased onto a locally available base.Local history changes; the remote remains unchanged until a separate publication operation.
Verify the transformation directly
For a non-empty rebase, do not rely only on terminal output. Record the old tip, perform the rebase, record the new tip, and verify both the changed object ID and the ancestry of the new tip. This gives a state-based proof of the transformation.
old=$(git rev-parse HEAD)
base=$(git rev-parse main)
git rebase main
new=$(git rev-parse HEAD)
printf 'old=%s\nbase=%s\nnew=%s\n' "$old" "$base" "$new"
git merge-base --is-ancestor "$base" "$new"
git log --oneline --graph --decorate --all -8Quick check
What most directly proves that a non-empty rebase changed the branch tip?
The original branch tip and selected base are recorded.The resulting tip is compared with the original and checked for the expected ancestry.
Practice what you learned
Use the dedicated Git code-completion exercise for this lesson.
Thanks for your feedback.
Mark this learning resource complete to track your learning progress.