git reset问题 - 添加.gitattribute后的硬盘 - 不应该存在的本地更改

pep*_*epr 12 windows git gitattributes

在合并我的同事的捆绑后,我发现了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
Run Code Online (Sandbox Code Playgroud)

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

git version 1.7.11.msysgit.0已从Git-1.7.11-preview20120620.exe下载的Windows 安装当前版本安装.

我还应该尝试什么?

谢谢,彼得

Den*_*nis 14

原因

它正在* text=auto设置.gitattributes导致此问题.你可以删除它并过上幸福的生活,但是你的repo中可能有非repo-default行编码的文件,甚至包含几种不同行结束编码的文件(即LF和CRLF,甚至CR!).

为什么会发生这种情况(详情)

当git按原样检出文件时,它将在添加/提交时修改行结尾.该文件实际上尚未修改,但git已将其视为已修改,因为它将由于repo的设置而被修改.

不知怎的,它对git有点奇怪.例如,git reset --hard有时可以工作,有时不工作,可能取决于您的设置.或者,如果您进入.gitattributes并将扩展名标记为二进制,则修改后的文件会神奇地消失:

*.ext binary
Run Code Online (Sandbox Code Playgroud)

即使你git reset --hard再次删除二进制标记后,效果仍然存在,因此它可能是一个git bug或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会抱怨修改过的文件现在阻止你继续.因此,当你需要git来关闭并忽略那些真正没有为你的特定上下文修改过的修改过的文件时,基本上都会使用这个方法.

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

如果您只有几个文件,确保您.gitattributescore.autocrlf设置根据自己的喜好,然后就做一个git add/commit,你不应该再看到这个问题.这些文件将转换为您想要的行结尾并存储在您的仓库中,如配置中所述.此提交将作为"整个文件已更改"存储在您的仓库中,因为每行都会更改其行结尾.对于较大或开源的回购中的一些文件,这很好.一定要合并或挑选提交到所有分支,因为问题将存在于具有这些文件的所有分支中,直到您修复它为止.顺便说一下,你可以在这里使用Option 0.即如果你切换到一个不固定的分支,然后它抱怨,运行选项0,然后进行修复(merge或cherry-pick).

重要提示:如果您要使用选项1的此路由,请确保正确转换已修改的文件.git可能不会像你期望的那样为你做,所以在你提交之前自己做,即使用它:将换行格式从Mac转换为Windows git可能会混淆的原因是我看到有三个CR的文件, LF和CRLF行结束格式化.在提交之前将它们自己压缩成您的首选格式.

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

如果你有一个更私人的回购,并且不害怕重写历史,请看看: git将整个文件视为一行由于mac行结尾 这将重写整个仓库并在所有树,分支的任何地方摆脱任何行结束问题,永远!请务必包含您可能要标准化的所有潜在麻烦的文本文件扩展名,否则它们可能会在以后显示.

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

  • 感谢您的精心解答. (2认同)