Cherry-picking is a fundamental building block that has no non-fundamental equivalent. That is, there's no lower level operation that's "pure plumbing". The reason is that cherry-pick does a merge with a (potentially, at least) somewhat screwy merge base.

That said, with proper inputs, git apply implements cherry-picking when run as git apply -3 (but git apply is not a plumbing command either). The way this works is using the Index: lines in each git diff. The Index: lines provide the otherwise-missing merge base information. There is still one thing that is different here though, having to do with rename detection.

If there are no renames, the two are equivalent. This is because a merge operation has one key difference from a simple patch: a merge has a merge base, from which we can derive two patches.

Consider the following sequence:

  • Alice and Bob start with a common Git repository, with file readme.txt in some commit.

  • Alice changes line 10 so that instead of saying "bees are purple", it says "bees are green". She also changes line 9 so that the file says "Everything below is bizarre." (And then, of course, Alice commits the new files.)

  • Bob changes line 10 so that instead of saying "bees are purple", it says "bees are green", and also adds a new line 20 so that it adds a claim that "submarines climb trees."

Now, if Alice gets Bob's change as a patch (without an Index: line, as just a contextual diff, e.g., from diff -U) and feeds that into her Git, Alice's Git won't know what to do with Bob's change to line 10. It will have no problem with the line-20 addition, but the context for the "bees are green" change doesn't match: it doesn't have the "bizarre" bit.

If, on the other hand, Alice get's Bob's change as a "cherry-pick-able patch" (either by running an actual git cherry-pick or by getting a diff with an Index: line and using git apply -3 or equivalent), Alice's Git now has more information. Alice's Git can now see not just that Bob changed readme.txt, but which version of that file he had when he started. Specifically, the Index: line has the blob hash of the "before" version of readme.txt, and since Alice and Bob started with the same version of the file, in the same commit. (It also has Bob's "after" version, which Alice doesn't have, but now the entire "after" version can be constructed if necessary—but it's unnecessary.)

Now Alice's Git can run its own diff: it can diff the base version against Alice's current version, to see what Alice did. Then it could diff the base version against Bob's version, to get the patch-with-base that it already has (but why bother? that's the patch it already has!). Now it can (try to) combine the two patches: it sees that Bob's change to line 10 is redundant—it's contained within Alice's own changes—and concentrates only on line 20. Now Alice's Git can apply the patch.

That's what a merge base is (and does) for a file. The rename case comes in when—and for Git, only when—Git can diff an entire tree, i.e., it needs the commit-as-a-whole (or at least the tree object attached to the commit). Here git apply will run out of its depth since it works on one file at a time. (The git am code might be able to deal with it if the incoming patch has "rename" instructions within it, but I don't think that's in Git, though I admit to not having looked lately.)

Answer from torek on Stack Overflow
🌐
Pygit2
pygit2.org › recipes › git-cherry-pick.html
git-cherry-pick — pygit2 1.19.1 documentation
The convenient way to cherry-pick a commit is to use Repository.cherrypick().
🌐
Git
git-scm.com › docs › git-cherry-pick
Git - git-cherry-pick Documentation
When recording the commit, append a line that says "(cherry picked from commit …​)" to the original commit message in order to indicate which commit this change was cherry-picked from. This is done only for cherry picks without conflicts. Do not use this option if you are cherry-picking ...
Discussions

git cherry-pick
what is the best way to use cherrypick using gitPython. I could not find this in the doc as well More on github.com
🌐 github.com
2
1
July 3, 2021
Python Script for Local Repository and Cherry-Pick for specific commit GIT - Stack Overflow
I want to create a python script for making local repository and I have no idea how to do this, after local repository I want to do cherry-pick for specific commit. Any tips for me ? More on stackoverflow.com
🌐 stackoverflow.com
Add support for git cherry
git cherry returns a list of commit hashes with a prefix + or - to indicate whether the commit has an equivalent cherry-pick commit in a sibling branch. I would like to be able to iterate over the ... More on github.com
🌐 github.com
4
February 21, 2019
version control - Git: Is there a way to figure out where a commit was cherry-pick'ed from? - Stack Overflow
If I cherry-pick from multiple branches, is there a simple way to figure out where the commit was coming from (e.g. the sha of the original commit)? Example: - at master branch - cherry pick commi... More on stackoverflow.com
🌐 stackoverflow.com
People also ask

