【发布时间】:2017-05-03 08:55:18
【问题描述】:
我很惊讶没有找到对这个问题的回复,但基本上说我有一个包含几个文件的存储区(例如,我可以通过 git 扩展来探索它)。看它的内容,我想在应用之前先删除一些文件,可以吗?
我能想到的唯一解决方法是:
- 将存储签出到新分支
- 签出目标文件
- 再次藏匿
- 删除分支
还有更好的吗?
【问题讨论】:
我很惊讶没有找到对这个问题的回复,但基本上说我有一个包含几个文件的存储区(例如,我可以通过 git 扩展来探索它)。看它的内容,我想在应用之前先删除一些文件,可以吗?
我能想到的唯一解决方法是:
还有更好的吗?
【问题讨论】:
您可以直接使用stash(或stash@{0})作为提交参考。
如果你的工作树是干净的(没有修改过的文件),你可以签出你想要的文件:
git checkout stash -- file1 file2 file3
然后手动检查差异以保留您想要的。
如果您想要更接近git stash apply 的行为,您可以创建一个补丁并应用它:
git show -p stash -- file1 file2 file3 | git apply -
[编辑] 列出在stash 中修改的文件:
git diff --name-only stash^ stash
如果你想获取除一个以外的所有文件:
git show -p stash -- $(git diff --name-only stash^ stash | grep -v "thefile")
【讨论】:
git show -p stash@{0} -- file1 file2 file3 | git apply - 工作,我得到“错误:无法识别的输入”,而它在没有| git apply - 的情况下工作
git show -p ... > patch && git apply patch 有效吗?
是的,有更好的方法来做到这一点。
首先,您可以将存储列表检查为
git stash list
然后您可以执行以下操作来检查隐藏提交的内容。
git stash show -p stash@{1}
然后你可以申请使用
git stash apply stash@{1}
【讨论】:
这个问题的棘手部分似乎围绕着您希望完成后的存储外观。由于git stash {pop|apply} 仅影响工作树(有时影响索引),因此很容易有选择地从存储中获取更改(足以让我最初认为您过度思考问题):
git stash pop
# maybe a 'git reset head' if the index was changed
git checkout -- file.with.unwanted.changes.in.stash
但是这些命令完全删除了存储;相比之下,如果我说git stash apply 而不是pop,那么存储不会改变。听起来您希望存储区保留您选择的更改(以防您需要再次应用它们)。
(我想有时您可能希望完全相反 - 将那些您未应用的更改留在隐藏中,以便以后应用它们。)
所以退后一步:修改存储涉及什么?
实际上,一个 stash 包含两个或三个临时提交。特殊的 ref stash 指向这些提交,并使用 reflog 维护多个存储的“堆栈”(这可能有点小技巧,但通常是有效的)。
所以修改 stash 就是创建新的提交(因为提交是不可变的)并相应地重新排列 stash ref 和 reflog。
这就是 LeGEC 提到的符号会起作用的原因,并且可以为您在阅读存储时提供额外的灵活性。但是由于 reflog 的使用与非存储 refs 的用法不同,因此利用这一事实来设计一种 write 到存储的方法可能会产生意想不到的结果。我并不是说结果会很糟糕,或者无法预测/控制;但我认为最终你会创造出比你避免的更多的复杂性。
因此,如果我们将自己局限于实际记录的git-stash 子命令,那么存储或多或少是原子的。当您创建一个存储时,有一个 patch 模式,可让您选择要放入堆栈的工作更改,但我知道弹出/应用没有相应的功能。不过,还是有这样的:
如果您有一个干净的工作树和一个要拆分的存储,您可以尝试以下操作:
应用一些更改,并将这些相同的更改保留在存储中
git stash pop
git stash -p
# select the "good" changes
git checkout -- .
git stash apply
应用一些更改,并将剩余的更改保留在存储中
git stash pop
git stash -p
# select the "unwanted" changes
将存储分成两部分,稍后决定如何处理它们
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}
【讨论】:
git stash -u 或git stash -a stashes 中,并包含“untracked-sans-ignored”或“untracked-including-ignored”文件(仅;这与索引和工作树状态不同,它们都保存所有跟踪的文件)。
删除隐藏条目而不应用它的简单解决方案是删除它:
git stash drop stash@{1}
这里1 是您通过运行获得的隐藏条目:
git stash list
【讨论】: