Dan*_*phe 588 git cross-platform newline eol
我尝试使用CRLF结束行提交文件,但失败了.
我花了整整一天的时间在我的Windows计算机上尝试不同的策略,几乎被迫停止尝试使用Git而是尝试使用Mercurial.
每个答案只能分享一个最佳实践.
Dan*_*phe 732
在提出这个问题差不多四年后,我终于找到了一个完全满足我的答案!
请参阅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
Run Code Online (Sandbox Code Playgroud)
对于最流行的编程语言,有一个方便的即用型.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工具,用于许多用例.
谁说软件很简单?: - /
Joh*_*kin 114
不要转换行结尾.解释数据并不是VCS的工作 - 只需存储和版本化即可.无论如何,每个现代文本编辑器都可以读取两种行结尾.
Cor*_*ory 81
autocrlf=input
除非你真的知道自己在做什么,否则你几乎总是想要.
下面的一些附加背景:
它应该是
core.autocrlf=true
你喜欢DOS结束还是core.autocrlf=input
喜欢unix-newlines.在这两种情况下,您的Git存储库将只有LF,这是正确的东西.唯一的理由core.autocrlf=false
是自动启发式可能会错误地将某些二进制文件检测为文本,然后您的磁贴将被损坏.因此,core.safecrlf
引入了一个选项来警告用户是否发生了不可逆转的变化.事实上,有两种不可逆转的可能性 - 文本文件中的混合行尾,在这种规范化中是可取的,因此可以忽略此警告,或者(非常不可能)Git错误地将二进制文件检测为文本.然后你需要使用属性来告诉Git这个文件是二进制文件.
上面的段落最初是从gmane.org上的一个帖子中提取出来的,但它已经失败了.
luk*_*mdo 57
在混合环境中(Microsoft + Linux + Mac)获得关于行尾的一致性的两种替代策略:
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
Run Code Online (Sandbox Code Playgroud)
2)设置core.autocrlf
到input
在Linux/UNIX或true
在MS Windows(库或全球)
git config --global core.autocrlf input
Run Code Online (Sandbox Code Playgroud)
3)[可选]设置core.safecrlf
为true
(停止)或warn
(唱歌:)添加额外的保护比较,如果反向换行转换将导致相同的文件
git config --global core.safecrlf true
Run Code Online (Sandbox Code Playgroud)
find . -type f -not -path "./.git/*" -exec dos2unix {} \;
git commit -a -m 'dos2unix conversion'
Run Code Online (Sandbox Code Playgroud)
2)将.gitattributes
文件添加到您的存储库
echo "* text=auto" > .gitattributes
git add .gitattributes
git commit -m 'adding .gitattributes for unified line-ending'
Run Code Online (Sandbox Code Playgroud)
不要担心你的二进制文件--Git应该足够聪明.
Gre*_*ill 10
尝试将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手册.
在您的repo .gitattributes
文件中添加:
* text=auto
Run Code Online (Sandbox Code Playgroud)
这将规范化LF
repo中具有行结尾的所有文件.
根据您的操作系统(core.eol
设置),工作树中的文件将LF
针对基于Unix的系统或CRLF
Windows系统进行标准化.
这是Microsoft .NET repos使用的配置.
例:
Hello\r\nWorld
Run Code Online (Sandbox Code Playgroud)
将在回购中标准化为:
Hello\nWorld
Run Code Online (Sandbox Code Playgroud)
在结帐时,Windows中的工作树将转换为:
Hello\r\nWorld
Run Code Online (Sandbox Code Playgroud)
结帐时,Mac中的工作树将保留为:
Hello\nWorld
Run Code Online (Sandbox Code Playgroud)
注意:如果您的repo已包含未规范化的
git status
文件,则下次对其进行任何更改时,将显示这些文件已完全修改,以及其他用户稍后合并其更改可能会很麻烦.有关更多信息,请参阅更改行结尾后刷新存储库.
如果文件中text
未指定.gitattributes
,Git使用core.autocrlf
配置变量来确定是否应转换文件.
对于Windows用户,git config --global core.autocrlf true
是一个很好的选择,因为:
LF
行尾.如果存储库中没有标准化的文件,则此设置不会触及它们.CRLF
工作目录中的行结尾.这种方法的问题是:
autocrlf = input
,您将看到一堆带有LF
行结尾的文件.对团队的其他成员而言并不存在危险,因为您的提交仍将使用LF
行结尾进行标准化.core.autocrlf = false
,您将看到一堆带有LF
行结尾的文件,您可以将带有CRLF
行结尾的文件引入到repo中.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/),这是一种标准化格式,与编辑器插件结合在一起:
git client的dafaults在大多数情况下都可以使用。即使您只有Windows仅客户机,Linux仅客户机或两者都有。这些是:
core.autocrlf=true
表示在结帐时将行转换为CRLF,并在添加文件时将行转换为LF。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
Run Code Online (Sandbox Code Playgroud)
另外,与git document相比,我强烈建议不要使用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
)。.gitattributes
core.autocrlf
将上述内容设置为其默认值。.gitattributes
。IDE的git-client可能会忽略它们或将它们区别对待。如前所述,可以在git属性中添加一些内容:
# Always checkout with LF
*.sh text eol=lf
# Always checkout with CRLF
*.bat text eol=crlf
Run Code Online (Sandbox Code Playgroud)
我认为可以使用其他一些安全选项,.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
这只是一个变通的解决方案:
通常情况下,使用 git 附带的解决方案。这些在大多数情况下都很好用。如果您通过设置.gitattributes在基于 Windows 和 Unix 的系统上共享开发,则强制使用 LF 。
就我而言,有超过 10 名程序员在 Windows 中开发一个项目。这个项目是用 CRLF 签入的,没有强制执行 LF 的选项。
一些设置是在我的机器上内部编写的,对 LF 格式没有任何影响;因此,每次小文件更改时,某些文件都会全局更改为 LF。
我的解决方案:
Windows-Machines: 让一切照原样。什么都不在乎,既然你是一个默认的 windows '孤狼' 开发者,你必须像这样处理:“世界上没有其他系统,是吗?”
Unix-机器
将以下行添加到配置[alias]
部分。此命令列出所有更改的(即修改的/新的)文件:
lc = "!f() { git status --porcelain \
| egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \
| cut -c 4- ; }; f "
Run Code Online (Sandbox Code Playgroud)将所有这些更改的文件转换为 dos 格式:
unix2dos $(git lc)
Run Code Online (Sandbox Code Playgroud)可选...
为此操作创建一个 git hook以自动执行此过程
使用 params 并包含它并修改grep
函数以仅匹配特定的文件名,例如:
... | egrep -r "^(\?| ).*\.(txt|conf)" | ...
Run Code Online (Sandbox Code Playgroud)随意使用额外的快捷方式使其更加方便:
c2dos = "!f() { unix2dos $(git lc) ; }; f "
Run Code Online (Sandbox Code Playgroud)
...并通过键入来触发转换后的内容
git c2dos
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
199805 次 |
最近记录: |