Categories
git git-stash

How do I stash only one file out of multiple files that have changed?

3564

How do I stash only one of the multiple changed files on my branch?

3

  • 1

    stackoverflow.com/a/19700341/1668622 is much shorter than the accepted answer, does not need any additional tools (like e.g. JesusFreke’s script) and it only stashes, what you wanted to stash

    – frans

    Sep 8, 2015 at 9:45

  • 11

    >>>>>>>>> git diff -- *filename* > ~/patch then git checkout -- *filename* and later you can re-apply the patch with git apply ~/patch

    – neaumusic

    Dec 23, 2015 at 2:08


  • 79

    Most existing answers below are outdated. Since Git 2.13 (Q2 2017) it is supported with git stash push [--] [<pathspec>...].

    Aug 15, 2017 at 13:23

3414

+50

git stash push -p -m "my commit message"

-p let’s you select the hunks that should be stashed; whole files can be selected as well.

You’ll be prompted with a few actions for each hunk:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help

16

  • 7

    I am a TortoiseGit addict. However TortoiseGit does not support stash -p. I award this answer because it remains the most interactive/user friendly.

    – Antonio

    Apr 15, 2015 at 13:53


  • 34

    you might want to add: git stash save -p my stash message; since the order of the argumenst is not very intuitive…

    Apr 23, 2015 at 9:12

  • 37

    Between this and git log -p, I think the -p flag must mean “do the cool thing that I want but don’t know how to express.”

    May 23, 2017 at 20:33

  • 2

    This is a correct answer, but it becomes unusable if you have too many hunks to work through.

    Feb 12, 2019 at 18:27

  • 26

    A quick call out to answer posted on a newer question: stackoverflow.com/a/5506483/2661238 by @svick git stash push -m <stash_name> <file_path_to_stash>

    – Deep

    Jun 23, 2019 at 16:14


1399

Disclaimer: the following answer is for git before git 2.13. For git 2.13 and over, check out another answer further down.


Warning

As noted in the comments, this puts everything into 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.


This will stash everything that you haven’t previously added. Just git add the things you want to keep, then run it.

git stash --keep-index

For example, if you want to split an old commit into more than one changeset, you can use this procedure:

  1. git rebase -i <last good commit>
  2. Mark some changes as edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Fix things up as necessary. Don’t forget to git add any changes.
  7. git commit
  8. git stash pop
  9. Repeat, from #5, as necessary.
  10. git rebase --continue

15

  • 47

    I find this approach to be much more simpler: stackoverflow.com/a/5506483/457268

    Sep 3, 2012 at 14:52

  • 581

    I’m not sure why this is being upvoted. Everyone must have a different expectation than me. The original post is asking “how do I stash just a portion of the uncommitted changes?” When I use git stash save -k, yes the index (green in git stat) is preserved, but the entire changeset (both green and red) goes into the stash. This violates the OP’s request, “stash only some changes”. I want to stash just some of the red (for future usage).

    – Pistos

    Dec 7, 2012 at 17:01


  • 71

    If you are more interested in the answer to the question posed by @Pistos (as I was), then look here: stackoverflow.com/questions/5506339/…

    – Raman

    Mar 17, 2013 at 19:22


  • 29

    @Raman: Excellent! git stash -p is exactly what I was looking for. I wonder if this switch was only recently added.

    – Pistos

    Apr 9, 2013 at 21:47

  • 14

    WARNING: git stash --keep-index is broken. If you make more changes, then try to git stash pop later you get merge conflicts because the stash includes the changed files you kept, not just the ones you didn’t keep. For example: I change files A and B, then stash B, because I want to test the changes in A; I find a problem with A that I then fix; I commit A; Now I can’t unstash because an old version of A is in the stash for no good reason causing a merge conflict. In practise A and B might be many files, perhaps even binary images or something, so I basically have to give up and lose B.

    – rjmunro

    Feb 26, 2014 at 17:28

896

Since Git 2.13 (Q2 2017), you can stash individual files, with git stash push:

git stash push [-m <message>] [--] [<pathspec>...]

When pathspec is given to ‘git stash push‘, the new stash records the modified states only for the files that match the pathspec
See “Stash changes to specific files” for more.

Simplified example:

 git stash push path/to/file

The test case for this feature shows a few more options off:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

The original answer (below, June 2010) was about manually selecting what you want to stash.

Casebash comments:

This (the stash --patch original solution) is nice, but often I’ve modified a lot of files so using patch is annoying

bukzor‘s answer (upvoted, November 2011) suggests a more practical solution, based on
git add + git stash --keep-index.
Go see and upvote his answer, which should be the official one (instead of mine).

About that option, chhh points out an alternative workflow in the comments:

you should “git reset --soft” after such a stash to get your clear staging back:
In order to get to the original state – which is a clear staging area and with only some select un-staged modifications, one could softly reset the index to get (without committing anything like you – bukzor – did).


(Original answer June 2010: manual stash)

Yet, git stash save --patch could allows you to achieve the partial stashing you are after:

With --patch, you can interactively select hunks from in the diff between HEAD and the working tree to be stashed.
The stash entry is constructed such that its index state is the same as the index state of your repository, and its worktree contains only the changes you selected interactively. The selected changes are then rolled back from your worktree.

However that will save the full index (which may not be what you want since it might include other files already indexed), and a partial worktree (which could look like the one you want to stash).

git stash --patch --no-keep-index

might be a better fit.


If --patch doesn’t work, a manual process might:

For one or several files, an intermediate solution would be to:

  • copy them outside the Git repo
    (Actually, eleotlecram proposes an interesting alternative)
  • git stash
  • copy them back
  • git stash # this time, only the files you want are stashed
  • git stash pop [email protected]{1} # re-apply all your files modifications
  • git checkout -- afile # reset the file to the HEAD content, before any local modifications

At the end of that rather cumbersome process, you will have only one or several files stashed.

9

  • 3

    This is nice, but often I’ve modified a lot of files so using patch is annoying

    – Casebash

    Nov 16, 2011 at 2:03

  • 1

    @Kal: true, stackoverflow.com/a/13941132/6309 suggests a git reset (mixed)

    – VonC

    Mar 22, 2013 at 7:43

  • 4

    git is fundamentally about managing a all repository content and index and not one or several files – that’s implementation overshadowing the problem being solved; it’s an explanation, but not a justification. Any source control system IS about “managing several files”. Just look what comments get upvoted most.

    Dec 23, 2015 at 11:09

  • 1

    -1 for recommending git stash --keep-index; as noted in the comments on bukzor’s answer, it simply doesn’t do what you think it does. Create two files, foo and bar. Commit them. Add a line to each. git add foo. git stash --keep-index. The desired result now is that you have your change to bar stashed, and your change to foo still present and staged. Reality is that you have your change to foo present and staged, but your changes to both files stashed. If you git reset and modify foo, you now cannot git stash pop due to conflict.

    Aug 5, 2016 at 22:53

  • 2

    This also stashed all staged files. So make sure you haven’t staged any changes

    Mar 31, 2020 at 11:07