Git and GitHub / Intermediate: collaborative change management / Lesson 10
Rebase, cherry-pick, and private history
Replay changes deliberately while preserving recovery anchors and respecting collaborators who depend on existing commits.
On this page
Lesson goals
- Explain why replay creates new commit identities.
- Choose private-history rebase or targeted backport with explicit verification.
Replay a change onto a different parent
Rebase selects commits and replays their changes onto a chosen base. The resulting commits generally have new identities because parent relationships and committer metadata change, even when the final file content is similar. It is not merely moving existing objects unchanged. Cherry-pick applies selected commit changes to the current line and ordinarily creates new commits there. Both can conflict or produce behavior that differs in the new context. Understand the selected range, destination, and sharing state before proceeding. Preserve a named reference to the original private topic so comparison and recovery remain straightforward.
Rebase only an understood private topic
The lab below assumes a clean private feature/title branch and a main branch with independent nonconflicting progress. A safety branch records the original tip before rebase. After replay, main is an ancestor of the topic, while the original topic remains reachable through the safety reference. This demonstration never changes the workspace repository or a published branch. A real shared branch requires coordination and project policy; force-with-lease is not permission to rewrite colleagues’ history. Inspect the result and tests before considering any publication, which is outside this course’s execution scope.
git switch feature/title
git branch safety/title-before-rebase
git -c user.name="Lab Author" -c user.email="lab@example.invalid" rebase main
git merge-base --is-ancestor main feature/title
The final ancestry check exits 0 without output after a successful rebase. Commit ids may change and are intentionally not predicted. This fragment requires the stated clean local graph; any conflict requires the rebase-specific resolution workflow.
Compare the series, not only the final tree
A successful rebase can accidentally drop, duplicate, or alter intended behavior during conflict resolution. Compare the old and new patch series with suitable range-diff arguments, inspect the resulting graph, and run relevant tests. The safety reference helps identify the original range. A plain endpoint diff can be useful but may include independent base changes, so it is not always the right review question. Interactive rebase can reorder, squash, edit, or drop private commits, and every action changes the reviewable story. Keep each resulting commit coherent if the project expects bisectable history.
Backport a focused change with provenance
A maintenance branch may need one fix without the entire feature history. Cherry-pick can transfer that change, but it does not automatically bring every dependency the fix assumes. Inspect the source commit, its prerequisites, and target compatibility. The -x option records the source commit in the message under its documented behavior, which can help public maintenance traceability. Do not expose private commit references or messages unintentionally across access boundaries. The example selects a named local lab fix rather than an invented hash, and all validation remains inside temporary repositories.
git switch lab-maintenance
git -c user.name="Lab Author" -c user.email="lab@example.invalid" cherry-pick -x lab-fix
git log -1 --format=%B
lab-fix must point to the intended single ordinary commit, and the target must be clean. The resulting message includes the source identifier when the documented -x conditions apply. The resulting commit has its own identity on the target history.
Common errors and fixes
A rebase changes expected commit ids
- Why it happens
- Replay changed parents or metadata.
- How to fix it
- Compare patch series and verify intended behavior.
- Prevent it next time
- Keep original refs while rewriting private work.
A backport compiles but misses a prerequisite
- Why it happens
- The chosen fix depends on earlier context.
- How to fix it
- Inspect dependencies and adapt or include the required change.
- Prevent it next time
- Test the target maintenance context explicitly.
Skipping a conflict silently removes behavior
- Why it happens
- Skip was mistaken for automatic resolution.
- How to fix it
- Review the omitted commit and restore required behavior deliberately.
- Prevent it next time
- Explain each replay continuation choice before using it.
Check your understanding
1. Why can rebased commits differ in identity while showing similar patches?
Show worked solution
A commit includes parent relationships and metadata, not only a patch. Replaying onto a different base creates a new object. Verify intent with a series comparison and tests rather than expecting the old identifiers to remain.
2. A teammate already based work on your topic. What must precede rewriting it?
Show worked solution
Coordinate and follow the shared-history policy, considering a merge or new correction instead. Preserve the old history and explain any agreed rewrite and recovery path. A local command’s ability to rewrite does not establish collaboration authorization.
Key takeaways
- Replay creates new history and requires comparison.
- Backports need dependency and target-context review.
- Shared history changes require explicit coordination.