Answers:
问了这个问题将近四年之后,我终于找到了一个完全令我满意的答案!
请参阅github:help的行尾处理指南中 的详细信息。
Git的允许您设置为结束直接使用回购性质的行文本属性中
.gitattributes
的文件。该文件将提交到存储库中并覆盖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
,如果您同意,该应用程序还将对存储库中的所有文件进行规范化。
最后,“ 尽你所能”一文提供了更多背景知识,并解释了Git在当前问题上的发展。我认为这是必读的。
您的团队中可能已经有使用EGit或JGit的用户(Eclipse和TeamCity之类的工具使用它们)来提交更改。然后,您就走运了,就像@gatinueta在此答案的评论中解释的那样:
如果您的团队中有使用Egit或JGit的人员,此设置将无法完全满足您的需要,因为这些工具只会忽略.gitattributes并愉快地检入CRLF文件https://bugs.eclipse.org/bugs/show_bug.cgi? id = 342372
一个提示可能是让他们在另一个客户端中提交更改,如SourceTree。那时,我们的团队在许多用例中都喜欢使用Eclipse的EGit工具。
谁说软件很简单?:-/
.gitattributes
GitHub for Windows对您的项目有何建议?我安装了适用于Windows的GitHub,启动了GUI版本,但找不到与.gitattributes
建议相关的任何选项。
core.autocrlf = false
-我更喜欢在任何地方使用LF,但是某些Windows工具(如Visual Studio)坚持在某些文件中使用CRLF结尾(甚至将它们混合在几个文件中。);不更改行尾是最安全的选择。如果您知道自己在做什么,我可能core.autocrlf = input
会对Windows上对行尾敏感的项目使用例外。正如其他人指出的那样,每个体面的文本编辑器现在都支持LF结尾。我实际上认为core.autocrlf = true
可能会造成更多的麻烦,而不是无法避免。
不要转换行尾。解释数据不是VCS的工作-只是存储和版本化数据。每个现代的文本编辑器都可以读取两种行尾。
autocrlf=input
除非您真的知道自己在做什么,否则您几乎总是想要。
以下是一些其他上下文:
core.autocrlf=true
如果您喜欢DOS结束,或者core.autocrlf=input
您喜欢unix-newlines ,则应该是。在这两种情况下,您的Git存储库将只有LF,这是正确的事情。唯一的论据core.autocrlf=false
是自动启发式可能会错误地将某些二进制文件检测为文本,然后您的图块将被破坏。因此,core.safecrlf
引入了一个选项来警告用户是否发生了不可逆的更改。实际上,存在两种不可逆更改的可能性-文本文件中混合的行尾,在这种规范化中是可取的,因此可以忽略此警告,或者(极不可能)Git错误地将二进制文件检测为文本。然后,您需要使用属性来告诉Git该文件是二进制文件。
上一段最初是从gmane.org上的一个线程中拉出来的,但是此后就消失了。
core.autocrlf=input
是规范的答案。对于大多数使用情况,core.autocrlf=true
以及core.autocrlf=false
过于热心(...相反,但同样可怕的方式,当然,),因此内在的破坏性。“ Git for Windows” 确实应该附带“按原样签出,提交Unix样式的行尾”(即core.autocrlf=input
)作为默认的换行策略。没有。因此,在这里- 在2015年Frickin上 -我们仍在无休止地辩论这一点。
为了使混合环境(Microsoft + Linux + Mac)中的行尾保持一致,有两种替代策略:
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
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对它们应该足够聪明。
dos2unix
是一个命令行工具,具体取决于系统,您可能需要另外安装
dos2unix
-存在损坏.git/index
的风险,我们不需要将其应用于每个文件。最好使用类似的东西,find ./ -name "*.html"
并指定要应用到的文件。
find
行之前,请注意:dos2unix
Git for Windows附带的行为具有特殊的(IMO愚蠢和危险的)行为,没有任何参数:而不是更改为UNIX,而是切换了换行格式(DOS <-> UNIX )
尝试将core.autocrlf
配置选项设置为true
。也可以看看该core.safecrlf
选项。
实际上,这听起来core.safecrlf
可能已经在您的存储库中设置了,因为(强调我的):
如果当前的core.autocrlf设置不是这种情况,则git将拒绝该文件。
如果是这种情况,那么您可能要检查文本编辑器是否配置为一致地使用行尾。如果文本文件包含LF和CRLF行尾的混合,您可能会遇到问题。
最后,我认为建议简单地“使用给出的内容”并在Windows上使用LF终止的行将引起更多的问题,而不是解决的问题。Git具有以上选项,试图以一种明智的方式处理行尾,因此使用它们很有意义。
core.autocrlf=false
当我在Visual Studio 2010项目中检出它们时,using 停止了所有文件的标记为更新的操作。开发团队的其他两个成员也在使用Windows系统,因此没有使用混合环境,但是存储库随附的默认设置始终将所有文件标记为在克隆后立即更新。
我想最重要的是找到适合您的环境的CRLF设置。尤其是因为在我们Linux盒子上的许多其他存储库中,设置autocrlf = true
会产生更好的结果。
20多年后的今天,我们仍在处理OS之间的行尾差异……令人遗憾。
这是Windows和Visual Studio用户与Mac或Linux用户共享代码的两个选项。有关详细说明,请阅读gitattributes手册。
在回购.gitattributes
文件中添加:
* text=auto
这将规范化仓库中所有以LF
行结尾的文件。
并且,根据您的操作系统(core.eol
设置),工作树中的文件将被标准化LF
为基于Unix的系统或CRLF
Windows系统。
这是Microsoft .NET存储库使用的配置。
例:
Hello\r\nWorld
将在回购中始终归一化为:
Hello\nWorld
签出时,Windows中的工作树将转换为:
Hello\r\nWorld
结帐时,Mac中的工作树将保留为:
Hello\nWorld
注意:如果您的存储库中已经包含未规范化的
git status
文件,则下次您对它们进行任何更改时,这些文件将显示为已完全修改,并且其他用户以后合并它们的更改可能会很痛苦。有关更多信息,请参见更改行尾后刷新存储库。
如果text
在.gitattributes
文件中未指定if ,则Git使用core.autocrlf
配置变量来确定是否应转换文件。
对于Windows用户,git config --global core.autocrlf true
是一个不错的选择,因为:
LF
行尾。如果存储库中有未规范化的文件,则此设置将不会影响它们。CRLF
工作目录中的行尾。这种方法的问题是:
autocrlf = input
,则将看到一堆带有LF
行尾的文件。对于团队其他成员而言,这没有危险,因为您的提交仍将使用LF
行尾进行标准化。core.autocrlf = false
,则将看到一堆带有LF
行尾的文件,并且可以将带有CRLF
行尾的文件引入仓库。autocrlf = input
带有CRLF
文件结尾的文件core.autocrlf = false
。git config --global core.autocrl true
。你是说git config --global core.autocrlf true
。
考虑到Windows用户喜欢使用文本文件,CRLF
而linux / mac用户喜欢LF
使用文本文件的情况。从存储库维护者的角度提供答案:
对我来说,最好的策略(少的问题解决)是:保留所有文本文件与LF
内部的git回购,即使你是一个只有Windows的项目。然后,让客户可以自由选择其首选项的行尾样式,前提是他们选择一个core.autocrlf
属性值,该属性值在暂存提交文件时会尊重您的策略(回购交易中的LF)。
分阶段是很多人在试图了解换行策略如何工作时会感到困惑的地方。在为core.autocrlf
属性选择正确的值之前,必须理解以下几点:
.git/
的子目录与转换行结束(取决于core.autocrlf
值在客户端的配置)。所有这些都是在本地完成的。 core.autocrlf
就像提供问题的答案(在所有操作系统上都是相同的问题):
false:
“ 以上都不做 ”,input:
“ 不仅有B ”true
:“ 做a和b ”幸好
core.autocrlf: true
,linux / mac:)
core.autocrlf: false
将与LF-only-repo策略兼容。不幸:
core.autocrlf
值core.autocrlf=false
CRLF并添加带有CRLF的文件进行提交。要检测上述客户端提交的ASAP非lf文本文件,您可以按照---更新2 ---:(git grep -I --files-with-matches --perl-regexp '\r' HEAD
,在使用:--with-libpcre
标志编译的客户端上)进行描述。
这是要抓住的地方:。我作为回购维护者保留一个,git.autocrlf=input
这样我可以通过再次添加进行提交的方式来修复任何错误提交的文件。我提供一个提交文本:“修复错误提交的文件”。
据.gitattributes
所知。我不指望它,因为还有更多不了解它的ui客户端。我仅使用它为文本和二进制文件提供提示,并可能标记一些异常的文件,这些文件应在各处保持相同的行尾:
*.java text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg -text # Don't do auto-detection. Treat as binary
*.sh text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat text eol=crlf # Treat as text. Checkout and add with eol=crlf
回答:为避免一次字母更改提交,请显示为5000行更改,仅因为执行更改的客户端在将完整文件添加为提交之前将完整文件从crlf自动转换为lf(或相反)。当涉及解决冲突时,这可能会非常痛苦。或在某些情况下可能是造成不合理冲突的原因。
git client的dafaults在大多数情况下都可以使用。即使您只有Windows仅客户机,Linux仅客户机或两者都有。这些是:
core.autocrlf=true
表示在结帐时将行转换为CRLF,并在添加文件时将行转换为LF。core.autocrlf=input
意味着在结帐时不转换行(不需要,因为期望文件使用LF提交),并且在添加文件时将行转换为LF(如果需要)。(-update3-:看来这是false
默认设置,但也可以)可以在不同的范围内设置该属性。我建议显式设置--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 documentation 相比,我强烈建议不要在Windows上 使用git config --global core.autocrlf false
(如果您只有Windows客户端)。设置为false将在仓库中提交带有CRLF的文件。但是,实际上没有任何理由。您永远不会知道是否需要与linux用户共享项目。另外,对于每个加入该项目的客户,这是一个额外的步骤,而不是使用默认值。
现在,对于某些特殊情况的文件(例如*.bat
*.sh
),您希望使用LF或CRLF签出文件,可以使用.gitattributes
总结一下,最佳实践是:
git grep -I --files-with-matches --perl-regexp '\r' HEAD
(注:在Windows客户端只有通过工作git-bash
和Linux客户端仅在使用编译--with-libpcre
中./configure
)。core.autocrlf=input
(-更新3-).gitattributes
core.autocrlf
将上述内容设置为其默认值。.gitattributes
。IDE的git-clients可能会忽略它们或将它们区别对待。如前所述,可以在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
我花了几个小时来想尽最大可能地使用.gitattributes
,最终意识到我不能指望它。
不幸的是,只要存在基于JGit的编辑器(无法.gitattributes
正确处理),安全的解决方案就是即使在编辑器级别也将LF强制到处。
使用以下anti-CRLF
消毒剂。
Windows / Linux客户端: core.autocrlf=input
承诺.gitattributes
: * text=auto eol=lf
提交.editorconfig
(http://editorconfig.org/),这是一种标准化格式,与编辑器插件结合在一起:
.gitattributes
生产线,它在Git <2.10中有意想不到的后果,请参见stackoverflow.com/a/29508751/2261442
git config --global core.autocrlf false
,并建议.gitattributes
仅在指令中处理eol 的答案。
这只是一个解决方法:
在正常情况下,请使用git随附的解决方案。在大多数情况下,这些效果很好。如果通过设置.gitattributes共享基于Windows和Unix的系统上的开发,请强制使用LF 。
以我为例,有十多个程序员在Windows中开发项目。该项目已通过CRLF签入,没有选择强制使用LF。
有些设置是在我的机器上内部写入的,而不会影响LF格式;因此,每次小文件更改时,某些文件就会全局更改为LF。
我的解决方案:
Windows机器: 让一切保持原样。不用担心,因为您是默认的Windows'lone wolf'开发人员,因此您必须像这样处理:“广阔的世界上没有其他系统了,对吗?”
Unix机器
将以下行添加到配置[alias]
部分。此命令列出所有已更改(即已修改/新)的文件:
lc = "!f() { git status --porcelain \
| egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
| cut -c 4- ; }; f "
将所有这些更改的文件转换为dos格式:
unix2dos $(git lc)
选择性地...
为此操作创建一个git 挂钩,以自动执行此过程
使用参数并将其包含在内并修改grep
函数以仅匹配特定的文件名,例如:
... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
随意使用其他快捷方式使其更加方便:
c2dos = "!f() { unix2dos $(git lc) ; }; f "
...并输入以下内容触发转换后的内容
git c2dos
.gitattributes
?