49

I want to apply some of the changes in a git stash to one commit, and the rest of the changes to another.

2
  • 1
    What do you mean with "half"? Half of what? Half of each stash, or half of stash list? Commented Mar 4, 2013 at 23:09
  • 1
    Could it be by half you mean a portion? Commented Mar 4, 2013 at 23:10

4 Answers 4

71
git checkout stash@{0} -- <filename> 

You can also do this with a list or a glob of filenames.

Sign up to request clarification or add additional context in comments.

2 Comments

checkout is wrong if the stash is made from an earlier commit.
While this works, it overwrites <filename> with the version from the stash. You will need to manually resolve unrelated merge conflicts if the file has drifted, as pointed out by @nikolai.
32

Looks like you can use git checkout -p with a stash reference, like stash@{0}. This will let you choose piece by piece what you want to apply to your work tree from the stash.

After you're done using git checkout -p, the changes you accepted will have been applied to your work tree and added to the cache/index, ready to commit. You can use git checkout -p stash@{0} multiple times, choosing the patches you want and committing however many times you want along the way.

1 Comment

This is exactly what I need, I think the other answers throw away changes from subsequent commits and/or working tree. Note that passing a path as well is very useful, particularly if your branch has been rebased since the stash. That helps avoid manually filtering out intervening changes (to other paths you don't need to restore) since the rebase.
12

Apply the patch for only the files you want to change.

git show --first-parent stash@{0} -- <file(s) in question> | git apply 

8 Comments

I think the default output has changed as you now need to specify the -m option (git show -m stash...) to output a diff that git apply understands. Without that I got error: unrecognised input from git apply.
@AndrewFrance I can't find much reference to -m. Can you point me to some documentation and I'll update my answer.
The documentation does seem lacking, -m is not in the options list on the man page for git-show but it is briefly mentioned in the combined diff format section. It's not clear to me why it works sorry!
I think -m is for git stash show (having the same options as git diff), not for git show stash
@Cilyan I've reproduced the bug. Stashes are now saved as merge commits, it seems and produce a "combined diff". If I add --first-parent to the show command, it works again. Answer updated.
|
6

Unstash the stash...

git stash pop 

...use git add in patch mode...

git add -p 

...and then commit that...

git commit -m "Partial stashed commit" 

This is what quickly came to my head without reading the docs. Leo's answer has much better way to achieve this.

3 Comments

You could also restash unstaged changes but keep the index.
^ Yes. @R0MANARMY suggests a good approach. Use git stash --keep-index to do this.
After doing this, I realized I wanted to follow Dmitry's answer because I wanted to have my undesired changes still stashed, but my to-be-commited changes both in the working directory and index/cache/stage so that I could test them before committing them.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.