Field Note

Peeking over the fence with `git cherry`

Git logo
Posted on March 10th, 2026
3 min read

Tl;dr (for those rushing to get coffee)

  • git cherry <upstream> <downstream> lets us get a set of commits that only exist on a downstream branch (e.g. a feature branch) compared to the upstream
  • some use cases include:
    • debugging the cause of issues on branches
    • selecting commits for git cherry-pick

If you are a Git veteran, you will likely have heard of the git cherry-pick command that lets you apply a commit or set of commits to a target branch.

But, have you heard of its sibling git cherry? While the naming is of course a bit curious, git cherry essentially lets you do the precursory work before doing git cherry-pick (or, git rebase -i). Meaning that it lets you peek over the fence and check out what commits have been made to a branch (e.g. a feature branch) as compared to a reference branch (e.g. the main branch).

So, why would we do that? Granted, it’s a niche situation. But, if you run into one of the following situations, git cherry may help you:

  1. a downstream branch has some issue that doesn’t exist on the upstream branch and you need to identify probable changes/commits that may have caused it;
  2. you are planning to extract some commits from a feature branch and apply them to another (for example, for git cherry-pick)

Example

set -e 
# Create a git repo
mkdir /tmp/git-cherry-example 
cd /tmp/git-cherry-example
git init .

# Create an initial set of commits on the main branch
for i in 1 2; do
  echo "main-${i}" >> "file-main-${i}.txt"
  git add .
  git commit -m "Main commit $i"
done

# a branch is forked from main and some changes are made
git checkout -b feat/thefeature
for i in 1 2; do
  echo "thefeature-${i}" >> "file-feat-${i}.txt"
  git add .
  git commit -m "Feature commit $i"
done

# meanwhile some changes happen on main
git checkout main 
for i in 3 4; do
    echo "main-$i" >> "file-main-${i}.txt"
    git add .
    git commit -m "Main commit $i"
done

# Merge the main changes into the downstream
git checkout feat/thefeature
git merge main -m "Merge branch 'main' into feat/thefeature"

git log --oneline will show the following

$ git log --oneline
193303f (HEAD -> feat/thefeature) Merge branch 'main' into feat/thefeature
077dc92 Feature commit 2
a0d38a8 (main) Main commit 4
40068af Feature commit 1
540fbce Main commit 3
0f16caa Main commit 2
30fe85f Main commit 1

Since the normal git log output doesn’t show a graph, feature commits are mixed with main branch commits. It’s thus unclear which commit came from where (especially if the commit messages are not as indicative as in this case).

Visually, we may identify the commits that only exist on feat/thefeature by running git adog (i.e. git log --all --decorate --oneline --graph):

$ git log --all --decorate --oneline --graph
*   193303f (HEAD -> feat/thefeature) Merge branch 'main' into feat/thefeature
|\
| * a0d38a8 (main) Main commit 4
| * 540fbce Main commit 3
* | 077dc92 Feature commit 2
* | 40068af Feature commit 1
|/
* 0f16caa Main commit 2
* 30fe85f Main commit 1

And git-cherry gives us the machine-readable answer (easily parseable with e.g. awk):

$ git cherry -v main feat/thefeature
+ 8f6c8f50d996cbb09d03a4969715ab757cf13439 Feature commit 1
+ 6a43e68e9ca66c1ab642da50d2fd5ebcae07ac61 Feature commit 2

The + in front of the line indicates a commit that only exists on the reference branch. Using -v, we also get the commit message. This is only necessary if the commit message gives us vital information on the change, of course.

friedrichkurz.me © 2019-2026 Friedrich Kurz Privacy Policy