我尝试使用CRLF结束行提交文件,但失败了.
我花了整整一天的时间在我的Windows计算机上尝试不同的策略,几乎被迫停止尝试使用Git而是尝试使用Mercurial.
每个答案只能分享一个最佳实践.
在提出这个问题差不多四年后,我终于找到了一个完全满足我的答案!
请参阅github中的详细信息:帮助处理行结尾的帮助指南 .
Git的允许您设置为结束直接使用回购性质的行文本属性中
.gitattributes
的文件.此文件将提交到repo中并覆盖该core.autocrlf
设置,从而允许您确保所有用户的行为一致,而不管其git设置如何.
因此
这样做的好处是,您的行尾配置现在随您的存储库一起移动,您无需担心协作者是否具有正确的全局设置.
这是一个.gitattributes
文件的例子
# Auto detect text files and perform LF normalization
* text=auto
*.cs text diff=csharp
*.java text diff=java
*.html text diff=html
*.css text
*.js text
*.sql text
*.csproj text merge=union
*.sln text merge=union eol=crlf
*.docx diff=astextplain
*.DOCX diff=astextplain
# absolute paths are ok, as are globs
/**/postinst* text eol=lf
# paths that don't start with / are treated relative to the .gitattributes folder
relative/path/*.txt text eol=lf
对于最流行的编程语言,有一个方便的即用型.gitattributes文件集合.让你入门是有用的.
一旦你创建或调整了你的.gitattributes
,你应该执行一次又一次的所有行结束重新规范化.
请注意,在应用程序中打开项目的Git仓库后,GitHub Desktop应用程序可以建议并创建一个.gitattributes
文件.要尝试此操作,请单击齿轮图标(位于右上角)>存储库设置...>行结尾和属性.系统会要求您添加建议.gitattributes
,如果您同意,该应用程序还将对存储库中的所有文件执行标准化操作.
最后,Mind the Your Line的文章提供了更多背景知识,并解释了Git如何在手头的事情上发展.我认为这需要阅读.
您的团队中可能有用户使用EGit或JGit(Eclipse和TeamCity等工具使用它们)来提交更改.然后你运气不好,正如@gatinueta在这个答案的评论中解释的那样:
如果您的团队中有人使用Egit或JGit,这个设置将无法完全满足您,因为这些工具只会忽略.gitattributes并愉快地检查CRLF文件https://bugs.eclipse.org/bugs/show_bug.cgi? ID = 342372
一个技巧可能是让他们在另一个客户端提交他们的更改,比如SourceTree.然后我们的团队更喜欢Eclipse的EGit工具,用于许多用例.
谁说软件很简单?: - /
不要转换行结尾.解释数据并不是VCS的工作 - 只需存储和版本化即可.无论如何,每个现代文本编辑器都可以读取两种行结尾.
autocrlf=input
除非你真的知道自己在做什么,否则你几乎总是想要.
下面的一些附加背景:
它应该是
core.autocrlf=true
你喜欢DOS结束还是core.autocrlf=input
喜欢unix-newlines.在这两种情况下,您的Git存储库将只有LF,这是正确的东西.唯一的理由core.autocrlf=false
是自动启发式可能会错误地将某些二进制文件检测为文本,然后您的磁贴将被损坏.因此,core.safecrlf
引入了一个选项来警告用户是否发生了不可逆转的变化.事实上,有两种不可逆转的可能性 - 文本文件中的混合行尾,在这种规范化中是可取的,因此可以忽略此警告,或者(非常不可能)Git错误地将二进制文件检测为文本.然后你需要使用属性来告诉Git这个文件是二进制文件.
上面的段落最初是从gmane.org上的一个帖子中提取出来的,但它已经失败了.
在混合环境中(Microsoft + Linux + Mac)获得关于行尾的一致性的两种替代策略:
1)将所有转换为一种格式
find . -type f -not -path "./.git/*" -exec dos2unix {} \; git commit -a -m 'dos2unix conversion'
2)设置core.autocrlf
到input
在Linux/UNIX或true
在MS Windows(库或全球)
git config --global core.autocrlf input
3)[可选]设置core.safecrlf
为true
(停止)或warn
(唱歌:)添加额外的保护比较,如果反向换行转换将导致相同的文件
git config --global core.safecrlf true
1)将所有转换为一种格式
find . -type f -not -path "./.git/*" -exec dos2unix {} \; git commit -a -m 'dos2unix conversion'
2)将.gitattributes
文件添加到您的存储库
echo "* text=auto" > .gitattributes git add .gitattributes git commit -m 'adding .gitattributes for unified line-ending'
不要担心你的二进制文件--Git应该足够聪明.
有关safecrlf/autocrlf变量的更多信息
尝试将core.autocrlf
配置选项设置为true
.还看看core.safecrlf
选项.
实际上它听起来core.safecrlf
可能已经在您的存储库中设置,因为(强调我的):
如果对于core.autocrlf的当前设置不是这种情况,git将拒绝该文件.
如果是这种情况,那么您可能需要检查文本编辑器是否配置为一致地使用行结尾.如果文本文件包含LF和CRLF行结尾的混合,则可能会遇到问题.
最后,我觉得简单地"使用你给你的东西"并在Windows上使用LF终止线的建议将导致比它解决的更多问题.Git有以上选项来尝试以合理的方式处理行结尾,因此使用它们是有意义的.
core.autocrlf=false
在我的Visual Studio 2010项目中检出后,使用停止的所有文件被标记为已更新.开发团队的另外两个成员也使用Windows系统,因此混合环境没有发挥作用,但存储库附带的默认设置始终将所有文件标记为克隆后立即更新.
我想底线是找到适合您环境的CRLF设置.特别是因为在我们Linux机箱上的许多其他存储库中,设置autocrlf = true
会产生更好的结果.
20多年后,我们仍在处理操作系统之间的线路结束差异......很难过.
这些是与Mac或Linux用户共享代码的Windows和Visual Studio用户的两个选项.有关扩展说明,请阅读gitattributes手册.
*text = auto在您的repo .gitattributes
文件中添加:
* text=auto
这将规范化LF
repo中具有行结尾的所有文件.
根据您的操作系统(core.eol
设置),工作树中的文件将LF
针对基于Unix的系统或CRLF
Windows系统进行标准化.
这是Microsoft .NET repos使用的配置.
例:
Hello\r\nWorld
将在回购中标准化为:
Hello\nWorld
在结帐时,Windows中的工作树将转换为:
Hello\r\nWorld
结帐时,Mac中的工作树将保留为:
Hello\nWorld
core.autocrlf = true注意:如果您的repo已包含未规范化的
git status
文件,则下次对其进行任何更改时,将显示这些文件已完全修改,以及其他用户稍后合并其更改可能会很麻烦.有关更多信息,请参阅更改行结尾后刷新存储库.
如果文件中text
未指定.gitattributes
,Git使用core.autocrlf
配置变量来确定是否应转换文件.
对于Windows用户,git config --global core.autocrlf true
是一个很好的选择,因为:
仅当添加到仓库时,文件才会标准化为LF
行尾.如果存储库中没有标准化的文件,则此设置不会触及它们.
所有文本文件都将转换为CRLF
工作目录中的行结尾.
这种方法的问题是:
如果您是Windows用户autocrlf = input
,您将看到一堆带有LF
行结尾的文件.对团队的其他成员而言并不存在危险,因为您的提交仍将使用LF
行结尾进行标准化.
如果您是Windows用户core.autocrlf = false
,您将看到一堆带有LF
行结尾的文件,您可以将带有CRLF
行结尾的文件引入到repo中.
大多数Mac用户使用autocrlf = input
并可能获得带有CRLF
文件结尾的文件,可能来自Windows用户core.autocrlf = false
.
我花了几个小时来想尽最大可能地使用.gitattributes
,最终意识到我不能指望它。
不幸的是,只要存在基于JGit的编辑器(无法.gitattributes
正确处理),安全的解决方案就是即使在编辑器级别也将LF强制到处。
使用以下anti-CRLF
消毒剂。
Windows / Linux客户端: core.autocrlf=input
承诺.gitattributes
: * text=auto eol=lf
提交.editorconfig
(http://editorconfig.org/),这是一种标准化格式,与编辑器插件结合在一起:
https://github.com/editorconfig/
https://github.com/welovecoding/editorconfig-netbeans/
git client的dafaults在大多数情况下都可以使用。即使您只有Windows仅客户机,Linux仅客户机或两者都有。这些是:
Windows: core.autocrlf=true
表示在结帐时将行转换为CRLF,并在添加文件时将行转换为LF。
linux: core.autocrlf=input
表示在结帐时不转换行(不需要,因为期望文件使用LF提交),并且在添加文件时将行转换为LF(如果需要)。
可以在不同的范围内设置该属性。我建议显式设置--global
范围,以避免最后描述一些IDE问题。
git config core.autocrlf git config --global core.autocrlf git config --system core.autocrlf git config --local core.autocrlf git config --show-origin core.autocrlf
另外,与git document相比,我强烈建议不要使用git config --global core.autocrlf false
(如果您只有Windows客户端)。设置为false将在仓库中提交带有CRLF的文件。但是,实际上没有任何理由。您永远不会知道是否需要与linux用户共享项目。另外,对于每个加入该项目的客户,这是一个额外的步骤,而不是使用默认值。
现在,对于某些*.bat
*.sh
需要使用LF或CRLF签出文件的特殊情况(例如),您可以使用.gitattributes
总结一下,最佳实践是:
确保在git repo上使用LF提交每个非二进制文件(默认行为)。
使用此命令以确保没有文件承诺与CRLF: git grep -I --files-with-matches --perl-regexp '\r' HEAD
(注:在Windows客户端只有通过工作git-bash
和Linux客户端仅在使用编译--with-libpcre
中./configure
)。
如果通过执行上述命令找到任何此类文件,请更正它们。这涉及(至少在Linux中):
更改文件
还原更改(文件仍显示为更改)
提交
仅使用最低限度 .gitattributes
指示用户core.autocrlf
将上述内容设置为其默认值。
请勿将100%计为存在.gitattributes
。IDE的git-client可能会忽略它们或将它们区别对待。
如前所述,可以在git属性中添加一些内容:
# Always checkout with LF *.sh text eol=lf # Always checkout with CRLF *.bat text eol=crlf
我认为可以使用其他一些安全选项,.gitattributes
而不是对二进制文件使用自动检测:
-text
(例如,对于*.zip
或*.jpg
文件:将不被视为文本。因此,将不尝试行尾转换。通过转换程序可能会产生差异)
text !eol
(例如,对于*.java
,*.html
::被视为文本,但未设置eol样式首选项。因此使用客户端设置。)
-text -diff -merge
(例如*.hugefile
::不被视为文本。不能进行差异/合并)
客户端错误提交文件的一个痛苦示例:
netbeans 8.2(在Windows上)将错误地提交所有带有CRLF的文本文件,除非您已明确将其设置core.autocrlf
为global。这与标准的git客户端行为相矛盾,并在以后更新/合并时引起很多问题。这就是使某些 文件即使在还原时也显得不同(尽管它们没有区别)的原因。
即使您.gitattributes
向项目中添加了正确的代码,在netbeans中也会发生相同的行为。
提交后使用以下命令,至少可以帮助您及早发现git repo是否存在行尾问题: git grep -I --files-with-matches --perl-regexp '\r' HEAD