would_like_to_be_anon
would_like_to_be_anon

Reputation: 1727

How to cherry-pick from stash in git?

I am wondering if cherry-picking from stash is possible.

git stash save "test cherry-pick from stash"

git cherry-pick stash@{0} # --> Is this possible?

I am getting the following error when I tried above command:

~/Documents$ git cherry-pick stash@{0}
error: Commit 4590085c1a0d90de897633990f00a14b04405350 is a merge but no -m option was given.
fatal: cherry-pick failed

Upvotes: 42

Views: 25259

Answers (4)

idbrii
idbrii

Reputation: 11916

I was in a situation where I thought I wanted to cherry-pick a stash: I had an old stash that I was inspecting in a tool, but I accidentally dropped it and wanted to revive it.

The solution I found was that you can git stash apply with a commit as well as with a stash reference (because stash@{0} is just a fancy reference to a commit). This way stash is applying the commit and knows how to bring over the content in the stash's merge commits without creating a merge commit.

I copied the hash of the "WIP on branchname" commit (where the actual changes live) and passed it to git stash apply.


Example where 354705f1fa68a840ffa9f60e13b52a3c5d4e3e is the hash of the stash I was looking at:

$ git log --graph --oneline -n4 354705f1fa68a840ffa9f60e13b52a3c5d4e3e

*   354705f1 WIP on room-travel: fe4a0847 Setup room transitions
|\  
| * 72830c5c index on room-travel: fe4a0847 Setup room transitions
|/  
* fe4a0847 Setup room transitions
* 4bed4afe Split per player menu items

$ git stash apply 354705f1fa68a840ffa9f60e13b52a3c5d4e3e

Upvotes: 1

scaly
scaly

Reputation: 605

This works for me... git cherry-pick -nm1 stash

YMMV

Upvotes: 4

Klas Mellbourn
Klas Mellbourn

Reputation: 44347

The problem is that a stash consists of two or three commits. When stashing, the modified working tree is stored in one commit, the index in one commit, and (if using the --include-untracked flag) any untracked files in a third commit.

You can see this if you use gitk --all and do a stash.

enter image description here

stash@{0} points to the commit that contains the working tree.

You can however cherry-pick from that commit if you do

git cherry-pick "stash@{0}" -m 1

The reason that cherry-pick thinks that the stash is a merge, and thus needs the -m 1 parameter is that the stash commit has multpile parents, as you can see in the graph.

I am not sure exactly what you want to achieve by cherry-picking. A possible alternative is to create a branch from the stash. Commit changes there and merge them to your current branch.

git stash branch stashchanges
git commit -a -m "changes that were stashed"
git checkout master
git merge stashchanges

Upvotes: 48

Bhaskar
Bhaskar

Reputation: 2723

I have not done this before. But the man-page on cherry-pick says that it works on commits only.

   Given one or more existing commits, apply the change each one introduces,
   recording a new commit for each. This requires your working tree to be
   clean (no modifications from the HEAD commit).

Stashing is not a commit and doesn't move HEAD. So, this cannot be done [this is only a guess though]

Upvotes: -9

Related Questions