51

I've been using magit for a few months now and I like it a lot. But one thing I still do it in a terminal is cherry picking.

What is a simple way to do this?

40

Everywhere you see a commit in a Magit buffer, you can cherry-pick it by moving point there and then typing A A. You can also cherry-pick multiple commits at once: just select some commits using the region and then press A A.

64

Magit version <= 1.4.2

It's quite easy:

  1. Enter overview magit-status
  2. Check out (press b b) the branch you want to cherry pick into.
  3. Do a log range (press l r l) to find the commits that you want to cherry pick. Here you select the 2 branches you want to compare.
  4. Scroll to the commit you want to pick and press A to apply the changes and also stage them togeteher with the commit message. If you press a it will not stage the changes but only apply them.

You don't need to do a log range to cherry pick. Whenever you see a commit log you can press A to cherry pick it.

Magit version >= 2.1.0

After upgrading magit to 2.1 the workflow is different. For both methods you first need to start up magit-status.

Method A: Cherry Pick changes from another branch one by one, or by ranges

  1. Press l and then o to get a list of other branches.
  2. Select the branch you want to cherry pick from.
  3. Move to the commit you need and press A followed by A again. You can also select the lines with the commit range you want with C-space and press A followed by A again.
  4. The status line will show you which commit you selected

    e.g. feature/ABC~4

    Press Enter to apply changes.

Method B: Cherry Pick all changes from another branch

  1. Press A to choose the cherry pick mode.
  2. Press A again to apply and commit changes. Press a to only apply changes.
  3. Choose a branch to cherry pick changes from and press Enter.

I personally prefer method A as you can handle merge conflicts better.

2
  • 1
    I did this wrong and it took me a bit to figure out why so here's to future readers: I was doing l l o inside the magit buffer instead of l o, this was causing my git to checkout the other branch instead of just showing its log (however it was hard to tell, because inside the log it looked like i was just looking at the other branch log without checking out). This was messing up my cherry-picking.
    – Jose V
    Nov 20 '20 at 19:42
  • 3
    I don't always cherry pick. But when I do, I come to this answer every time. Jan 15 at 18:51
7

I don't use cherry picking, but hitting ? in magit-status shows y: Cherry. This runs the command magit-cherry, which lets you pick a head and an upstream. It sounds like this is what you want.

You can type C-h r d m Magit RET to read the Magit manual. You can use C-s cherry and repeated hit C-s to search through the manual. Looks like the info is in section 23:

One of the comforts of git is that it can tell you which commits have been merged upstream but not locally and vice versa. Git's sub-command for this is cherry (not to be confused with cherry-pick). Magit has support for this by invoking magit-cherry which is bound to y by default.

Magit will then ask you first for the upstream revision (which defaults to the currently tracked remote branch if any) and the head revision (which defaults to the current branch) to use in the comparison. You will then see a new buffer in which all commits are listed with a directional marker, their revision and the commit message's first line. The directional marker is either + indicating a commit that's present in upstream but not in head or - which indicates a commit present in head but not in upstream.

From this list you can use the usual key bindings for cherry-picking individual commits (a for cherry-picking without committing and A for the same plus the automatic commit). The buffer is refreshed automatically after each cherry-pick.

5
  • 1
    When invoking the Magit manual you can save a key stroke by doing C-h i instead of C-h r d. This will take you to the top-level of Info directly.
    – itsjeyd
    Apr 10 '15 at 14:42
  • 1
    @itsjeyd Nahh, C-h i will take you to the last info file you opened, so if I hit C-h i m, I could potentially be looking at a menu of chapters in SICP instead of a menu of everything. Hitting d after C-h i or C-h r will ensure that you will be in the Info-directory when before you hit m.
    – nanny
    Apr 10 '15 at 15:28
  • That's a nice trick, I did not know about that! Also, totally off-topic: An Info version of SICP?! Where can I get a copy? :)
    – itsjeyd
    Apr 11 '15 at 7:26
  • @itsjeyd I keep it in my Dropbox, I think I got it from here: github.com/webframp/sicp-info
    – nanny
    Apr 12 '15 at 17:46
  • 2
    Thanks! I checked MELPA and it turns out there is a package that gets built from that repository. So installing the Info version of SICP is as easy as M-x package-install RET sicp RET :)
    – itsjeyd
    Apr 13 '15 at 8:06
0

Using Cherry to better narrow down candidate commits:

Usually you want to pick some commits which are on feature-a but not on released, you can:

  • create/checkout the branch you want to save the cherries to (name like feature-a-subset)
  • Cherry in magit status buffer
  • select feature-a as cherry head, released as upstream, to get some log of commits feature-a differ from released
  • Apply->Pick (A->A) on some single commits or a region (see more detail in tarsius and other's answers)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.