Git And Collaboration Workflows

Cherry-Pick And Range-Diff

Cherry-pick copies selected commits, while range-diff compares two versions of a commit series.

Why This Matters

These tools are useful for focused backports, moving a small fix between branches, and proving that a rebased patch series retained its intent.

Working Model

Cherry-pick applies the patch represented by a commit to the current branch and creates a new commit. Range-diff pairs old and new commits by patch similarity so reviewers can see how a series changed.

Practical Rules

  • Cherry-pick only commits whose dependencies are understood.
  • Use -x for backports when recording the original commit ID is valuable.
  • Resolve conflicts in the target branch's context.
  • Use range-diff after rebase or review-driven history cleanup.
  • Prefer merging a whole branch when the changes form one inseparable unit.

Failure Modes

  • Cherry-picking a symptom fix without its prerequisite schema or API change.
  • Repeatedly copying the same evolving feature between long-lived branches.
  • Comparing only final trees and missing changes in commit boundaries.
  • Assuming a clean cherry-pick means behavior is compatible with the target release.

Verification

  • Inspect the selected commit and its parents.
  • Run target-branch tests and compatibility checks.
  • Use git log --cherry or range-diff to identify equivalent patches.
  • Document why a backport is intentionally different when necessary.

What You Should Be Able To Do

After this lesson, you should be able to explain when to copy a commit, when not to, and how range-diff supports review of rewritten series, choose a suitable approach for a real PHP project, and verify the result instead of relying on assumptions.

Cherry-Pick Copies A Commit's Patch

git cherry-pick applies the change introduced by an existing commit onto the current branch, creating a new commit with a new ID. It is useful when one fix needs to move to another branch without merging the entire source branch. Common cases include hotfixes, backports, and extracting one useful commit from a larger line of work.

Cherry-pick copies the patch, not the original commit object. The new commit has a different parent and may have different content if conflicts are resolved differently. The original commit message is usually reused, and Git can add a reference to the source commit with -x, which is valuable for backports and audit trails.

When Cherry-Pick Is Appropriate

Use cherry-pick when the target branch should receive one specific change and not the surrounding history. For example, a production release branch may need the session-fix commit from main, but not the new feature commits that followed it. A library maintenance branch may need a security patch without adopting a breaking refactor.

Do not use cherry-pick as a substitute for regular integration. Repeatedly cherry-picking random commits between long-lived branches creates duplicate history and makes it hard to know which branch contains which behavior. If two branches need most changes from each other, merge or rebase policy should be revisited.

Cherry-Pick Conflicts

A cherry-pick can conflict because the target branch lacks context from the source branch. Resolve conflicts the same way you would during merge: understand both sides, produce the behavior intended for the target branch, stage, and continue. Sometimes the correct resolution is different from the source branch because the maintenance branch has older APIs or different dependencies.

After cherry-picking, run tests on the target branch. The source branch's green build does not prove the patch works against older code. Pay special attention to migrations, Composer dependencies, generated clients, and public API behavior.

Backport Discipline

Backports should be traceable. Include the original commit ID, issue number, or pull request in the backport commit message. If the patch must be adapted, explain why. This helps future maintainers decide whether a later bug is present in both branches or only in the adapted backport.

When a fix is made first on a release branch, bring it back to main promptly. Otherwise the next release can reintroduce the defect. Some teams require all hotfixes to be merged forward immediately after production stabilization.

Range-Diff Compares Commit Series

git range-diff compares two versions of a patch series. It is especially useful after an interactive rebase or after updating a stacked pull request. Instead of showing one giant before-and-after diff, range-diff attempts to match old commits with new commits and show what changed in each.

A reviewer can use range-diff to answer: Did the author only rebase onto main, or did they change the content? Did a fixup alter a previously reviewed commit? Did the order change? This makes rewritten branches less opaque.

Using Range-Diff In Review

Suppose a pull request had commits A, B, and C. After review, the author rebases and edits B. A normal force-push makes the old commits disappear from the platform's simple view. A range-diff between the old branch tip and new branch tip can show that A and C are unchanged while B has specific modifications.

Authors should paste or summarize range-diff output when rewriting a branch after review. Reviewers should ask for it when the force-push is hard to understand. This is a collaboration courtesy, not just a Git trick.

