为什么git认为未触及文件的每一行都发生了变化

为什么git认为未触及文件的每一行都发生了变化,git,Git,我不认为这是行尾差异问题-p4merge不认为文件中有任何更改,即使设置为识别行尾和空白差异 我的问题是,有时会发生以下情况: 首先,git status没有显示未提交的更改 然后我结帐到另一家分行 现在git status列出了一些已更改的文件 git diff在任何一个“已更改的文件”上,文件的每一行都显示为已更改。更改后的版本与原始版本相同 为什么会这样?为什么git认为文件已经改变了,而他们似乎没有这样做?为什么只是签出另一个分支会导致这种情况 我的第一个想法是行尾,但我不知道为什么

我不认为这是行尾差异问题-p4merge不认为文件中有任何更改,即使设置为识别行尾和空白差异

我的问题是,有时会发生以下情况:

  • 首先,
    git status
    没有显示未提交的更改
  • 然后我结帐到另一家分行
  • 现在
    git status
    列出了一些已更改的文件
  • git diff
    在任何一个“已更改的文件”上,文件的每一行都显示为已更改。更改后的版本与原始版本相同
为什么会这样?为什么git认为文件已经改变了,而他们似乎没有这样做?为什么只是签出另一个分支会导致这种情况

我的第一个想法是行尾,但我不知道为什么p4merge不会检测到这些。第二个想法是改变文件模式。我不知道怎样才能知道是不是这样
git config--list
显示core.filemode设置为false
git config--global--list
git config--system--list
不显示core.filemode的任何设置(我在这里告诉大家,因为我不确定不同的配置级别如何相互覆盖)。core.autocrlf设置为true

多个开发人员提交到我从中提取更改的同一存储库,所有这些都在Windows计算机上。我猜某个地方的某个人在某个位置上的某些设置导致了这种情况,但我不知道是本地的我还是其他人,或者可能是什么设置

列出为已更改的文件似乎不是随机的-如果我删除本地存储库,从远程克隆它(默认为正在签出的主分支),然后再次签出同一分支,
git status
每次都列出与已更改的文件完全相同的文件。这些文件有时是最近编辑的,有时是几年没碰过的。它们不仅是二进制文件(有时会损坏
core.autocrlf=true
),而且也是文本文件

执行命令
git-rm--cached-r.
然后执行
git-reset--hard
可以消除这些更改,但这种情况经常发生,这让人感到麻烦。我也很好奇是什么原因造成的

同样的存储库也会导致行结束问题。我认为这是一个单独的问题,所以我可能会为它提出另一个问题,但我在这里简要地提到它,以防它毕竟是相关的。签出另一个分支或从远程存储库提取更改有时会导致文件显示为已更改,并且这些文件上的
git diff
仅输出
warning:LF将被[file]中的CRLF替换。该文件将在您的工作目录中有其原始行结尾。

编辑:存储库的.gittributes文件中只有行
*text=auto
,没有其他内容

git-config的输出——列出
(包括颜色、编辑器文件路径、远程、difftool、用户名和电子邮件等内容的输入设置):

要在细节中显示此类“不可见”更改,请使用:

git diff --word-diff-regex=.
这将标记所有更改的字符,甚至是空白

最有可能的是,它将显示行结束的变化。如果您在Windows上工作并打开了
core.autocrlf
,git可能会使用另一种行尾,并将“错误”的行尾显示为diff


通过关闭
core.autocrlf
告诉git不要在意行尾应该可以解决您的问题。

git config core.autocrlf在克隆的回购中返回什么?是否有任何
.gittattributes
中包含
core.eol
指令?您在Windows和其他开发人员上工作吗?听起来好像^M或其他以Windows为中心的字符正在将其放入文件中。@VonC
git config core.autocrlf
outputs
true
.gittributes
中没有关于
core.eol
的任何内容@杰夫:是的,我在Windows上工作,就像其他开发者一样。现在我突然想到,存储库已经有好几年的历史了,开发人员来来往往。我不知道过去是否有人在其他平台上工作过(不过,所有Windows至少在过去一年中都在工作,而这个问题是几个月前才开始的)。您是否可以尝试再次克隆,但在克隆之前:
git config--global core.autocrlf false
。并查看问题是否仍然存在。是否可能是空白(制表符/空格)?尝试使用Git历史查看器,它允许您在显示差异视图时关闭空白。这确实表明每行中已删除^M字符。谢谢你!目前还没有解决导致这种情况的原因,但现在似乎离解决方案更近了。您告诉git总是以本机(即windows)行结尾存储文件。但是,该文件包含unix行结尾。因此git假设您删除了“^M”字符,这正是两个行尾之间的区别。那么这是因为一些开发人员将
core.autocrlf
设置为开,而其他人设置为关,所以意外的行尾会提交到数据库中吗?如果每个人都一直处于相同的设置,无论选择的设置是开还是关,这仍然是一个问题吗?另外,我知道可以通过向
.gittributes
添加适当的设置来解决这一问题,以避免我们必须为每个开发人员将
core.autocrlf
设置为合适的设置。是这样吗?@riksteri我想说“这取决于”-对于某些文件,您实际上希望有特定的行结尾(例如\n对于.sh文件,\r\n对于bat文件),对于其他文件,您必须决定策略。如果您选择一个特定的策略并实施它,那么可以正确地说这是由于缺少.gittributes造成的。但是你的需求会影响到什么是最好的设置;我得出的结论是
git diff --word-diff-regex=.