Git: drop file in a stash without applying it

▼魔方 西西 提交于 2020-01-07 06:25:13

问题


I am surprised not having found a response to this question but basically say I have a stash with several files in it (I can explore it through git extension for instance). Looking at its content, I'd like to drop some files before applying it, is it possible ?

The only workaround I can think of is:

  1. checkout the stash to a new branch
  2. checkout the targeted files
  3. stash again
  4. delete the branch

Is there something better ?

thanks


回答1:


You can directly use stash@{0} as a commit reference.

If your working tree is clean (no modified files), you can checkout the files you want :

git checkout stash@{0} -- file1 file2 file3

and then inspect the diff manually to keep what you want.


If you want something closer to the behaviour of git stash apply, you can create a patch and apply it :

git show -p stash@{0} -- file1 file2 file3 | git apply -

[EDIT] To list the files modified in stash@{0} :

git diff --name-only stash@{0}^ stash@{0}

If you want to get all files except one :

git show -p stash@{0} -- $(git diff --name-only stash@{0}^ stash@{0} |\
                           grep -v "thefile")



回答2:


Yes there is a better way to do it.

First of all, You can check the stash list as

git stash list

Then you can do below for checking contents of the stashed commits.

git stash show -p stash@{1}

Then you can apply using

git stash apply stash@{1}



回答3:


It seems like the tricky part of this question revolves around what you want the stash to look like when you're done. Since git stash {pop|apply} only affects the working tree (and sometimes index), it's easy enough to selectively take changes from a stash (enough so that I initially thought you were over-thinking the problem):

git stash pop
# maybe a 'git reset head' if the index was changed
git checkout -- file.with.unwanted.changes.in.stash

But those commands remove the stash entirely; and by contrast if I'd said git stash apply instead of pop, that leaves the stash unchanged. It sounds like you want the stash to remain with the changes you've selected (in case you should need to apply them again).

(I suppose alternately there could be times you'd want exactly the opposite - to leave in the stash those changes that you didn't apply, so they can be applied later.)

So taking a step back: what is involved in modifying a stash?

A stash, really, comprises two or three temporary commits. The special ref stash points to these commits, and a "stack" of multiple stashes is maintained using the reflog (which may be a bit of a hack, but generally is effective).

So to modify the stash is to create new commits (because commits are immutable) and rearrange the stash ref and reflog accordingly.

This is why the notations LeGEC mentions will work and may give you extra flexibility in reading a stash. But because the reflog usage is not the same as for non-stash refs, leveraging this fact to contrive a way to write to a stash could have unexpected results. I'm not saying the results would be horrible, or impossible to predict/control; but I think in the end you'd create more complexity than you'd avoid.

So if we confine ourselves to actual documented git-stash subcommands, then a stash is more or less atomic. When you create a stash there's a patch mode that lets you select working changes to put in the stack, but I'm aware of no corresponding functionality for pop/apply. Still, that's something:

If you have a clean work tree and a stash you want to split, you could try things like:

Apply some changes, and keep those same changes in the stash

git stash pop
git stash -p
# select the "good" changes
git checkout -- .
git stash apply

Apply some changes, and keep the remaining changes in the stash

git stash pop
git stash -p
# select the "unwanted" changes

Split the stash into two parts, decide what to do with them later

git stash pop
git stash -p
# select the "good" changes
git stash
# now the "good" changes are stash@{1} and the "unwanted" are stash@{0}



回答4:


Simple solution to remove a stash entry without applying it is to drop it:

git stash drop stash@{1}

Here 1 is the stash entry that you get by running:

git stash list


来源:https://stackoverflow.com/questions/43755453/git-drop-file-in-a-stash-without-applying-it

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!