你可以尝试(
git update-index手册页面):
git update-index --skip-worktree -- path
跳过工作树标记可以用一句话来定义:当读取一个条目时,如果它被标记为跳过工作树,则Git假装它的工作目录版本是最新的,并读取索引版本。但是如 "
git assume unchanged vs skip worktree" 中所述,这两个选项都有问题。"--assume-unchanged" 在索引被丢弃(例如 "git reset")时会重置自己,因此迟早会使您感到困惑。"--skip-worktree"也是一样。
此外,请确保使用Git 2.24(2014年第四季度)。
自2012年(原始问题)以来,git stash已被移植到C语言中(不再是shell脚本),但是它在新实现中必须(重新)学习将刷新的索引写回磁盘。
请参见
提交34933d0(由
Thomas Gummerer (tgummerer
)于2019年9月11日提交)。
(由Thomas Gummerer -- tgummerer
--合并于提交34933d0,2019年9月20日)
stash
: 确保写入刷新后的缓存
在将stash转换为C语言时,调用'git update-index --refresh
'的方式被'refresh_cache()
'函数替换。
只要索引仅需要在内存中使用,而不是从磁盘重新读取,这样做就可以了。
然而,在许多情况下,我们确实需要将刷新后的索引写入磁盘,例如'merge_recursive_generic()
'在重新从磁盘读取之前会丢弃内存中的索引,在'apply --quiet
'的情况下,我们当前使用的'refresh_cache()
'没有写入索引到磁盘是没有意义的。
始终在刷新后将索引写入以确保与脚本stash相比没有退化。
在未来,我们可以考虑在确定后续调用实际上不需要刷新缓存并且不需要在stash退出后或已经写入其他位置后刷新时,尽可能避免写入。
警告,当使用--quiet
选项与git stash一起使用时,该索引可能不会被正确重写:自Git 2.25(2020年第一季度)以来,对"git stash
pop"的最近更新使得该命令在运行时清空索引,这已得到纠正。
请看提交df53c80(2019年11月13日),作者是Thomas Gummerer (tgummerer
)。
(合并于提交3c3e5d0,由Junio C Hamano -- gitster
--于2019年12月1日处理)
stash
:确保在写入索引之前我们拥有有效的索引
报告人:Grzegorz Rajchman
签署者:Thomas Gummerer
在'do_apply_stash()
'中,我们最终会刷新索引。
自34933d0eff ("stash
: make sure to write refreshed cache",2019-09-11,Git v2.24.0-rc0 -- merge listed in batch #6)以来,当使用参数'--quiet
'调用'git stash apply
'时,我们还会写入刷新后的索引。
但是,如果没有使用参数'--index
'调用'git stash apply
',则在'else'子句中也会丢弃索引。
我们需要这样做是因为我们使用一个外部的'git update-index --add --stdin',这将导致内核索引过时。
稍后我们调用'refresh_and_write_cache
',现在会导致写入被丢弃的索引,这意味着我们实际上是在写入一个空的索引文件。
显然,这是不正确的,或者说不符合用户的预期行为。
我们不应该在未经请求的情况下修改用户的索引。
确保在丢弃当前内核索引后重新读取索引,以避免处理过时的信息。
相反,我们也可以完全放弃'discard_cache()
'和'read_cache()
',但这会使我们容易陷入与34933d0eff相同的陷阱,因此最好避免这种情况。
在静默情况下,我们还可以完全放弃'refresh_and_write_cache
'。
在旧版stash中,我们依赖于'git status
'在传递'--index
'至'git apply
'时,在调用'git read-tree
'之后刷新索引。
然而,替换'git read-tree
'的'reset_tree()
'调用总是传递与'-m
'等效的选项,使得刷新索引变得不必要。