Mostly, yes, but not exactly.
First, there are three methods by which git rebase
is implemented. The interactive one, and the one with -m
, literally run git cherry-pick
. The non-interactive non-merge one uses git format-patch | git am
internally by default, and this will occasionally produce a different result from running git cherry-pick
.
Second, not every commit gets selected. In particular, git rebase
generally eliminates:
- commits that are merges;
- commits that are "empty" (commits with no diff); and
- commits that Git decides are already cherry-picked.1
Merges literally cannot be copied, so it just doesn't bother, except when using -p
(which does not copy them after all, but instead re-performs the merges). Empty-diff commits cannot be copied via git format-patch
, and in general are not required for correctness anyway, so the default is to discard them. Adding -k
(keep empty) makes even the non-interactive rebase use git cherry-pick
, which can copy empty-diff commits.
Finally, all variants of rebase may, depending on options, use the "fork point" code to discard some of the leading commits from the set of commits-to-be-copied. Using --no-fork-point
disables this option, and it is disabled by default for some rebases, but enabled by default for others. The details are spelled out in the git rebase
documentation.
Unless you are running git rebase -m
or git rebase -i
, the difference you see is most likely due to using git format-patch | git am
. It would be useful if you could identify the specific commit that is applied differently when git am
runs git apply -3
on it, vs when it is git cherry-pick
ed, since commits where this happens are somewhat rare (I have not had time to construct an artificial example, and a real example would perhaps be more valuable).
1To make this decision, Git uses git patch-id
, which you can run manually; or you can use git cherry
or git rev-list
to get Git to run it for you automatically. The rebase code uses git rev-list
(sometimes by passing these arguments, or their equivalent, to git format-patch
, sometimes using --reverse --topo-order
):
git rev-list --cherry-pick --right-only --no-merges upstream...HEAD
(note the three dots, which invokes the symmetric difference selector).