这一行结尾问题让我疯狂......
背景:从历史上看,我使用的是core.autocrlf设置,但我发现我遇到了不同的repos表现不好的问题(我在Windows上工作,我有一些需要LF结尾的repos和一些需要CRLF结尾的repos)。所以我试图摆脱它并在每个存储库中使用.gitattributes(我希望Git只是闭嘴并让我管理行结尾!)。所以我现在有core.autocrlf=false
和.gitattributes
对于我正在处理的Visual Studio项目看起来像这样:
# Don't do any end of line normalization.
* -text
# Always treat these files as binary. Not strictly necessary, but can't hurt.
*.png binary
*.gif binary
*.jpg binary
*.jpeg binary
*.dll binary
*.doc binary
*.docx binary
*.xls binary
*.xlsx binary
*.pdf binary
我已经使用unix2dos将repo中的所有文件强制为CRLF结尾,并确认它们在工作目录中具有正确的行结尾,并将它们全部检入。是的,我按照此处的建议Trying to fix line-endings with git filter-branch, but having no luck < / p>
这几乎是完美的。
问题是每当我更改文件时git报告它在更改的行上有行结尾差异,例如,如果原始行是
string s;
,更改的行是
string sucks;
git diff将更改显示为
string sucks;^M
看起来Git认为repo中的文件仍然有LF结尾(因为它们在过去被标准化了?)。 ^ M会产生大量的视觉噪音,我不确定这是否是其他任何问题的症状。我不明白为什么Git会报告差异,因为我在之前的提交中检查了所有带有CRLF结尾的文件,实际上是在此之前的提交。
那么为什么我会得到这些“假的”差异,我怎么能摆脱它们呢?
答案 0 :(得分:5)
哇噢!我想我找到了答案。本网站http://lostechies.com/keithdahlby/2011/04/06/windows-git-tip-hide-carriage-return-in-diff/建议
git config [--global] core.whitespace cr-at-eol
这确实关闭了&#34; git diff&#34;起来。当然,最好的解决方案是在.gitattributes文件中执行等效操作,以使其与repo一致,并且不依赖于用户的设置。
.gitattributes的明确设置
花了一些时间在Linux和Windows上尝试使用repos,并使用具有Unix和Windows行结尾的文件,我相信如果你只是给你的git repo,那么整个行尾问题就可以消失了。 gitattributes文件有两行:
* -text
* whitespace=cr-at-eol
第一行阻止git执行任何行结束规范化,第二行停止git-diff突出显示行末尾的CR字符。我能找到的唯一不足之处是如果你将一个文件从DOS转换为Unix,反之亦然:git-diff会将文件显示为已更改,但它没有突出显示原因,而只是显示每行删除然后添加。我可以忍受这个,因为它是一种罕见的操作(或应该是)。
以上将行结束管理的负担放在提交者身上。这应该是,我不相信我的VCS工具应该尝试做魔术,成千上万的网页和关于git处理行结尾的问题证明他们在这里作出了错误的决定。
<强>变体形式强>
如果用
替换第一行* eol=lf
然后文件将始终在工作目录中有LF结尾。这对于必须在Unix和Windows上运行的存储库来说非常方便,例如&#34; .dotfiles&#34;。同样eol=crlf
将强制Windows样式行结尾。 警告这也会转换二进制文件中的CRLF!请参阅我在how to config git repo so that all files are stored with line-ending LF ( not CFLF ) ?的评论,因此您还需要使用文件路径或告诉git哪些文件是二进制文件。 https://help.github.com/articles/dealing-with-line-endings/
方便的别名
以下两个git别名提供了一种快速方法,可以将repo中的所有文本文件从DOS转换为Unix,反之亦然。它们专门排除.git文件夹的任何处理。我找不到从命令行定义它们的方法,因此请编辑.gitconfig并在[alias]
部分添加以下两行:
godos = !find . -path ./.git -prune -o -type f -exec unix2dos {} "\\;"
gounix = !find . -path ./.git -prune -o -type f -exec dos2unix {} "\\;"
然后,您可以在回购的根目录中执行git godos
或git gounix
,将所有文本文件结尾设置为其中一个。的 n.b。以上只适用于当前分支中的文件。我还没有找到转换每个分支中每个文件的方法。
<强>参考强>
gitattributes手册页:https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html
gitconfig手册页(讨论cr-at-eol):https://www.kernel.org/pub/software/scm/git/docs/git-config.html
用于查找的Git别名:`find -exec` in git alias