Cherry picking in Git allows developers to apply specific changes from one branch onto another without merging the entire branch history. Practically speaking, while the basic command handles a single commit, real-world workflows often require moving a series of changes—perhaps a feature developed across several commits or a batch of bug fixes. Understanding how to cherry pick multiple commits efficiently saves time, reduces merge conflicts, and keeps project history clean Simple, but easy to overlook..
This guide explores the various methods for selecting and applying multiple commits, ranging from simple range syntax to interactive workflows, along with strategies for handling conflicts and maintaining repository hygiene.
Understanding the Basics of Git Cherry-Pick
Before diving into multiple commits, Grasp the fundamental mechanics — this one isn't optional. The git cherry-pick command takes the diff introduced by a specific commit and attempts to apply it to the current working branch (HEAD). It creates a new commit with a new SHA-1 hash, preserving the original author information and commit message (unless edited).
Because it creates new commit objects, the original commits remain untouched in their source branch. This distinction is critical: cherry-picking duplicates changes rather than moving them Surprisingly effective..
Method 1: Using Commit Range Syntax
The most direct way to cherry pick multiple commits is by specifying a range. Git supports the A..B syntax (two dots) to denote "all commits reachable from B but not from A Surprisingly effective..
The Standard Range (A..B)
If you want to pick commits starting after commit A up to and including commit B, use:
git cherry-pick A..B
Crucial Detail: The commit A (the older ancestor) is excluded, while commit B (the newer tip) is included. The commits are applied in chronological order (oldest first) No workaround needed..
Example Scenario:
Imagine a feature/login branch with this history:
C1 (oldest) -> C2 -> C3 -> C4 (newest)
You are on main and want C2, C3, and C4. You would run:
git cherry-pick C1..C4
Git will apply C2, then C3, then C4 sequentially.
The Inclusive Range (^A B or A^..B)
If you need to include the starting commit A in the selection, you have two options:
- Think about it: 2. Use the caret (
^) notation:git cherry-pick ^A B(meaning "start from parent of A up to B"). UseA^..B(meaning "from parent of A to B").
Both achieve the same result: applying A, then subsequent commits up to B.
Method 2: Listing Commits Explicitly
When the commits you need are not in a clean, linear sequence—or if you want to skip specific commits in the middle—listing the hashes explicitly is safer And it works..
git cherry-pick
Git processes these in the order provided on the command line. This is distinct from range syntax, which always sorts chronologically. If you list C3 C1 C2, Git attempts to apply C3 first, which will likely fail if C3 depends on changes in C1 That's the whole idea..
Best Practice: Always list hashes in chronological order (oldest first) to respect dependency chains.
Method 3: Interactive Mode (-i or --interactive) — Recommended for Complex Sets
For maximum control, the interactive mode is the professional standard. It opens an editor (similar to git rebase -i) listing the selected commits, allowing you to reorder, drop, squash, or edit commit messages before execution.
Initiating Interactive Cherry-Pick
You can combine range syntax with the interactive flag:
git cherry-pick -i A..B
Or list specific commits:
git cherry-pick -i
The Instruction Sheet
Git opens a file (typically in your configured $EDITOR) looking like this:
pick a1b2c3d Fix typo in README
pick e4f5g6h Refactor auth module
pick i7j8k9l Add login validation
pick m0n1o2p Update dependencies
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash" but discard this commit's log message
# d, drop = remove commit
Powerful Actions in Interactive Mode
- Reordering: Move lines up or down to change application order.
- Dropping: Delete a line or change
picktodrop(ord) to skip a commit entirely. - Squashing/Fixing Up: Change
picktosquash(s) orfixup(f) on the second commit to combine it with the previous one. This is invaluable for cleaning up "WIP" or "fix typo" commits before they land on the target branch. - Rewording: Change
picktoreword(r) to improve commit messages on the fly. - Editing: Change
picktoedit(e) to pause the process at that specific commit, allowing you to modify the code (e.g., fix a bug introduced in that commit) before continuing.
Save and close the editor. Git executes the instructions sequentially Turns out it matters..
Method 4: The --no-commit Strategy (Batch Application)
Sometimes you want the code changes from multiple commits but prefer a single, clean commit on the target branch. The --no-commit (or -n) flag applies the diff to your working directory and staging area but stops before creating the commit object Not complicated — just consistent..
git cherry-pick -n A..B
# OR
git cherry-pick -n
Workflow:
- Run the command with
-n. - Git applies all diffs. If conflicts arise, they are marked in files for all commits at once (or sequentially depending on Git version, usually sequentially but staged).
- Resolve any conflicts.
- Run
git commitonce to create a single commit encompassing all changes.
At its core, excellent for "squashing" a feature branch's messy history into one atomic commit on main or release without using interactive rebase Worth keeping that in mind..
Handling Merge Conflicts Across Multiple Commits
Cherry-picking multiple commits increases the probability of conflicts. Git pauses at the first commit that conflicts.
The Standard Resolution Loop
When a conflict occurs:
- That's why git stops and prints
error: could not apply <hash>... Consider this: <message>. 2. In real terms, conflicted files are marked with<<<<<<<,=======,>>>>>>>. 3. Day to day, Resolve the conflicts in your editor/IDE. 4. Stage the resolved files:git add <file>. - Continue the sequence:
git cherry-pick --continue.
Git then attempts the next commit in the queue. Repeat until the list is exhausted That's the part that actually makes a difference. Simple as that..
Aborting the Entire Operation
If the conflict resolution becomes too messy or you realize you picked the wrong range:
git cherry-pick --abort
This resets the working directory and index to the state before you started the command, discarding all progress.
Skipping a Problematic Commit
If one specific commit in the middle of a range is broken or irrelevant, and
you would rather not bring its changes onto the target branch, skip it without terminating the rest of the operation:
git cherry-pick --skip
Git discards the changes associated with the problematic commit and moves on to the next one in the sequence. This is useful when the commit is obsolete, contains accidental changes, or duplicates work already present on the target branch. Be aware, however, that later commits may depend on the skipped commit and could fail to apply cleanly.
If the conflicting commit contains changes you need, resolve the conflict instead and continue the operation:
git add
git cherry-pick --continue
Final Verification
After all commits have been processed, inspect the result before pushing:
git status
git log --oneline --decorate -n 10
The working tree should be clean, and the new commits should appear in the expected order. You can also review the changes introduced
introduced by the operation. Comparing the resulting state against the original commit hashes with git diff <hash>..HEAD ensures that only the intended changes survived conflict resolution, and that no unintended modifications were accidentally staged or carried forward.
With the working tree clean and the commit history updated as desired, you can now push the result to your remote repository. If the branch is tracking a remote, git push will update the remote with your squashed, single commit, ready for inclusion in a pull request, release tag, or deployment pipeline.
Honestly, this part trips people up more than it should.
Conclusion
`git cherry-pick
Conclusion
git cherry-pick is a versatile command that lets you apply a single commit—or a range of commits—onto another branch while preserving the original authorship and commit message. In real terms, it shines when you need to move a specific fix, backport a security patch, or reorder changes without the bulk of a full merge. The command’s linear nature makes history easy to follow, but it also means you must be vigilant: if the target branch has moved, cherry‑picks can create duplicate commits and conflict‑prone situations Still holds up..
You'll probably want to bookmark this section.
To use cherry‑pick safely, follow a disciplined workflow:
- Plan which commits are essential and verify they apply cleanly.
- Resolve any conflicts promptly, using
git addandgit cherry-pick --continue(or--abortif the whole operation becomes untenable). - Skip problematic commits only when you’re confident they’re unnecessary and won’t break later changes.
- use options like
--no-commit,--allow-empty,--signoff, or--authorto tailor the pick to your needs. - Validate the result with
git status,git log, and appropriate tests before pushing.
By mastering these techniques—and understanding when a plain git merge or git rebase might be a better fit—you gain fine‑grained control over your repository’s evolution. A clean, well‑documented history not only aids collaboration but also simplifies future debugging and release management.
In short, git cherry-pick is a powerful ally when applied thoughtfully. Practically speaking, use it to bring precise changes across branches, keep your history intelligible, and maintain the integrity of your project’s development timeline. Happy picking!