我已经在Stack Overflow上阅读了很多不同的问题和答案,以及git的文档。自专制设置工作。

以下是我读到的内容:

Unix和Mac OSX (pre-OSX使用CR)客户端使用LF行结束符。 Windows客户端使用CRLF行结束符。

当核心。在客户端被设置为true, git存储库总是以LF行结束格式存储文件,客户端文件中的行结束符在签出/提交时来回转换,对于使用非LF行结束符的客户端(即Windows),无论客户端上的行结束符文件是什么格式(这与Tim Clem的定义不一致-参见下面的更新)。

下面是一个矩阵,它试图为core的'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链接的Tim Clem的文章后,我修改了上表中“未知”值中的一些值,以及更改“checkout现有| true转换为CRLF而不是转换为客户端”。以下是他给出的定义,比我在其他地方看到的任何定义都更清楚:

核心。独裁者= false

This is the default, but most people are encouraged to change this immediately. The result of using false is that Git doesn’t ever mess with line endings on your file. You can check in files with LF or CRLF or CR or some random mix of those three and Git does not care. This can make diffs harder to read and merges more difficult. Most people working in a Unix/Linux world use this value because they don’t have CRLF problems and they don’t need Git to be doing extra work whenever files are written to the object database or written out into the working directory.

核心。独裁者= true

这意味着Git将处理所有文本文件,并确保 在将该文件写入对象数据库时,CRLF将被LF替换 并在写入工作时将所有LF转回CRLF 目录中。这是Windows上的推荐设置,因为它 确保您的存储库可以在其他平台上使用 在工作目录中保留CRLF。

核心。selflf =输入

This means that Git will process all text files and make sure that CRLF is replaced with LF when writing that file to the object database. It will not, however, do the reverse. When you read files back out of the object database and write them into the working directory they will still have LFs to denote the end of line. This setting is generally used on Unix/Linux/OS X to prevent CRLFs from getting written into the repository. The idea being that if you pasted code from a web browser and accidentally got CRLFs into one of your files, Git would make sure they were replaced with LFs when you wrote to the object database.

Tim的文章非常棒,我能想到的唯一缺失的是他假设存储库是LF格式的,这并不一定是正确的,特别是对于仅用于Windows的项目。

将Tim的文章与jmlane迄今为止投票最多的答案进行比较,可以发现在正确设置和输入设置上完全一致,而在错误设置上存在分歧。


当前回答

在即将到来的Git 1.7.2中,“eol转换”方面的事情即将发生变化:

一个新的配置设置核心。Eol正在被添加/进化:

This is a replacement for the 'Add "core.eol" config variable' commit that's currently in pu (the last one in my series). Instead of implying that "core.autocrlf=true" is a replacement for "* text=auto", it makes explicit the fact that autocrlf is only for users who want to work with CRLFs in their working directory on a repository that doesn't have text file normalization. When it is enabled, "core.eol" is ignored. Introduce a new configuration variable, "core.eol", that allows the user to set which line endings to use for end-of-line-normalized files in the working directory. It defaults to "native", which means CRLF on Windows and LF everywhere else. Note that "core.autocrlf" overrides core.eol. This means that: [core] autocrlf = true puts CRLFs in the working directory even if core.eol is set to "lf". core.eol: Sets the line ending type to use in the working directory for files that have the text property set. Alternatives are 'lf', 'crlf' and 'native', which uses the platform's native line ending. The default value is native.


正在考虑其他演变:

对于1.8,我会考虑制作核心。只需要打开规范化,并将工作目录行结束决定留给core。Eol,但那会打破人们的设定。


git 2.8(2016年3月)改进了内核的方式。selff影响eol:

参见Torsten Bögershausen (tboegi)的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, commit 320d39c(2016年2月05日)。 (由Junio C Hamano—gitster—在commit c6b94eb中合并,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)

正如torek在评论中补充的那样:

所有这些转换(从EOL =或selflf设置的任何EOL转换,以及“clean”过滤器)都在文件从工作树移动到索引时运行,即在git添加期间而不是在git提交时运行。 (注意git commit -a或——only或——include会在那个时候将文件添加到索引中。)

有关更多信息,请参见“selflf和eol之间的区别是什么”。

其他回答

语句核心。selflf =true导致CRLF -> LF提交是完全错误的!事情并没有那么简单,正如你将看到的……

文档上说这个设置对应于…" text=auto在.gitattributes和核心。在git配置中Eol被设置为CRLF”…这到底意味着什么?

这意味着,如果文件没有.gitattributes文本属性集,如果core. properties文本属性集。自专制是真的,它现在取决于你提交的文件是新的(在这种情况下,是的,它将在git repo数据库中被规范化为LF),还是它是一个你编辑过的现有文件,现在正在提交(在这种情况下什么都不会发生…除非你运行git add——renormalize。在这种情况下,它将在git回购数据库中得到规范化)。

你看到…整个机制只发生在.gitattributes没有放置文本属性变体的文件:text, -text, text=auto。

所以你真正应该看的是使用.gitattributes默认设置在你的所有文件,是:

* -text
# followed by specialization

它将默认所有(除了专门化)为原样,并覆盖核心。完全独裁,或使用默认的:

*  text=auto
# followed by specialization

