我在Stack Overflow上阅读了很多不同的问题和答案,以及关于 core.autocrlf 设置如何工作的 git 文档。
这是我对以下内容的理解:
Unix和Mac OSX(OSX之前使用CR)客户端使用LF行结尾 Windows客户端使用CRLF行结尾。
当客户端上的core.autocrlf设置为true时,git存储库始终以LF行结束格式存储文件,客户端上文件中的行结尾在客户端(即Windows)的check out / commit上来回转换使用非LF行结尾,无论行结尾文件在客户端上的格式是什么(这与Tim Clem的定义不一致 - 请参阅下面的更新)。
这是一个矩阵,它试图为带有问号的core.autocrlf的'input'和'false'设置记录相同的内容,其中我不确定行结束转换行为。
我的问题是:
我会从答案中更新问号,因为似乎已形成共识。
core.autocrlf value true input false ---------------------------------------------------------- commit | convert ? ? new | to LF (convert to LF?) (no conversion?) commit | convert to ? no existing | LF (convert to LF?) conversion checkout | convert to ? no existing | CRLF (no conversion?) conversion
我并不是真的在寻找各种设置的利弊意见。我只是在寻找数据,这清楚地说明了如何期望git能够在三种设置中运行。
-
2012年4月17日更新:在评论中阅读了JJD关联的the article by Tim Clem后,我修改了上表中“未知”值中的一些值,如以及更改“checkout existing | true转换为CRLF而不是转换为客户端”。以下是他给出的定义,这些定义比我在其他地方看到的更清楚:
core.autocrlf = false
这是默认设置,但我们鼓励大多数人更改此设置 立即。使用false的结果是Git不会混乱 在您的文件上有行结尾。您可以使用LF或CRLF签入文件 或CR或那些随机混合的那三个和Git并不关心。这个 可以使差异难以阅读和合并更困难。大多数人 在Unix / Linux世界中工作使用此值是因为它们没有 CRLF问题,他们不需要Git随时做额外的工作 文件被写入对象数据库或写入 工作目录。
core.autocrlf = true
这意味着Git将处理所有文本文件并确保这一点 将该文件写入对象数据库时,CRLF将替换为LF 在写入工作时将所有LF转回CRLF 目录。这是Windows上的推荐设置,因为它 确保您的存储库可以在其他平台上使用 将CRLF保留在工作目录中。
core.autocrlf =输入
Tim的文章很棒,我唯一能想到的就是缺少的是他认为存储库是LF格式的,这不一定是真的,特别是对于仅限Windows的项目。这意味着Git将处理所有文本文件并确保这一点 将该文件写入对象时,CRLF将替换为LF 数据库。但是,它不会反过来。当你阅读文件 退出对象数据库并将其写入工作状态 目录中他们仍然会有LF来表示行尾。这个 设置通常用于Unix / Linux / OS X以防止CRLF 写入存储库。想法是,如果你粘贴 来自网络浏览器的代码,并意外地将CRLF纳入您的一个 文件,Git会确保你写的时候用LF替换它们 到对象数据库。
将Tim的文章与jmlane迄今为止最高投票答案进行比较,表明他们对真实和输入设置以及对错误设置的不同意见达成了完美的一致。
答案 0 :(得分:116)
有关core.autocrlf
工作原理的最佳说明,请参见gitattributes手册页,text
属性部分。
这就是core.autocrlf
目前的工作方式(至少从我所知道的v1.7.2开始):
core.autocrlf = true
LF
个字符的文本文件在工作树中被标准化为CRLF
;不会触及存储库中包含CRLF
的文件LF
个字符的文本文件在提交回存储库时会从CRLF
标准化为LF
。存储库中包含CRLF
的文件将不受影响。core.autocrlf = input
CRLF
字符的文本文件在提交回存储库时会标准化为LF
。core.autocrlf = false
core.eol
指示工作树的文本文件中的EOL字符。core.eol = native
,这意味着Windows EOL为CRLF
,* nix EOL在工作树中为LF
。gitattributes
设置确定提交到存储库的EOL字符规范化(默认为规范化为LF
个字符。)我刚才刚刚研究过这个问题,我也发现情况非常复杂。 core.eol
设置肯定有助于阐明git如何处理EOL字符。
答案 1 :(得分:55)
混合平台项目中的EOL问题长期以来一直让我的生活变得悲惨。当回购中已存在具有不同且混合的EOL 已的文件时,通常会出现问题。这意味着:
CRLF
和LF
在同一文件中的组合。这种情况如何发生不是问题,但它确实发生了。
我在Windows上针对各种模式及其组合运行了一些转换测试 这是我得到的,在一个稍微修改过的表中:
| Resulting conversion when | Resulting conversion when | committing files with various | checking out FROM repo - | EOLs INTO repo and | with mixed files in it and | core.autocrlf value: | core.autocrlf value: -------------------------------------------------------------------------------- File | true | input | false | true | input | false -------------------------------------------------------------------------------- Windows-CRLF | CRLF -> LF | CRLF -> LF | as-is | as-is | as-is | as-is Unix -LF | as-is | as-is | as-is | LF -> CRLF | as-is | as-is Mac -CR | as-is | as-is | as-is | as-is | as-is | as-is Mixed-CRLF+LF | as-is | as-is | as-is | as-is | as-is | as-is Mixed-CRLF+LF+CR | as-is | as-is | as-is | as-is | as-is | as-is
如您所见,有两种情况在提交时发生转换(左侧列为3列)。在其余情况下,文件按原样提交。
结帐时(右列3列),只有1例在以下情况下发生转换:
core.autocrlf
是true
和 LF
EOL。对我来说最令人惊讶的是,我怀疑,许多EOL问题的原因是没有配置使CRLF
+ LF
之类的混合EOL得到规范化。
另请注意CR
的“旧”Mac EOL也永远不会被转换
这意味着,如果写得不好的EOL转换脚本尝试使用CRLF
s + LF
s转换混合结束文件,只需将LF
转换为CRLF
s,那么将CR
转换为CRLF
的任何地方都会将文件保留为“孤独”CRCRLF
的混合模式。
然后,即使在true
模式下,Git也不会转换任何内容,并且EOL将继续进行破坏。这实际上发生在我身上并且使我的文件搞得很糟糕,因为一些编辑和编译器(例如VS2010)不喜欢Mac EOL。
我想真正解决这些问题的唯一方法是偶尔通过检查input
或false
模式下的所有文件来规范化整个仓库,运行正确的规范化并重新提交已更改的文件(如果有)。在Windows上,可能会继续使用core.autocrlf true
。
答案 2 :(得分:37)
新的配置设置core.eol
is being added/evolved:
这是{Add}
core.eol
“配置变量”提交的替代品,该提交目前位于pu
(我系列中的最后一个)。
而不是暗示“core.autocrlf=true
”替代“* text=auto
”,它明确表明autocrlf
仅适用于想要与之合作的用户 CRLF位于没有文本的存储库的工作目录中 文件规范化。
启用后,将忽略“core.eol”。引入一个新的配置变量“
core.eol
”,允许用户设置哪些行结尾用于工作目录中的行末端规范化文件。
它默认为“native
”,这意味着Windows上的CRLF和其他地方的LF。 请注意,“core.autocrlf
”会覆盖core.eol
这意味着:即使[core] autocrlf = true
core.eol
设置为“lf
”,也会将CRLF放入工作目录。
core.eol:
设置要在工作目录中使用设置了
text
属性的文件的行结束类型 替代品是'lf','crlf'和'native',它们使用平台的原生行结尾 默认值为native
。
其他进化are being considered:
对于1.8,我会考虑让
core.autocrlf
打开规范化并将工作目录行结束决定留给core.eol,但将打破人们的设置。
git 2。8(2016年3月)改进了core.autocrlf
影响eol的方式:
请参阅commit 817a0c7(2016年2月23日),commit 6e336a5,commit df747b8,commit df747b8(2016年2月10日),commit df747b8,commit df747b8( 2016年2月10日),commit 4b4024f,commit bb211b4,commit 92cce13,commit 320d39c,commit 4b4024f,commit bb211b4,commit 92cce13,{{ 3}}(2016年2月5日)commit 320d39c
(由Torsten Bögershausen (tboegi
)合并于Junio C Hamano -- gitster
--,2016年2月26日)
convert.c
:重构crlf_action
重构
crlf_action
的确定和用法 今天,如果文件中未设置“crlf
”属性,则crlf_action
设置为CRLF_GUESS
。请改用CRLF_UNDEFINED
,并像以前一样搜索“text
”或“eol
”。替换旧的
CRLF_GUESS
用法:
CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF
CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY
CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT
通过定义:
,更清楚,更清楚,是什么
- CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf
and core.eol is evaluated and one of CRLF_BINARY,
CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected
- CRLF_BINARY : No processing of line endings.
- CRLF_TEXT : attribute "text" is set, line endings are processed.
- CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text.
- CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text.
- CRLF_AUTO : attribute "auto" is set.
- CRLF_AUTO_INPUT: core.autocrlf=input (no attributes)
- CRLF_AUTO_CRLF : core.autocrlf=true (no attributes)
由于commit c6b94eb添加torek:
所有这些翻译(来自
eol=
或autocrlf
设置的任何EOL转换,以及“clean
”过滤器)在文件从工作树移动到索引时运行,即在git add
期间,而不是git commit
时间 (请注意,git commit -a
或--only
或--include
确实会在当时向索引添加文件。)
有关详情,请参阅“in the comments”。
答案 3 :(得分:27)
core.autocrlf
值不依赖于操作系统类型,但在Windows上,默认值为true
,对于Linux - input
。我为提交和签出案例探索了3个可能的值,这是结果表:
╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║ false ║ input ║ true ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ ║ LF => LF ║ LF => LF ║ LF => LF ║
║ git commit ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => LF ║ CRLF => LF ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ ║ LF => LF ║ LF => LF ║ LF => CRLF ║
║ git checkout ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝
答案 4 :(得分:6)
到目前为止,这是我对它的理解,以防有人帮助。
core.autocrlf=true
和core.safecrlf = true
您有一个存储库,其中所有行结尾都相同,但您在不同的平台上工作。 Git将确保您的行结尾转换为您的平台的默认值。为什么这很重要?假设您创建了一个新文件。平台上的文本编辑器将使用其默认行结尾。当您检入它时,如果您没有将core.autocrlf设置为true,那么您为平台上的某个人默认为不同的行结尾引入了行结尾不一致。我总是设置safecrlf,因为我想知道crlf操作是可逆的。使用这两个设置, git正在修改您的文件,但它会验证修改是否可逆。
core.autocrlf=false
您的存储库已经签入了混合行结尾,并且修复错误的行结尾可能会破坏其他内容。在这种情况下,最好不要告诉git转换行结尾,因为这样会加剧它设计解决的问题 - 使diff更容易阅读和合并更少的痛苦。使用此设置, git不会修改您的文件。
core.autocrlf=input
我不使用它,因为这样做的原因是为了覆盖一个用例,你在默认为LF行结尾的平台上创建了一个CRLF行结尾的文件。我更喜欢让我的文本编辑器始终保存平台的行结束默认值的新文件。
答案 5 :(得分:2)
在linux和windows上都进行了一些测试。我使用的测试文件包含以LF结尾的行以及以CRLF结尾的行 文件已提交,删除,然后签出。 core.autocrlf的值在commit之前设置,也在checkout之前设置。 结果如下。
commit core.autocrlf false, remove, checkout core.autocrlf false: LF=>LF CRLF=>CRLF
commit core.autocrlf false, remove, checkout core.autocrlf input: LF=>LF CRLF=>CRLF
commit core.autocrlf false, remove, checkout core.autocrlf true : LF=>LF CRLF=>CRLF
commit core.autocrlf input, remove, checkout core.autocrlf false: LF=>LF CRLF=>LF
commit core.autocrlf input, remove, checkout core.autocrlf input: LF=>LF CRLF=>LF
commit core.autocrlf input, remove, checkout core.autocrlf true : LF=>CRLF CRLF=>CRLF
commit core.autocrlf true, remove, checkout core.autocrlf false: LF=>LF CRLF=>LF
commit core.autocrlf true, remove, checkout core.autocrlf input: LF=>LF CRLF=>LF
commit core.autocrlf true, remove, checkout core.autocrlf true : LF=>CRLF CRLF=>CRLF
答案 6 :(得分:1)
不,@ jmlane的答案是错误的。
Checkin (git add, git commit)
:text
属性为Set, Set value to 'auto'
,则转换发生在文件已使用'CRLF'提交text
属性为Unset
:没有任何反应,请Checkout
text
属性为Unspecified
,则转化取决于core.autocrlf
autocrlf = input or autocrlf = true
,转换只发生在存储库中的文件是'LF'时,如果它是'CRLF',则不会发生任何事情。autocrlf = false
,没有任何反应Checkout
:text
属性为Unset
:没有任何反应。text
属性为Set, Set value to 'auto
:则取决于core.autocrlf
,core.eol
。
core.eol
text
属性为Unspecified
,则取决于core.autocrlf
。
2.1
2.2
text
属性为Unspecified
因此默认行为是text
属性Unspecified
和core.autocrlf = false
:
text
属性,则签入行为取决于自身,而不是取决于autocrlf 答案 7 :(得分:0)
LMAO!
你们都搞错了。
在提交时导致 CRLF->LF 的语句 core.autocrlf
是 true
是明显错误的!
没那么简单,你看...
(该设置对应于 text=auto
中的 .gitattributes
和 git config 中的 core.eol
设置为 crlf
;究竟是什么意思?哈哈哈。)
这意味着(如果文件没有设置 .gitattributes
文本属性,则 core.autocrlf
为 true
,意味着)它取决于它是否是正在提交的新文件(在这种情况下,是的,它将在 git repo 数据库中标准化为 LF),或者它是否是您编辑和提交的现有文件(在这种情况下不会发生任何事情;除非 --hahaha-- 您在其中运行 git add --renormalize .
在这种情况下,它将在 git repo 数据库中标准化)。
但老实说:谁在乎?
(你看...上面的机制,只发生在一个文件中,.gitattributes
,没有放置了一个文本属性的变体:text
, -text
、text=auto
。)
您真的应该在所有文件中使用带有默认设置的 .gitattributes
,或者
* -text
# followed by specialization
默认所有(特化除外)原样并完全覆盖 core.autocrlf
,
或使用默认值
* text=auto
# followed by specialization
意味着git自动检测为非二进制(文本)的所有文件(除了专业),在git数据库[1**]中有LF,当core.autocrlf
为true
时获得CRLF或者当 core.eol
为 crlf
时,或者当 core.eol
为 native
(默认)并且您使用的是 Windows 平台时。否则你会得到 LF。
我的意思是什么专业?例如,.bat
文件为 CRLF,.sh
文件为 LF,通过以下任一方式:
*.sh text eol=lf
# *.bat
*.[bB][aA][tT] text eol=crlf
或
# *.sh are committed correctly as-is (LF)
*.sh -text
# *.bat are committed correctly as-is (CRLF)
*.[bB][aA][tT] -text
但是是的……事情并没有那么简单。哈哈。
[1**]:对于与 text=auto attribute
匹配的所有文件(即没有其他专业化),情况就是这样,因为我认为当 .gitattribute
为将创建