我如何强制 git 检测更改的文件(由于工作树编码)?

How do I force git to detect changed files (due to working-tree-encoding)?

我刚刚发现有些文件实际上是 UTF16 却被标记为简单文本,而 git 在进行比较时不喜欢这样。 我玩弄了 .gitattributes(专门为这些文件设置 text working-tree-encoding=UTF-16),然后对某些文件做了一些 iconv。然后我还原了所有这些更改(包括 .gitattributes)。 实际上做了一个git reset --hard,但有些文件仍然乱七八糟,git 看不出有什么不同。也试过 git update-index --no-assume-unchanged,但没有成功。

如何强制 git 实际检测更改的文件?

LE:我删除了文件并恢复了它,它实际上解决了问题,但我不想手动执行此操作(即检查所有文件并删除它们)。还检查了另一个目录中的克隆,乱七八糟的文件没问题。

这是(我认为)由于 Git 中的一种错误。 Git 几乎在任何时候都试图在其索引中保留有关工作树中文件的信息,以及这些文件的内容与索引所指副本的比较情况。这就是索引充当 缓存 的原因(以及如何),因此第三个名称的来源:Git 将其索引称为 暂存区 以及“索引”,但在一些地方使用术语“缓存”。1

在任何情况下,.gitattributes 文件(和 .git/info/attributes)会影响 Git 在从索引读取和写入工作树时如何进行数据转换,反之亦然.这意味着如果您更改.gitattributes 文件的内容部分或所有缓存副本可能会变得无效。然而,git status 命令和其他 Git 命令并没有注意到这一点。

从工作树中删除文件会导致 Git 意识到该文件的缓存信息已过时。然而,这是相当激烈的。还有另一种相当激烈的替代方法,它可以快速使 Git 的 所有 文件的缓存数据失效:

rm .git/index; git reset
# assumes Unix-like commands and a Unix-style shell

这会清除所有阶段性更改,但不会触及您的工作树文件。 注意这个!这不是官方认可的处理问题的方法,以后可能会失效。

Git 需要开始注意属性文件的更新(这将有助于自动修复问题,因此您不必自己做任何事情),and/or 获取正式命令以宣布缓存数据已过期,以便您可以明确强制刷新(git update-index --really-refresh 已关闭,但实际上在这里不起作用)。不过,在那之前,如果您更改 .gitattributes 设置(或 core.autocrlf 设置),则可以强制 Git 使用此处的删除和重置方法从头开始重建索引。


1我们现在主要在标志中看到这个:例如 git rm --cachedstaging area 术语通常更优越,--staged 现在通常是一个选项,其含义与 --cached 完全相同,例如,在 git diff 中。但是,Git 并不以一致性着称,因此 git rm 仍然缺少 --staged,而 git restore 只有 --staged 引用索引副本。同时 git apply 使用具有不同含义的 --index--cached 并且没有 --staged 选项!