git 无法暂存文件,将所有文件显示为重复,但字符大小写不是问题

Posted

技术标签:

【中文标题】git 无法暂存文件,将所有文件显示为重复,但字符大小写不是问题【英文标题】:git fails to stage files, show all files as duplicate but the char casing is not an issue 【发布时间】:2019-08-20 17:40:45 【问题描述】:

在我的例子中,我对我的一个文件进行了简单的一行更改并想提交我的更改,但注意到 commit -am "" 没有添加/提交文件。

发出 git ls-files --stage 后,我可能看到项目中的所有文件都显示为重复文件。这是其中一个文件的示例

100644 6314bd3f89d1b794c6d8c0fb9bb4aa492e2d510a 0   SquirrelFoH/Squirrel.FoH.ViewModels/UserLoginViewModel.cs
100644 6314bd3f89d1b794c6d8c0fb9bb4aa492e2d510a 0   SquirrelFoH/Squirrel.FoH.ViewModels/UserLoginViewModel.cs

有趣的是,一些显示广告重复的文件根本没有被我修改,但有些仍然显示为重复,正如您在下面看到的那样,大小写不是这里其他 SO 帖子中的问题。

更新

虽然这不能解决我上面描述的问题,但它帮助我使用了git reset --hard HEAD~1,它将 HEAD 指针重置为第二次最后提交,这是有效的提交。我使用上面的--hard 丢弃最后一次提交,因为它对我造成了上述问题。 如果您需要保留这些更改,请改用--soft 将 HEAD 重置为您上次提交之前的提交,并将上次提交中的更改添加到暂存区。

git reset --hard HEAD~1
git reset --hard HEAD~2
git reset --hard HEAD~3
...

上述命令在最后一次提交之前重置 HEAD 指针 1、2、3、... 提交并丢弃之后的任何更改。如果您不想放弃这些更改,请使用--soft 而不是--hard,在这种情况下,这些更改将为您上演。

这就是我的情况。下面,最后一次提交是提交 A,它是在最后一次将远程更改拉入我的本地分支后开始显示重复项的提交。提交 B、C、... 是提交 A 之前的提交:

commit A
commit B - git reseat --hard HEAD~1
commit C 

,现在我的最后一次提交是提交 B,它没有重复项。我现在可以尝试再次合并,看看是否会遇到与提交 A 相同的问题。正如我所提到的,这并不能解决问题,但至少允许我尝试重新创建它或继续我的工作并处理稍后合并。

【问题讨论】:

我敢打赌,你在 Windows 上,并且文件在 修订树 上重复,大小写不同。 我确信在某些 MacOS 特定版本的 Git / 例程中存在一个错误,它将这些重复的条目放入索引中。你是最近第三个提出这种问题的人,虽然我已经找不到另外两个了。如果这是一个错误,git --version 可能会帮助确定 Git 的哪个版本有它。我也很想知道它们是否符合 fsmonitor 资格(请参阅 git ls-files 文档以获取 -f 标志)。 @torek 你可以通过任何方式帮助解决这个问题***.com/questions/55426546/… 我遇到了严重的问题,想知道是否可以恢复丢失的文件 【参考方案1】:

您必须检查问题是否在 Git 2.22.1(2019 年第三季度)/ Git 2.25(2020 年第一季度)中仍然存在,因为 fsmonitor 收集的数据未正确写回磁盘索引文件(在 Mac、Linux 或 Windows 上)

参见Johannes Schindelin (dscho)commit b5a8169、commit d4c0a3a(2019 年 5 月 24 日)。(由 Junio C Hamano -- gitster -- 合并于 commit 10432cc,2019 年 7 月 25 日)

mark_fsmonitor_valid():如果需要,将索引标记为已更改

如果没有这个错误修复,t7519's four "status doesn't detect unreported modifications" test cases 偶尔会失败(而且,奇怪的是, 很多在 Windows 上更频繁)。

原因是这些测试用例故意使用了 git status 如果检测到任何更新,则重写索引:他们 首先清理工作树,运行git status 来更新索引 如向临时读者显示输出,然后使工作树变脏 再次,如果使用模拟运行,预计不会报告任何更改 fsmonitor 钩子。

这个策略的问题是索引是在 在干净的工作树上说git status 错误原因:不是 因为索引被标记为已更改(不是),但是因为 录制的mtimes 对索引自己的 mtime 很活泼。

由于 Windows 上的 mtime 粒度为 100 纳秒(参见例如 https://docs.microsoft.com/en-us/windows/desktop/SysInfo/file-times), 文件的mtimes 通常与索引“不够”,所以 git status 调用当前并不总是更新索引 (包括fsmonitor 扩展),导致测试用例失败。

明显的解决方法:如果我们更改 any 索引条目的 CE_FSMONITOR_VALID 标志,我们也应该将索引标记为已更改。 这将导致索引写入git status包括更新的fsmonitor 扩展。

旁注:尽管读者可能认为t7519 问题 考虑到 ext4 文件系统,应该在 Linux 上更多更流行 (似乎每个 Linux 发行版都使用它)将 mtimes 存储在 纳秒精度。但是,ext4 使用 current_kernel_time()(请参阅 https://unix.stackexchange.com/questions/11599#comment762968_11599;它 令人惊讶地很难找到有关此类的任何适当信息来源 ext4 问题),其准确性似乎取决于许多因素,但 安全性比 NTFS 的 100 纳秒粒度更差(同样,它是 可怕很难找到任何关于这个的远程权威 题)。所以似乎隐藏错误的活泼索引条件 由这个补丁修复的可能性在 Linux 上比在 视窗。但并非不可能;-)


使用 Git 2.25(2020 年第一季度),fsmonitor 更加健壮,并删除了不应触发的错误 BUG()。

见Junio C Hamano (gitster)commit 61eea52(2019 年 11 月 13 日)。(由 Junio C Hamano -- gitster -- 合并于 commit aec3b2e,2019 年 12 月 1 日)

fsmonitor: 不要将位图大小与分割索引的大小进行比较

报告者:Utsav Shah帮助者:Kevin Willford帮助者:William Baker

3444ec2e ("fsmonitor: 不要用要删除的条目填充位图", 2019-10-11, Git v2.24.0-rc1 -- merge 在batch #11 中列出) 添加了一些健全性检查确保 fsmonitor 位图中的位位置不会超出索引的末尾。

由于位图中的每个位都对应于索引中的一个路径,因此大多数情况下这是正确的检查。

除了我们处于拆分索引模式并查看要覆盖在基本索引上但在基本索引实际合并之前的增量索引的情况,即在 read_ 和 write_fsmonitor_extension() 中。

在这些代码路径中,拆分/增量索引中的条目通常是整个路径集的一小部分(否则我们为什么要使用拆分索引?),所以fsmonitor 使用的位图几乎总是大于部分索引中的条目数,不正确的比较会触发BUG()。

【讨论】:

以上是关于git 无法暂存文件,将所有文件显示为重复,但字符大小写不是问题的主要内容,如果未能解决你的问题,请参考以下文章

Git 暂存文件列表

JGit Java Git 库取消暂存文件

如何在 git 中取消暂存已删除的文件? [关闭]

git:比较更改

Git瓷器命令将单个文件恢复为其HEAD状态但保持其分阶段状态?

本地分支在没有明显原因的情况下显示未暂存的更改和未跟踪的文件[重复]