56

I have a stash with a bunch of files in it.

But I can't apply my stash because of a conflicting file. I've identified the problematic file in my stash and I want to remove it.

How can I remove a single file from a stash without destroying the entire thing?

SQB
  • 3,926
  • 2
  • 28
  • 49
  • 1
    This can help you http://stackoverflow.com/questions/1105253/how-would-i-extract-a-single-file-or-changes-to-a-file-from-a-git-stash – Tim Mar 28 '14 at 20:29
  • 1
    @TimCastelijns So, from that answer, `$ git checkout stash@{0} -- ` would be the command I want? –  Mar 28 '14 at 20:53

5 Answers5

40

A stash is a commit (or really, two or even sometimes three commits) and you cannot change a commit. The literal answer to your question, then, is "you can't". Fortunately, you don't need to.

You say you can't apply your stash because of a conflicting file. But you can apply it, you just get a merge conflict. All you need to do is resolve the merge conflict.

Let's say the conflict is in file README.txt, just so there's something to write about here.

If you want to resolve it by keeping the on-branch version, apply the stash, then check out the on-branch version to resolve the conflict:

git stash apply
git checkout --ours -- README.txt  # or git checkout HEAD -- README.txt

If you want to keep the in-stash version, extract that one:

git checkout --theirs -- README.txt # or git checkout stash -- README.txt

Or, use any old merge resolution tool (I just use a text editor), and then "git add" the result.

Once you are all done with the stash, git stash drop will "forget" the commits that make up the stash. (Don't do this until you are sure you are done with it; it's very hard to get it back afterward.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • My error was that sourcetree wasn't letting me apply the stash because of a windows-specific error involving permissions and locked files. But this answers my question. –  Mar 28 '14 at 21:12
  • 2
    When attempting `git stash apply` I get an error due to the conflicts: `error: Your local changes to the following files would be overwritten by merge:` – BergQuester Jun 22 '16 at 19:04
  • 1
    @BergQuester: in this particular case, you're trying to `git stash apply` when you already have some existing change(s) in the work-tree. Normally even that would be OK, so I'm not entirely sure what's happening (I'd need to see `git status` output before the `apply`, and what flags you're giving to `git stash apply`). In general the way to handle this case, though, is to commit or stash the *current* changes, then use `git stash branch` to turn the previous stash into a new branch, and then use the full set of Git tools now that what you had stashed is safely stored as a branch. – torek Jun 22 '16 at 20:16
  • Saying that you "cannot change a commit" is deceptive. You can amend a commit, which creates a copy with everything the same except the files and hash. So what's the equivalent to 'amend a stash'? – Mark Jeronimus Jul 29 '22 at 09:39
  • 1
    @MarkJeronimus: It's not deceptive: what's deceptive is the option `--amend` itself. You're not amending a commit at all. You're making a new, different commit, with a new, different hash; the old commit continues to exist, and is still used by all the *other* branch and tag names that find this commit (ideally there are zero such names, but when there aren't, that's when the deception is exposed). There's no "amend a stash" either, and this time there's no `--amend` flag: you just have to apply (with `--index` perhaps) the original stash in its original place, drop it, and build a new one. – torek Jul 29 '22 at 09:42
  • That is, since `git stash` is a poor(ish, it's been improved) set of tools compared to all the regular Git tools, there's no fancy front end with a deceptive option like `git commit`'s `--amend`. The closest one gets is `git stash branch`, which checks out the parent of the stash clump of commits, creates a new branch name, and then applies (with `--index`) the stash and drops it. – torek Jul 29 '22 at 09:44
32

There is a workaround for this situation:

  1. save your stash as a patch file:

    $ git stash show -p > stash.patch
    
  2. apply this patch, skipping the conflicts (you will be asked for resolution of conflicts, just skip missing files):

    $ patch -p1 < stash.patch
    

Don't forget to clean up stash.patch afterwards!

Dmytro Sirenko
  • 5,003
  • 21
  • 26
3
  1. Stash your uncommitted changes.
  2. Apply your original stash
  3. Discard the file
  4. 4 Apply the stash containing your uncommitted changes.
Francisco Aguilera
  • 3,099
  • 6
  • 31
  • 57
1

I had the same issue today. I was working on a branch, stashed my modifications and wanted to apply them on another branch. But I noticed that I also stashed an unwanted file that created a conflict. Here's what I did to solve the issue:

  • git restore --staged path/to/file
  • git reset HEAD -- path/to/file to remove the file from the staging area

Then, I added the files I wanted only and was able to make my commit.

ZeFifi
  • 157
  • 1
  • 13
-1

delete the required file from your local codebase and then push it to stash. The changes will get reflected and your files will be deleted from stash.

viper03
  • 9
  • 1
  • 2