What is git-cherry-pick-helper?
Simplify cherry-picking for messy git workflows. Visit Snyk Advisor to see a · full health score report · for git-cherry-pick-helper, including popularity, security, maintenance · & community analysis.
🌐
snyk.io
snyk.io › advisor › python packages › git-cherry-pick-helper
git-cherry-pick-helper - Python Package Health Analysis | Snyk
Is git-cherry-pick-helper popular?
The python package git-cherry-pick-helper receives a total · of 37 weekly downloads. As · such, git-cherry-pick-helper popularity was classified as · · limited. Visit the · popularity section · on Snyk Advisor to see the full health analysis.
🌐
snyk.io
snyk.io › advisor › python packages › git-cherry-pick-helper
git-cherry-pick-helper - Python Package Health Analysis | Snyk
Is git-cherry-pick-helper safe to use?
While scanning the latest version of git-cherry-pick-helper, we found · that a security review is needed. A total of · 0 vulnerabilities or license issues were · detected. See the full · security scan results.
🌐
snyk.io
snyk.io › advisor › python packages › git-cherry-pick-helper
git-cherry-pick-helper - Python Package Health Analysis | Snyk
Top answer
1 of 1
1

Cherry-picking is a fundamental building block that has no non-fundamental equivalent. That is, there's no lower level operation that's "pure plumbing". The reason is that cherry-pick does a merge with a (potentially, at least) somewhat screwy merge base.

That said, with proper inputs, git apply implements cherry-picking when run as git apply -3 (but git apply is not a plumbing command either). The way this works is using the Index: lines in each git diff. The Index: lines provide the otherwise-missing merge base information. There is still one thing that is different here though, having to do with rename detection.

If there are no renames, the two are equivalent. This is because a merge operation has one key difference from a simple patch: a merge has a merge base, from which we can derive two patches.

Consider the following sequence:

  • Alice and Bob start with a common Git repository, with file readme.txt in some commit.

  • Alice changes line 10 so that instead of saying "bees are purple", it says "bees are green". She also changes line 9 so that the file says "Everything below is bizarre." (And then, of course, Alice commits the new files.)

  • Bob changes line 10 so that instead of saying "bees are purple", it says "bees are green", and also adds a new line 20 so that it adds a claim that "submarines climb trees."

Now, if Alice gets Bob's change as a patch (without an Index: line, as just a contextual diff, e.g., from diff -U) and feeds that into her Git, Alice's Git won't know what to do with Bob's change to line 10. It will have no problem with the line-20 addition, but the context for the "bees are green" change doesn't match: it doesn't have the "bizarre" bit.

If, on the other hand, Alice get's Bob's change as a "cherry-pick-able patch" (either by running an actual git cherry-pick or by getting a diff with an Index: line and using git apply -3 or equivalent), Alice's Git now has more information. Alice's Git can now see not just that Bob changed readme.txt, but which version of that file he had when he started. Specifically, the Index: line has the blob hash of the "before" version of readme.txt, and since Alice and Bob started with the same version of the file, in the same commit. (It also has Bob's "after" version, which Alice doesn't have, but now the entire "after" version can be constructed if necessary—but it's unnecessary.)

Now Alice's Git can run its own diff: it can diff the base version against Alice's current version, to see what Alice did. Then it could diff the base version against Bob's version, to get the patch-with-base that it already has (but why bother? that's the patch it already has!). Now it can (try to) combine the two patches: it sees that Bob's change to line 10 is redundant—it's contained within Alice's own changes—and concentrates only on line 20. Now Alice's Git can apply the patch.

That's what a merge base is (and does) for a file. The rename case comes in when—and for Git, only when—Git can diff an entire tree, i.e., it needs the commit-as-a-whole (or at least the tree object attached to the commit). Here git apply will run out of its depth since it works on one file at a time. (The git am code might be able to deal with it if the incoming patch has "rename" instructions within it, but I don't think that's in Git, though I admit to not having looked lately.)

