git如何快速检测到文件修改?
它是否对repo中的每个文件进行哈希并比较SHA1?这需要很多时间,不是吗?
或者它比较atime,ctime或mtime?
我正在 Intellij 中开发一个使用 git 的 Java 项目。相当多的文件是蓝色的(表明已进行更改),但是当我右键单击它们并单击“Git -> 与最新存储库版本比较”时,它说内容是相同的。有谁知道为什么会发生这种情况?它似乎只发生在我打开查看但未更改的文件上。如果我不小心添加了额外的空白然后将其删除或其他什么情况,会发生这种情况吗?或者只是一般的额外空白?
考虑一下我们将以下命令应用于hello.txtgit 下跟踪的文件(在干净的工作副本中):
echo "hi" >> hello.txt
mv hello.txt bye.txt
git rm hello.txt
git add bye.txt
git status
Run Code Online (Sandbox Code Playgroud)
结果:
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
renamed: hello.txt -> bye.txt
Run Code Online (Sandbox Code Playgroud)
因此,git 知道它是同一个文件,即使它被重命名了。我有一些模糊的记忆,git 检查 inode 以确定新文件与旧的已删除文件相同。 不过,这个和这个SO 答案表明 git 只检查文件的内容,并且不会以任何方式检查它是否是相同的 inode。(我的结论(*):如果我对文件进行更大的修改,git 将不会检测到重命名,即使 inode 仍然相同。)
因此,在我看来,很明显,我错了,git 不检查 inode(或任何其他文件系统信息),只检查内容。但后来,我发现了另一个答案,它声称
除了时间戳之外,它[即git]还记录lstat的大小、inode和其他信息,以减少误报的机会。当您执行 git-status 时,它只需对工作树中的每个文件调用 lstat 并比较元数据,以便快速确定哪些文件未更改。
我对此实际上有两个问题:
Git 确实依赖(也)依赖 inode 来检测文件是否已更改,但它不使用 inode 来检测文件重命名。