CWallach
CWallach

Reputation: 109

How to remove file from git stash

I'm working on Branch A, then do "git stash" (with multiple files changed) and checkout branch B. Changes are made and branch B is committed and pushed. Then "git stash pop" reports a merge conflict because a binary IDE file changed.

I don't want to merge a binary file. Just, how does one delete the original stashed binary file while retaining the other edited files?

Upvotes: 0

Views: 1151

Answers (1)

torek
torek

Reputation: 488193

Technically, you can't. The reason is simple: a stash is nothing but commits, and no commit can ever be altered.

As everyone noted in the comments, you don't need to remove this file. An attempt to apply the stash will stop in the middle of the application with a merge conflict. At this point, Git returns control to you; it becomes your job to select the correct merge result, in this case by selecting whichever binary file you prefer.

The tricky part is seeing which binary file is which. The thing to know here is that the stage 2 or ours (--ours in git checkout) file is the one that was in the working tree at the start of the merge. The stage 3 or --theirs file is the one in the stash; that's the file that was in place when you ran git stash.1 There is also a stage 1, or merge base, copy of the file, but you can ignore that one in this case: you will want the "ours" copy if you want the one you obtained via git checkout B, or the "theirs" copy if you want the one you stashed earlier.

It may be the case that the binary file should never have been in any of these commits (that's often the case for binary files: that they should never have been committed, that is). Unfortunately, it is far too late, because of the fact that no existing commit can ever be changed. So just go ahead and resolve the conflict first. Later, you might look into making sure that future commits don't store these particular binary files, if they shouldn't.


1Technically, git stash makes two commits. One of these two commits contains exactly what was in Git's index at the time you ran git stash. This commit is completely ignored later unless you choose --index while applying it. The other of the two commits contains the working tree copies of each of the files that was already in Git's index. The git stash apply code always uses this commit (whether or not you use --index when applying).

To understand all of this, read up on how Git actually makes new commits from what is in Git's index, and how Git's index works. This takes most people a fair bit of time when learning about Git, so don't worry if it doesn't "click" for a while.

Upvotes: 1

Related Questions