🌐
GitHub
github.com › gitpython-developers › GitPython › issues › 846
Add support for git cherry · Issue #846 · gitpython-developers/GitPython
February 21, 2019 - git cherry returns a list of commit hashes with a prefix + or - to indicate whether the commit has an equivalent cherry-pick commit in a sibling branch. I would like to be able to iterate over the ...
Author   sffc
Find elsewhere
🌐
GitHub
github.com › python › cherry-picker
GitHub - python/cherry-picker: 🐍🍒⛏ Utility script for backporting/cherry-picking CPython changes from master into one of the maintenance branches.
🐍🍒⛏ Utility script for backporting/cherry-picking CPython changes from master into one of the maintenance branches. - python/cherry-picker
Starred by 63 users
Forked by 47 users
Languages   Python
🌐
Snyk
snyk.io › advisor › python packages › git-cherry-pick-helper
git-cherry-pick-helper - Python Package Health Analysis | Snyk
February 8, 2023 - gitpythonnumpy · Simplify cherry-picking for messy git workflows. Visit Snyk Advisor to see a full health score report for git-cherry-pick-helper, including popularity, security, maintenance & community analysis. The python package git-cherry-pick-helper receives a total of 37 weekly downloads.
🌐
Python for Data Science
python4data.science › en › latest › productive › git › advanced › cherry-pick.html
Git cherry-pick - Python for Data Science
git cherry-pick allows you to append arbitrary Git commits to the current HEAD based on their hash value. Cherry-picking is selecting a commit from one branch and applying it to another, for exampl...
🌐
PyPI
pypi.org › project › cherry-picker
cherry-picker - cherry_picker
JavaScript is disabled in your browser · Please enable JavaScript to proceed · A required part of this site couldn’t load. This may be due to a browser extension, network issues, or browser settings. Please check your connection, disable any ad blockers, or try using a different browser
🌐
GitHub
github.com › python › cherry-picker › blob › main › cherry_picker › cherry_picker.py
cherry-picker/cherry_picker/cherry_picker.py at main · python/cherry-picker
🐍🍒⛏ Utility script for backporting/cherry-picking CPython changes from master into one of the maintenance branches. - cherry-picker/cherry_picker/cherry_picker.py at main · python/cherry-picker
Author   python
🌐
Python for Data Science
python4data.science › en › 24.3.0 › productive › git › advanced › cherry-pick.html
Git cherry-pick - Python for Data Science 24.3.0
git cherry-pick allows you to append arbitrary Git commits to the current HEAD based on their hash value. Cherry-picking is selecting a commit from one branch and applying it to another, for exampl...
🌐
Codementor
codementor.io › community › understanding git cherry-pick: how to use
Understanding Git Cherry-pick: How to Use | Codementor
January 18, 2017 - But cherry-picking simply means picking a commit from a branch and applying that commit onto another branch. It is more useful for sampling out a small subset of changes from a topic branch you've decided to delete, but you still got some useful ...
Top answer
1 of 3
58

By default, the information about the original, “cherry” commit is not recorded as part of the new commit.

Record the Source Commit in the Commit Message

If you can force the use of particular workflows/options, git cherry-pick has the -x option:

When recording the commit, append to the original commit message a note that indicates which commit this change was cherry-picked from.

This is obviously useless if you can not rely on the cherry pickers using the option. Also, since the recorded information is just plain text—not an actual reference as far as Git is concerned—even if you use -x, you still have to take steps to make sure that the original commit is kept alive (e.g. is is part of the DAG of a tag or a non-rewinding branch).

git cherry and git patch-id

If you can restrict your search to two particular branches of the history DAG, then git cherry can find both “unpicked” and “picked” cherries.

Note: This command (and the related git patch-id) can only identify conflict-free cherries that were individually picked without extra changes. If there was a conflict while picking the cherry (e.g. you had to slightly modify it to get it to apply), or you used -n/--no-commit to stage extra changes (e.g. multiple cherries in a single commit), or the content of the commit was rewritten after the picking, then you will have to rely on commit message comparison (or the -x information if it was recorded).

git cherry is not really designed to identify the origin of picked cherries, but we can abuse it a bit to identify single cherry pairs.

Given the following history DAG (as in the original poster’s example):

1---2---3---B---D  master
         \
          A---C    dev
# D is a cherry-picked version of C

you will see something like this:

% git cherry master dev
+ A
- C
% git cherry dev master
+ B
- D

(A, B, C, and D are full SHA-1 hashes in the real output)

Since we see one cherry (the - lines) in each list, they must form a cherry pair. D was a cherry picked from C (or vice versa; you can not tell by the DAG alone, though the commit dates might help).

If you are dealing with more than one potential cherry, you will have to “roll your own” program to do the mapping. The code should be easy in any language with associative arrays, hashes, dictionaries, or equivalent. In awk, it might look like this:

match_cherries() {
    a="$(git rev-parse --verify "$1")" &&
    b="$(git rev-parse --verify "$2")" &&
    git rev-list "$a...$b" | xargs git show | git patch-id |
    awk '
        { p[$1] = p[$1] " " $2 }
    END { 
            for (i in p) {
                l=length(p[i])
                if (l>41) print substr(p[i],2,l-1)
            }
        }'
}
match_cherries master dev

With an extended example that has two picked cherries:

1---2---3---B---D---E  master
         \
          A---C        dev
# D is a cherry-picked version of C
# E is a cherry-picked version of A

The output might look like this:

match_cherries master dev
D C
E A

(A, C, D, and E are full SHA-1 hashes in the real output)

This tells us that C and D represent the same change and that E and A represent the same change. As before, there is no way to tell which of each pair was “the first” unless you also consider (e.g.) the commit dates of each commit.

Commit Message Comparison

If your cherries were not picked with -x, or they are “dirty” (had conflicts, or other changes added to them (i.e. with --no-commit plus staging extra changes, or with git commit --amend or other “history rewriting” mechanism)), then you may have to fall back on less the less reliable technique of comparing commit messages.