Patch Identity And Duplicate Changes

Git can sometimes detect equivalent patches even when commit IDs differ, but duplicate cherry-picks can still happen. Before backporting, search the target branch for the change, issue number, or patch using git log --cherry or platform tools. Duplicate changes can cause conflicts later or make release notes confusing.

If a cherry-pick is empty, Git may be telling you the patch already exists. Confirm before skipping or forcing an empty commit.

Practical Workflow

For a backport: check out the target branch, ensure it is up to date, create a backport branch, cherry-pick with -x, resolve conflicts, run target-branch tests, open a pull request, and note any adaptation. For a rewritten review branch: save the old tip, rewrite, then use range-diff to explain the new series.

After this lesson, you should be able to cherry-pick a specific commit, decide when cherry-pick is appropriate, resolve target-branch conflicts, keep backports traceable, use range-diff to review rewritten series, and avoid duplicate or untested patch copies.

Backport Review Checklist

A backport should answer five questions: which original commit is being copied, why the target branch needs it, how the patch differs from the original, which tests ran on the target branch, and whether the fix must be merged forward anywhere else. Put those answers in the pull request description or commit message.

Security fixes need extra care. Public commit messages may need to be discreet until an advisory is ready, but private review still needs enough context to verify the patch. If the same vulnerable code exists in several supported branches, track each backport explicitly. Do not assume one cherry-pick covers every maintained version.

For PHP applications, check Composer constraints and PHP version compatibility on the target branch. A patch from main may use a language feature, dependency method, or configuration option unavailable in the older release. Adapting the patch is acceptable, but the adaptation should be tested and documented.

Range-Diff Habits

Range-diff is most useful when you save the old tip before rewriting. Hosting platforms sometimes expose previous force-push tips, but relying on that is awkward. Create a local name or copy the old SHA before the rewrite, then compare old and new series after the rebase.

Read range-diff as a review guide, not a formal proof. It helps identify corresponding commits and changed patches, but you should still inspect the final diff and run tests. If range-diff shows a commit disappeared, confirm whether it was intentionally squashed, already applied upstream, or accidentally dropped.

Cherry-Pick Versus Merge

Choose cherry-pick when the target branch needs one isolated change. Choose merge when the target branch should receive the whole line of development. If you cherry-pick several adjacent commits from the same branch, pause and ask whether a merge would be more honest. Copying many commits individually can lose context and make later conflict resolution harder.

Cherry-pick also bypasses branch-level review history. A commit reviewed on main may need a new review on a release branch because the surrounding code is different. Treat the target branch as its own product line: run its tests, inspect its dependencies, and verify its deployment assumptions.

Range-diff complements that discipline. It helps reviewers understand a rewritten series, but it does not replace normal review of the final target branch. Use it to focus attention, then still validate the actual branch that will be merged or released.

Practice Exercise

Create a release branch and a main branch, then commit a small bug fix on main. Cherry-pick it to the release branch with -x, inspect the new commit ID, and run a focused test. Then rewrite the main branch series and use range-diff to compare old and new. Seeing both operations in a disposable repository makes backports and rewritten review branches much less mysterious. Record the source and target branch names in your notes so the copied patch remains traceable.

Practice

Practice: Backport A Security Fix

A focused security fix on main must be applied to a supported release branch.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Inspect dependencies, branch from the release tip, cherry-pick with -x, adapt conflicts to the older code, run the release test matrix, and open a dedicated backport pull request.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.

Practice: Reject An Unsafe Pick

A requested commit depends on two earlier refactors and a migration. Decide whether to cherry-pick it alone.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Do not copy it in isolation. Either identify and validate the complete dependency set or implement a smaller release-specific fix. Record why the original commit is not independently portable.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.

Practice: Review A Rebased Series

A contributor rebased and reordered six commits after review. Explain how to inspect only what changed in the series.

Your answer must:

  • state the intended outcome;
  • show the commands, data flow, or implementation shape;
  • identify at least one unsafe alternative;
  • explain how the result will be verified.
Show solution

Keep the old and new tips, run git range-diff old-base..old-tip new-base..new-tip, inspect changed pairings, then review the final diff and run checks.

The important part is not memorising one command or vendor screen. The solution makes the invariant, failure behavior, and verification evidence explicit.