Skip to content

[git-cherry-pick recipe] The example in docs produces a misleading result #1032

Open
@webknjaz

Description

@webknjaz
Contributor

I was following https://www.pygit2.org/recipes/git-cherry-pick.html#cherry-picking-a-commit-without-a-working-copy and it seemed to work at first but then I noticed that it pulls in extra commits that I've never wanted.

I think that this example is incomplete.

My src (https://github.com/sanitizers/patchback-github-app/blob/92934c6/patchback/event_handlers.py#L66-L133) should produce a branch with one cherry-picked commit but instead gets a whole bunch of earlier commits too: https://github.com/webknjaz/backport-test-repo/pull/13/commits.

Activity

webknjaz

webknjaz commented on Sep 10, 2020

@webknjaz
ContributorAuthor

To make my problem more illustrative here's the state I have

(a) * <- master
    |
(x) *
    |
(y) * * (b) <- backport-branch
    |/
(z) *

And so when I want to cherry-pick (a) into "backport-branch", I need to get a resulting commit with (a') that would be a direct child of (b) as a branch (that will later be used in a PR).
I'm getting something like

                * (a') <- branch-for-backport-pr
                |
master -> (a) * * (x')
              | |
          (x) * * (y')
              | |
          (y) * * (b) <- backport-branch
              |/
          (z) *

and this ^ is not what I want. I expect to produce

(a) * <- master
    |
(x) *
    | * (a') <- branch-for-backport-pr
(y) * * (b) <- backport-branch
    |/
(z) *

P.S. (a) is sometimes a merge commit so in some cases I want to emulate cherry-pick -x -m1 but it is currently broken even for a case when (a) is a regular commit.

webknjaz

webknjaz commented on Sep 10, 2020

@webknjaz
ContributorAuthor

@jdavid do you have any idea what's missing here? Is the recipe even correct?

webknjaz

webknjaz commented on Sep 10, 2020

@webknjaz
ContributorAuthor
rmoehn

rmoehn commented on Sep 11, 2020

@rmoehn
Contributor

@webknjaz, sorry, I can't help you with this. I wrote the recipe more than five years ago and I haven't used pygit2 since.

jdavid

jdavid commented on Sep 12, 2020

@jdavid
Member

The 2nd part of the recipe looks bad.

I think to support this use case first we need to wrap git_cherrypick_commit (see https://libgit2.org/libgit2/#v1.0.1/group/cherrypick/git_cherrypick_commit)

webknjaz

webknjaz commented on Sep 12, 2020

@webknjaz
ContributorAuthor

Yeah, I thought so. I would've sent a PR but I'm not sure how to implement it...

jdavid

jdavid commented on Sep 13, 2020

@jdavid
Member

It would be a lot like Repository_cherrypick https://github.com/libgit2/pygit2/blob/master/src/repository.c#L674 but with more arguments, and it would return an index object like merge_trees does https://github.com/libgit2/pygit2/blob/master/pygit2/repository.py#L791

If you want to do a PR you can choose to write it in C or with cffi, whatever you're more comfortable with. Above you've 2 examples, cherrypick is done in C and merge_trees is done with cffi.

webknjaz

webknjaz commented on Sep 13, 2020

@webknjaz
ContributorAuthor

Thanks for the pointers! I'll see if I can find time for this.

pjw91

pjw91 commented on Jun 20, 2025

@pjw91

I've test this with my own case. However,

  1. The results of Repository_cherrypick (git_cherrypick), merge_trees and git_cherrypick_commit (written in cffi myself) are the same.
  2. And those are different from git cherrypick

Which might implies that libgit2 is different from git's implementation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @rmoehn@webknjaz@jdavid@pjw91

        Issue actions

          [git-cherry-pick recipe] The example in docs produces a misleading result · Issue #1032 · libgit2/pygit2