这意味着git自动检测为非二进制(文本)的所有文件(特化除外),并且在git数据库中有LF[参见注释1]。],将会得到CRLF: •核心。专制是真的,或者 •核心。Eol是crlf,或者 •核心。eol是本机(默认),并且您在Windows平台上。在其他情况下,你得到LF。

我指的是什么专门化?例如,.bat文件为CRLF, .sh文件为LF:

*.sh           text eol=lf

# *.bat
*.[bB][aA][tT] text eol=crlf

or

# *.sh are committed correctly as-is (LF)
*.sh           -text

# *.bat are committed correctly as-is (CRLF)
*.[bB][aA][tT] -text

是的……事情没那么简单。


[注1]:这将是所有匹配text=auto属性的文件的情况(即没有一些其他专门化),因为我假设你的repo在.gitattribute创建时已经正确地规范化了

在linux和windows上做了一些测试。我使用一个包含以LF结尾的行和以CRLF结尾的行的测试文件。 文件被提交,删除,然后签出。 核心的价值。在提交之前和签出之前设置专制语句。 结果如下所示。

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  

以下是我到目前为止对它的理解,以防它能帮助到别人。

核心。专制=真实和核心。Safecrlf = true

You have a repository where all the line endings are the same, but you work on different platforms. Git will make sure your lines endings are converted to the default for your platform. Why does this matter? Let's say you create a new file. The text editor on your platform will use its default line endings. When you check it in, if you don't have core.autocrlf set to true, you've introduced a line ending inconsistency for someone on a platform that defaults to a different line ending. I always set safecrlf too because I would like to know that the crlf operation is reversible. With these two settings, git is modifying your files, but it verifies that the modifications are reversible.

core.autocrlf = false

您的存储库已经签入了混合的行结束符,修复不正确的行结束符可能会破坏其他东西。在这种情况下,最好不要告诉git转换行尾,因为这样会加剧它本来要解决的问题——使差异更容易阅读,合并不那么痛苦。使用此设置,git不会修改您的文件。

core.autocrlf =输入

我不使用它的原因是为了介绍一个用例,在这个用例中,您在默认为LF行结束符的平台上创建了一个具有CRLF行结束符的文件。相反,我更喜欢让我的文本编辑器总是用平台的默认行结束符保存新文件。

在即将到来的Git 1.7.2中,“eol转换”方面的事情即将发生变化:

一个新的配置设置核心。Eol正在被添加/进化:

This is a replacement for the 'Add "core.eol" config variable' commit that's currently in pu (the last one in my series). Instead of implying that "core.autocrlf=true" is a replacement for "* text=auto", it makes explicit the fact that autocrlf is only for users who want to work with CRLFs in their working directory on a repository that doesn't have text file normalization. When it is enabled, "core.eol" is ignored. Introduce a new configuration variable, "core.eol", that allows the user to set which line endings to use for end-of-line-normalized files in the working directory. It defaults to "native", which means CRLF on Windows and LF everywhere else. Note that "core.autocrlf" overrides core.eol. This means that: [core] autocrlf = true puts CRLFs in the working directory even if core.eol is set to "lf". core.eol: Sets the line ending type to use in the working directory for files that have the text property set. Alternatives are 'lf', 'crlf' and 'native', which uses the platform's native line ending. The default value is native.


正在考虑其他演变:

对于1.8,我会考虑制作核心。只需要打开规范化,并将工作目录行结束决定留给core。Eol,但那会打破人们的设定。


git 2.8(2016年3月)改进了内核的方式。selff影响eol:

参见Torsten Bögershausen (tboegi)的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, commit 320d39c(2016年2月05日)。 (由Junio C Hamano—gitster—在commit c6b94eb中合并,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)

正如torek在评论中补充的那样:

所有这些转换(从EOL =或selflf设置的任何EOL转换,以及“clean”过滤器)都在文件从工作树移动到索引时运行,即在git添加期间而不是在git提交时运行。 (注意git commit -a或——only或——include会在那个时候将文件添加到索引中。)

有关更多信息,请参见“selflf和eol之间的区别是什么”。

长期以来,混合平台项目中的eol问题一直让我的生活很痛苦。当repo中已经存在具有不同和混合eol的文件时,通常会出现问题。这意味着:

回购可能具有不同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种情况下转换发生:

核心。专制是真实的 回购文件中有LF EOL。

最令我惊讶的是,我怀疑,许多EOL问题的原因是,没有一种配置可以将CRLF+LF这样的混合EOL标准化。

Note also that "old" Mac EOLs of CR only also never get converted. This means that if a badly written EOL conversion script tries to convert a mixed ending file with CRLFs+LFs, by just converting LFs to CRLFs, then it will leave the file in a mixed mode with "lonely" CRs wherever a CRLF was converted to CRCRLF. Git will then not convert anything, even in true mode, and EOL havoc continues. This actually happened to me and messed up my files really badly, since some editors and compilers (e.g. VS2010) don't like Mac EOLs.

我想真正处理这些问题的唯一方法是偶尔通过检出输入或false模式下的所有文件来规范化整个repo,运行适当的规范化并重新提交更改的文件(如果有的话)。在Windows上,可以继续使用core。autocrlf真的。