1789
votes

How can I stash a specific file leaving the others currently modified out of the stash I am about to save?

For example, if git status gives me this:

younker % gst      
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   app/controllers/cart_controller.php
#   modified:   app/views/cart/welcome.thtml
#
no changes added to commit (use "git add" and/or "git commit -a")

and I only want to stash app/views/cart/welcome.thtml, how would I do that? Something like (but of course this does not work):

git stash save welcome_cart app/views/cart/welcome.thtml
5
The "possible duplicate" question currently has an incorrect answer marked as accepted.Penguin Brian
you can use git checkout -- filename and revert it to the original state.visualex
@visualex it will indeed revert it, but not stash itJesper
Re Penguin Brian's comment: Yes, the accepted answer to the "possible duplicate" question links to this question for recent versions of git.Mars
$ git stash -- filename.extLini

5 Answers

2677
votes

EDIT: Since git 2.13, there is a command to save a specific path to the stash: git stash push <path>. For example:

git stash push -m welcome_cart app/views/cart/welcome.thtml

OLD ANSWER:

You can do that using git stash --patch (or git stash -p) -- you'll enter interactive mode where you'll be presented with each hunk that was changed. Use n to skip the files that you don't want to stash, y when you encounter the one that you want to stash, and q to quit and leave the remaining hunks unstashed. a will stash the shown hunk and the rest of the hunks in that file.

Not the most user-friendly approach, but it gets the work done if you really need it.

346
votes

I usually add to index changes I don't want to stash and then stash with --keep-index option.

git add app/controllers/cart_controller.php
git stash --keep-index
git reset

The last step is optional, but usually, you want it. It removes changes from the index.


Warning As noted in the comments, git stash --keep-index pushes everything onto the stash, both staged and unstaged. The --keep-index just leaves the index alone after the stash is done. This can cause merge conflicts when you later pop the stash.

69
votes

To add to svick's answer, the -m option simply adds a message to your stash, and is entirely optional. Thus, the command

git stash push [paths you wish to stash]

is perfectly valid. So for instance, if I want to only stash changes in the src/ directory, I can just run

git stash push src/
3
votes

If you're OK with using a GIT GUI client, Fork can pretty seamlessly do this as of May 2020. A GIF of the partial stash functionality will show this better than any words: GIF of partial stash functionality in git-fork

Note that Fork (which is a difficult name to Google for!) is not free software and costs $50 after the evaluation period, but you can just ignore the popups like you do for WinRAR or WinZip.

1
votes

If you are using visual studio code there is a simpler way to stash selected files.

  1. Go to Source Control tab
  2. Select files those you want to stash
  3. Right click on it, you will see many options. Click on Stash Changes
  4. Now it will ask you to add some stash message. Add understandable message.

enter image description here enter image description here