git reset的问题 – 在添加.gitattribute之后 – 不应该存在的局部变化

合并同事的捆绑后,我观察到CRLF问题。 有时LF的线条被混合到源头,可能是合并的线条。 因此,我们决定添加.gitattributes文件以下内容(删除注释):

 *.cpp text *.h text *.inc text *.cfg text *.dic text *.sln text eol=crlf *.vcxproj text eol=crlf *.filters text eol=crlf *.user text eol=crlf *.rc text eol=crlf *.rc2 text eol=crlf 

现在我观察这个奇怪的行为。 我可以看到很多modified: ...文件(即不挂起),不应该在那里。 我试过git reset --hard ,但是文件仍然有相同的状态。 我试图再次克隆存储库 – 相同的结果。

我从Git-1.7.11-preview20120620.exe git version 1.7.11.msysgit.0安装git version 1.7.11.msysgit.0作为当前版本的Windows

还有什么我应该尝试?

谢谢,彼得

Solutions Collecting From Web of "git reset的问题 – 在添加.gitattribute之后 – 不应该存在的局部变化"

原因

导致此问题的是.gitattributes中的* text=auto设置。 您可以删除它并且过后快乐地生活,但是您可能有非回购默认行编码的文件,甚至包含几个不同行结束编码的文件(即LF和CRLF,甚至CR!)在您的回购。

为什么会发生(详情)

当git按原样检出文件时,它会在添加/提交时修改行尾 。 该文件实际上还没有修改,但git已经认为它被修改,因为它会 ,由于回购的设置。

不知何故,它与git有点怪异。 例如, git reset --hard有时可以工作,有时候不会,也许取决于您的设置。 或者,如果您进入.gitattributes并将扩展名标记为二进制文件,则修改后的文件会奇迹般地消失:

 *.ext binary 

即使在删除二进制标记之后,甚至在执行git reset --hard之后,效果仍会保持不变,因此可能是git错误或git缓存问题。 对文件做git -rm ,然后做git reset --hard恢复修改后的标记。

如何解决它

我们在这里假设你想保持你的* text=auto设置,这样git会警告你现在和将来在各种文本文件中的不一致的行尾。 如果是的话,选择你的方法:

选项0 :暂时从标记文件中修改 git

  1. 编辑.gitattributes ,注释掉* text=auto ,保存
  2. git status (这一步需要在.gitattributes中有git记录的变化)
  3. git reset --hard (这会恢复* text=auto并且在你的工作目录中也会产生任何改变)。

这通常是有效的(除了可能最不经意的情况)。 它也推迟了这个问题,这个问题很可能在稍后的某个时候出现,因为行结局还没有被标准化。

这个选项是非常好的,当你不得不倒退前一个没有被标准化的提交时,比如在一个rebase或者其他一些git工作中,你知道现有的提交会规范行结束,但是git抱怨修改过的文件现在阻止了你从继续。 所以基本上使用这种方法,当你需要关闭和忽略修改的文件,真正没有修改您的特定上下文的混帐。

选项1 :简单的“最终用户”修复

如果你只有几个文件,确保你的.gitattributescore.autocrlf被设置为你喜欢的,然后只是做一个git add/commit ,你不应该再次看到这个问题。 这些文件将被转换为您所需的行尾,并存储在您的回购库中,如您的配置中所述。 这个提交将作为“整个文件已经改变”存储在你的仓库中,因为每一行都会改变其行结束。 对于较大或开源的回购协议中的一些文件是好的。 一定要合并或樱桃选择提交到所有分支机构,因为问题将存在于所有有这些文件的分支机构,直到你解决它。 顺便说一下,这里是你可以使用选项0.即如果你切换到一个未固定的分支,并抱怨,运行选项0,然后执行修复(合并或樱桃采摘)。

重要提示:如果您要使用此选项1的路线,请确保正确转换修改的文件。 git可能不会像你期望的那样为你完成,所以在你提交之前自己动手,比如使用这个: 将换行格式从Mac转换到Windows git可能会被混淆的原因是我已经看到有三个CR的文件, LF和CRLF行结束格式。 在提交之前,将这些文件自行编入您的首选格式。

选项2 :高级机制“git历史重写”修复:

如果你有一个更私人的回购,并不害怕重写历史,去看看这个: git看到整个文件作为一行,由于mac行结束这将重写整个回购和摆脱任何地方的所有树,分行永远! 确保包含所有可能需要标准化的潜在的麻烦文本文件扩展名,否则可能会在稍后显示。

在我的情况下,我做了选项2,因为我正在处理大量的分支文件结束问题。 但后来我有一些意想不到的扩展显示,我没有正常化,只做了选项1,因为我只错过了5-6个文件。