'Git cherry pick and then rebase

There's something I don't understand when I rebase after cherry-picking in git. Would someone please tell me what's going on?

The scenario like this:

I am working on the master and topic branches as follows and the topic has two commits.

      C---D  topic
     /
A---B      master

I had a problem with the topic branch, so I decided to just cherry-pick D and merge it into the master. I create a release branch and cherry-pick it.

      C---D  topic
     /
A---B      master
     \
      D'  release

I merge release into master.

      C---D  topic
     /
A---B----E   master
     \  /
      D'  release

The base branch of the topic has changed, so I rebase it to the latest master.

           C  topic
          /
A---B----E   master
     \  /
      D'  release

Finally, the commit of D that cherry-picked disappeared from the topic. This is the intended result for me. But I don't understand why git found them to be the same, even though the commit hashes are different.

git


Solution 1:[1]

A cherry-pick would change the metadata associates to a commit (like the date or its parent).
But it would not change its content (the tree SHA1 it references)

As explained in "How does git rebase skip the commit which its change already has in upstream?", the patch id associated to the commit D is the same as D', which is already merged.
So it is not repeated by the rebase.

With Git 2.34 (Q4 2021), you will actually see those skipped commits, as rebase will tell you:

skipped previously applied commit xxx
use git rebase --reapply-cherry-picks to include skipped commits

From the man page:

--reapply-cherry-picks

--no-reapply-cherry-picks

Reapply all clean cherry-picks of any upstream commit instead of preemptively dropping them. (If these commits then become empty after rebasing, because they contain a subset of already upstream changes, the behavior towards them is controlled by the --empty flag.)

By default (or if --no-reapply-cherry-picks is given), these commits will be automatically dropped.
Because this necessitates reading all upstream commits, this can be expensive in repos with a large number of upstream commits that need to be read.
When using the merge backend, warnings will be issued for each dropped commit (unless --quiet is given). Advice will also be issued unless advice.skippedCherryPicks is set to false.

--reapply-cherry-picks allows rebase to forgo reading all upstream commits, potentially improving performance.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1