Rebase, Interactive Rebase, Cherry-Pick, Amend, and Safe History Editing: Concepts, Architecture, and Mental Model
Understand Git history editing as graph reconstruction: rebase replay, interactive todo operations, cherry-pick, amend, old/new reachability, reflog safety, and the unpublished-versus-shared history boundary.
Learning objectives
- Explain why rebase creates replacement commits and why their object IDs change.
- Distinguish old object existence from current ref reachability after a rewrite.
- Interpret interactive rebase actions such as pick, reword, edit, squash, fixup, and drop.
- Explain cherry-pick as replaying selected changes and amend as replacing the current commit.
- Apply a publication/consumption boundary before deciding whether a rewrite is appropriate.
1. The problem — good work can still have a bad local history
Chapter 08 treated a topic branch as a reviewable series. While developing that series you may create commits such as “WIP,” forget a file, discover that two commits belong together, or learn that the target branch has moved. If the series is still private and unpublished, Git can reconstruct it into a cleaner graph before other people depend on the original commit IDs.
The important word is reconstruct. Rebase, cherry-pick, and amend do not reach into an existing commit object and edit it. They create replacement commits and move refs. Once collaborators have consumed the old IDs, that distinction becomes a coordination and provenance problem, not merely a syntax choice.
2. Read the graph before rewriting it
git status --short --branch
git branch -vv
git log --graph --decorate --oneline --all --max-count=25
git rev-parse --verify HEAD
git merge-base trunk HEAD
git log --oneline trunk..HEAD
git reflog -8
These commands establish the current branch, upstream relationship, exact tip OID, common base, commits unique to the topic, and recent local ref movement. A safe rewrite begins with evidence that answers “which branch am I changing?” and “which commits will be replaced?”
3. Rebase is replay plus ref movement
Suppose a private topic contains commits A,
B, and C on an old base E,
while trunk has advanced to G. A normal
rebase identifies the topic changes, checks out the new base
internally, reapplies those changes one by one, then moves the topic
branch to the final replacement commit.
flowchart TD D[D] --> E[E old base] E --> A[A old] A --> B[B old] B --> C[C old topic tip] E --> F[F] F --> G[G new trunk] G --> AP[A' replacement] AP --> BP[B' replacement] BP --> CP[C' new topic tip] R[refs/heads/topic] --> CP OLD[old commits A-B-C] -. may remain reachable via reflog/other refs .-> C
The new commits introduce corresponding changes, but their parents
differ. Because a commit object includes its parent OID as part of
its content, changing the parent necessarily changes the commit OID.
Committer metadata can also differ. The branch ref moves to
C'; the old C does not become “edited C.”
4. Rewriting changes reachability, not object history retroactively
Before the rewrite, the topic ref reaches A-B-C.
Afterward it reaches A'-B'-C'. The old objects may
still exist because a reflog, backup branch, tag, another clone,
remote ref, or other reference still reaches them. If nothing
retains them forever, later maintenance may eventually make them
unavailable.
This is why reflog is a useful local safety net, but not a collaboration contract. Another clone has its own reflogs and may retain a completely different set of old tips.
5. Interactive rebase edits a replay plan
git rebase -i <upstream> opens a todo list.
Unlike normal git log, the todo is executed
top to bottom, oldest selected commit first. The
most important actions are:
| Todo action | Meaning | Graph effect |
|---|---|---|
pick |
Replay the commit normally | Usually creates replacement commit when replay is needed |
reword |
Replay, but edit the message | New commit ID |
edit |
Pause so content/commit can be changed | Replacement commit after continue |
squash |
Combine with previous todo commit and edit combined message | Multiple old commits become fewer new commits |
fixup |
Combine with previous commit while discarding the fixup message by default | Multiple old commits become one replacement |
drop |
Intentionally omit a commit | That change is absent unless represented elsewhere |
rebase.missingCommitsCheck=warn or error;
using the explicit drop action makes intent visible.
6. Cherry-pick replays selected changes onto another tip
git cherry-pick <commit> computes the change
introduced by the selected commit relative to its parent, applies
that change to the current HEAD, and normally creates a
new commit. The source commit does not move from its branch.
flowchart LR S0[S0] --> S1[S1 source change] T0[T0 target tip] --> S1P[S1' replayed change] S1 -. selected patch/change .-> S1P SRC[source branch] --> S1 DST[target branch] --> S1P
The new commit normally has a different parent and committer context, so its OID differs. Later merging the source branch does not magically identify the two commits as the same object, even when their content changes are patch-equivalent.
7. Amend replaces the current commit
git show --no-patch --format=fuller HEAD
git rev-parse HEAD
# after intentionally staging the correction:
git commit --amend
Amend creates a replacement for HEAD, usually with the
same parent but potentially different tree, message,
author/committer metadata, or signature. The branch moves from the
old commit to the new one. Even changing only the commit message
changes the object ID.
8. The public-history boundary
| History state | Typical rewrite posture |
|---|---|
| Private local branch, nobody else consumes it | Cleanup is usually reasonable after inspection |
| Pushed review branch, policy explicitly allows author rewrites | Coordinate; use guarded force update if replacing the remote ref |
| Branch consumed by teammates or automation by exact OID | Prefer additive correction; rewriting invalidates their anchors |
| Published release/support/production provenance | Usually preserve and add corrective commits unless governance explicitly authorizes rewrite |
A technically successful rebase can still be operationally wrong if dashboards, artifacts, SBOMs, deployments, signatures, reviews, or incident records refer to the old OIDs.
9. Why this matters in DevOps
Clean unpublished history can improve code review, bisectability, release-note generation, and automated policy checks. Careless shared-history rewriting can instead break source provenance, invalidate review references, confuse deployment records, and overwrite collaborators' remote work. The operating model therefore needs both syntax and a rewrite policy.
10. Micro-lab — prove amend creates a replacement
git rev-parse HEAD
git show --no-patch --format='%H %P %s' HEAD
git commit --amend --no-edit
git rev-parse HEAD
git reflog -3
With identical staged content and message, Git still creates a new commit because committer metadata normally changes. The reflog records branch-tip movement, which is why the previous tip can often still be inspected locally.
11. Knowledge check
Question 1. Why does rebasing normally change commit IDs even when the final files look identical?
Question 2. Does cherry-pick move the selected source commit to the current branch?
Question 3. What is the difference between
squash and fixup in an interactive
todo?
Question 4. Why is amend risky after publication?
Question 5. Does a reflog guarantee that an old rewritten commit can be recovered forever or from another clone?
12. Summary
History editing is graph reconstruction. Rebase replays a series on a new base, interactive rebase changes the replay plan, cherry-pick replays selected changes, and amend replaces the current commit. In every case, ref movement and new object IDs are the key facts; whether the operation is appropriate depends on who already relies on the old history.
Authoritative references
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.