git-cherry-pick
Apply specific commits from one branch to another
TLDR
Apply a commit to the current branch
Apply a range of commits to the current branch (see also: git rebase --onto)
Apply multiple (non-sequential) commits to the current branch
Add the changes of a commit to the working directory, without creating a commit
SYNOPSIS
git cherry-pick [--options] <commit-ish>...
PARAMETERS
<commit-ish>...
Specifies one or more commits to cherry-pick. This can be a commit hash, a branch name, or any Git revision reference.
--no-commit
Prevents cherry-pick from automatically committing the changes after applying them. The changes are left in the index and working tree, allowing for further modifications or staging before a manual commit.
--edit (or -e)
Allows editing the commit message before the cherry-pick is committed. A text editor will open with the original commit message, which can be modified.
--continue
Continues the cherry-pick operation after a conflict has been resolved manually. After fixing conflicts and staging the changes (git add), this command completes the operation.
--abort
Aborts the current cherry-pick operation, discarding any changes that have been applied and reverting the working directory and index to the state before the cherry-pick started.
--quit
Aborts the current cherry-pick operation but leaves the working directory and index as is (i.e., with conflicts). This is useful if you want to inspect the conflicted state before deciding to fix or fully abort.
--strategy=<strategy>
Specifies the merge strategy to use during the cherry-pick. Common strategies include 'recursive' (default), 'resolve', 'ours', 'theirs'.
-x (or --signoff)
Adds a "Signed-off-by" line by the committer at the end of the commit message.
DESCRIPTION
The git-cherry-pick command is a powerful Git operation used to apply changes from one or more existing commits to a different branch. Unlike git-merge, which integrates an entire branch's history, cherry-pick allows users to pick specific commits by their SHA-1 hash and reapply their changes. This creates a new commit on the current branch, containing the same changes as the original commit, but with a new commit SHA and often new parentage.
It's commonly used for "backporting" bug fixes from a development branch to a stable release branch, or for moving a small feature from one branch to another without merging the entire source branch. While convenient for isolated changes, it should be used judiciously, as it can lead to duplicated commits and complex history if not managed carefully.
CAVEATS
- New Commits: git-cherry-pick creates new commits with new SHA-1 hashes. This means the new commit is not the "same" as the original from a Git history perspective, even if the content is identical.
- Duplicate History: If a cherry-picked commit is later integrated via a merge, it can lead to duplicate commits in the history, which might complicate future merges or reverts.
- Merge Conflicts: Conflicts are common, especially when cherry-picking commits that touch files also modified in the target branch. These require manual resolution.
- Parentage: The new commit's parentage will be the tip of the branch it was cherry-picked onto, not the original commit's parent.
HANDLING CONFLICTS
When cherry-pick encounters conflicts, it pauses the operation. The user must manually resolve the conflicts in the affected files, stage the changes using git add, and then continue the operation with git cherry-pick --continue. If the resolution is too complex or undesirable, git cherry-pick --abort can be used.
BEST PRACTICES
It is generally recommended to use git-cherry-pick for isolated, small changes (e.g., hotfixes, single-line bug fixes) rather than for integrating large features or many commits. For larger integrations, git-merge or git-rebase are often more appropriate to maintain a cleaner and more traceable history.
HISTORY
git-cherry-pick has been a fundamental part of Git since its early days, dating back to at least Git version 1.0.0 (released in 2005). It was introduced to address the need for selectively applying individual changes across branches, a common requirement in maintenance branches and bug-fixing workflows. Its utility in backporting specific bug fixes without introducing the overhead of full branch merges quickly solidified its place as a core command, complementing git-merge and git-rebase in managing complex project histories.
SEE ALSO
git-rebase(1), git-merge(1), git-revert(1), git-log(1)