Git 将相同的文件显示为已更改

标签 git cygwin

Git 向我显示整个文件已更改,而我似乎无法弄清楚这些更改。这是cygwin git,但它也发生在msysgit中

$ git --version
git version 2.1.1

$ diff <(git show HEAD:File.cs) <(cat File.cs)
// Shows no differences

$ diff <(git show HEAD:File.cs | xxd) <(xxd File.cs)
// Shows no differences

$ git diff
// shows the entire file has changed

$ git hash-object <(git show HEAD:File.cs)
7b3762473342a5b040835bfef9f6b45c109ba48b

$ git hash-object <(cat File.cs)
7b3762473342a5b040835bfef9f6b45c109ba48b

$ git hash-object File.cs
7b3762473342a5b040835bfef9f6b45c109ba48b

我有

$ git config --get core.fileMode
false

$ git config --get core.autocrlf
true

我真的不知道发生了什么,一切都希望它们是一样的,但 git 想要创建一个提交,说明整个内容已被删除并重新创建。有谁更了解 git 管道的人有什么建议吗?。我能想到的就是 git show 正在删除/规范化奇数行结尾。

更新:

我很确定它会发生,因为开发过程就是这样。从 git checkout ,rsync 到开发机器,开发,rsync 返回。我相信 rsync 弄乱了一些行尾。奇怪的是 gits 没有报告行尾,而且它似乎真的对到底发生了什么感到困惑。尽管比较文件的二进制表示似乎是相同的。

更新 2:

所以这非常烦人,我觉得我偶然发现了 git 中的一个错误。

例如

$ git gc
$ git checkout -- .
$ git clean -fd
$ git status

> shows a heap of modified files

我很确定它应该不会显示任何变化,无论它在哪里运行,但我得到了一个包含 20 个奇怪的东西的列表:(

最佳答案

这可能是由于 .gitattributes 文件指示 git 它应该执行 EOL 规范化但存储库包含非规范化行结尾。

简单的解决方法是从 .gitattributes 中删除相关行。这可能是

* text=auto

*.cs text

这是如何发生的一个简单示例如下:

$ echo "Hello World" > example.txt
$ unix2dos example.txt #Make sure it uses CRLF
$ git add example.txt
$ git commit -m "commit 1"
$ #Instruct git that all .txt files should be normalized
$ echo '*.txt text' >> .gitattributes 
$ git add .gitattributes
$ git commit -m "commit 2"

现在存储库处于一种奇怪的状态,因为 .gitattributes 声称文件在添加到索引之前应该被标准化,但是当前提交的版本没有被标准化。

然而,此时git status并没有注意到,因为文件本身在加入索引后大小和mtime都没有变化,所以索引被认为是最新:

$ git status
On branch master
nothing to commit, working directory clean

但是任何使索引无效的东西都会导致 git 认为文件是脏的:

$ touch example.txt
On branch master
Changes not staged for commit:

        modified:   example.txt

no changes added to commit (use "git add" and/or "git commit -a")

git reset --hard 或任何其他试图将文件重置为它应该处于的状态的操作都不会解决这个问题。这是因为无法将文件添加到存储库中的当前状态的索引中,因为已指示 git 规范化该文件,并且规范化永远无法生成当前提交的对象。

这就是为什么 GITATTRIBUTES(1) 手册页建议在像这样引入行结束规范化时显式使整个索引无效:

$ echo "* text=auto" >>.gitattributes
$ rm .git/index     # Remove the index to force Git to
$ git reset         # re-scan the working directory
$ git status        # Show files that will be normalized
$ git add -u
$ git add .gitattributes
$ git commit -m "Introduce end-of-line normalization"

阅读 gitattributes 中关于“行尾转换”的部分手册页了解更多详情。

与其快速修复从 .gitattributes 中删除该行,不如保留该行结束规范化规则并继续并立即对其进行规范化。这基本上只是意味着提交 20 多个不会消失的更改,但是您可以按照上面关于引入行结束规范化的说明(减去编辑 .gitattributes)有条不紊地进行,然后感觉相信它不会再次发生,因为所有文件现在都以规范化结尾提交,并且您添加的任何 future 文件也将被规范化。这主要是个人喜好。

关于Git 将相同的文件显示为已更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26542226/

相关文章:

git - 我更改了我的 github 用户名。如何更新本地存储库以指向新位置?

git - 您如何在不暂存文件的情况下添加新文件?

python - subprocess.call 在 Windows 上使用 cygwin 而不是 cmd

vim - Cygwin 更新后 vi 或 vim 无法启动

C++在派生类中调用基类的模板方法

windows - 通过 Cygwin(调用 shell 脚本)创建的文件没有正确的 Windows 权限

java - Maven 忽略 scm 标签

git - 在 GIT 中,如何防止人们更改或删除已推送的提交?

Git Push 从另一个存储库提交,没有原始用户信息

cygwin-1.75 中的 python win32api