This technique works best if you can find some bit of the commit message that is likely to be unique to the commit and is unlikely to have changed in the commit that resulted from the cherry pick. The bit that would work best would depend on the style of commit messages used in your project.

Once you have picked out an “identifying part” of the message, you can use git log to find commits (also demonstrated in Jefromi’s answer).

git log --grep='unique part of the commit message' dev...master

The argument to --grep is actually a regular expression, so you might need to escape any regexp metacharacters ([]*?.\).

If you are not sure which branches might hold the original commit and the new commit, you can use --all as Jefromi showed.

2 of 3
14

If I follow your diagram, you want to know if you can determine than D (not B) is the result of cherry-picking A.

In theory, as illustrated in "How to list git branches that contain a given commit?", you can search for a commit, if D is actually the same commit (SHA1) than A:

git branch --contains <commit>

But as Jefromi comments, D cannot have the same SHA1 in this case.
That leaves the search for a common commit message: see Jefromi's answer.


As Ken Bloom mentions in the comments of the question, for such a local cherry-picking, a daggy-fix technique (like in monotone or mercurial) is more appropriate, because it will leave a clear trace of the merge.

Daggy fixes mean using rather than losing the true origin and relationship between bugs and fixes in the ancestry graph.

Since [Git] offers the ability to make a commit on top of any revision, thereby spawning a tiny anonymous branch, a viable alternative to cherry-picking is as follows:

  • use bisect to identify the revision where a bug arose;
  • check out that revision;
  • fix the bug;
  • and commit the fix as a child of the revision that introduced the bug.

This new change can easily be merged into any branch that had the original bug, without any sketchy cherry-picking antics required.
It uses a revision-control tool's normal merge and conflict-resolution machinery, so it is far more reliable than cherry-picking (the implementation of which is almost always a series of grotesque hacks).

(here a Mercurial diagram, but easily applied to Git)

Doing daggy fixes all the time isn't for everyone.
It's not always so easy to develop a fix directly against the revision where the bug was introduced.

  • Perhaps the bug wasn't discovered until some other more recent code used it in ways that exposed the bug; it would be hard to debug and find the fix without this other code around.
  • Or perhaps the importance or scope of the fix simply hadn't been realised at the time.

See also this article for more on daggy-fix:

This technique of going back in history to fix a bug, then merging the fix into modern branches, was given the name "daggy fixes" by the authors of Monotone, an influential distributed revision-control system.
The fixes are called daggy because they take advantage of a project's history being structured as a directed acyclic graph, or dag.
While this approach could be used with Subversion, its branches are heavyweight compared with the distributed tools, making the daggy-fix method less practical. This underlines the idea that a tool's strengths will inform the techniques that its users bring to bear.

🌐
GitHub
github.com › gitpython-developers › GitPython › issues › 323
Assertion Error when "diffing" index during cherry pick conflict. · Issue #323 · gitpython-developers/GitPython
July 21, 2015 - I am trying to use gitpython to make a tool for helping in cherry-picking. The "repo.git.cherry_pick('hexsha')" command works perfectly, but, when I want to check the files with conflicts via repo.index.diff(None) I get the following Ass...
🌐
Joergdietrich
joergdietrich.github.io › git_cherry-pick.html
How I use git cherry-pick
March 17, 2018 - To see how I use git cherry-pick to quickly backport important changes like critical bug fixed from development branches, we will create a new, initially buggy, project. As a toy project, let’s create a Python module, which computes the $n$-th Fibonacci number.
🌐
OneUptime
oneuptime.com › home › blog › how to handle git cherry-pick
How to Handle Git Cherry-Pick
January 24, 2026 - If conflicts are too complex or you picked the wrong commit, abort. # Cancel the in-progress cherry-pick git cherry-pick --abort # Working directory returns to state before cherry-pick
🌐
OpenDev
opendev.org › openstack › deb-python-pygit2 › commit › b3025e3fe
Add git-cherry-pick recipes · b3025e3fe1 - deb-python-pygit2 - OpenDev: Free Software Needs Free Tools
Add the way that worked for me. Not sure if it is idiomatic. When doing the convenience-mode cherry-pick, the repo remains in cherry-picking mode afterwards. I've already added an issue for this.
🌐
GeeksforGeeks
geeksforgeeks.org › git › git-cherry-pick
Git - Cherry Pick - GeeksforGeeks
January 16, 2026 - Git cherry-pick lets you apply a commit from one branch to another without manually using commands like git show and patching.
🌐
PyPI
pypi.org › project › gitbuster
gitbuster
JavaScript is disabled in your browser. Please enable JavaScript to proceed · A required part of this site couldn’t load. This may be due to a browser extension, network issues, or browser settings. Please check your connection, disable any ad blockers, or try using a different browser