autocrlf和eol有什么区别

时间:2017-02-20 08:52:41

标签: git gitattributes

我正在阅读关于compatibility的{​​{3}}来修复混合行结尾的问题,并发现有两个类似的设置。

AUTOCRLF:

  

行结束转换虽然Git通常只保留文件内容,   它可以配置为将行结尾标准化为存储库中的LF   并且,可选择在签出文件时将它们转换为CRLF。

     

如果您只想在工作目录中使用CRLF行结尾   无论您使用哪个存储库,都可以设置   配置变量“core.autocrlf”,不使用任何属性。

     

[core] autocrlf = true这不会强制文本规范化   文件,但确保您引入的文本文件   存储库的行结束标准化为LF   添加,以及已在存储库中规范化的文件   保持正常化。

和EOL:

  

此属性设置要在其中使用的特定行结束样式   工作目录。它可以实现无线端转换   内容检查,有效设置文本属性。

     

设置为字符串值“crlf”此设置强制Git规范化线条   签入时此文件的结尾并在转换时将它们转换为CRLF   文件已签出。

     

设置为字符串值“lf”此设置强制Git标准化线   在签入时结束LF并防止在文件时转换为CRLF   签出。

     

向后兼容crlf属性   为了向后兼容,crlf属性解释如下:

     

crlf text

     

-crlf -text

     

crlf =输入eol = lf

似乎两者都在做同样的事情,但有一些关于autocrlf的事情。这是不是意味着,eol已被弃用,而新口味是crlf还是什么?我目前有一个包含多个已损坏文件的存储库,我想将其转换为{{1}}表示。而且你看到文档混淆了我们而不是澄清事情。

在这种情况下我应该申请什么?

1 个答案:

答案 0 :(得分:4)

不是直接回答问题本身 - 请参阅VonC's answer链接问题,让我们专注于此:

  

我目前有一个包含多个已损坏文件的存储库,我想将其转换为crlf表示。

首先,请注意,这些选项都不能更改任何现有提交。这是一个基本的Git属性:一旦制作,就不能改变现有的提交。你可以做的是做 new 提交。这通常不是太大的交易,因为通常我们只是希望 new 的东西是正确的(但请参阅git filter-branch,它在将过滤器应用到其内容后复制提交,并且可以是用于重新复制整个存储库:新的存储库不再与旧存储库兼容,但您可以通过这种方式修复历史记录。

接下来,我认为这是理解所有这些行/ CRLF属性选项的关键:转换在进入或退出索引时应用于文件。

请记住,Git的索引是您构建 next 提交的地方。索引的内容最初与当前提交的内容相同:例如,您运行git checkout master,Git将名称master解析为提交ID,并将该特定提交复制到您的工作中 - 树 - 但副本通过索引。

换句话说,Git首先发现文件foo.txt在提交中(需要提取)。所以Git将foo.txt的那个版本移动到索引。索引的版本完全匹配 HEAD提交的版本。 Git不会对索引版本应用任何过滤器,也不会更改任何行结尾。

更新索引版本后, Git将文件的从索引复制到工作树。 1 一些转换在此提取过程中发生 now 。如果有污迹过滤器,Git现在应用它。如果要进行行结束转换,Git现在会应用这些转换。

在此过程中,工作树文件可能索引版本不同。现在Git有一个问题,因为现在文件是"脏" (在工作树中修改)。这是事情变得特别混乱的地方,虽然大多数时候,这里的细节是看不见的。

最终,在使用工作树之后,您可以在某个文件路径名上运行git add(或使用git add -a或其他任何内容来添加许多文件)。这会将文件从工作树复制到索引中。 2 现在,在此副本中会发生更多转换:如果有一个干净的过滤器,Git现在应用它。如果要进行行结束转换,Git现在就应用它们。

换句话说,在git add这些文件之后,索引版本可能与工作树版本不匹配。但是,Git将索引版本标记为"匹配"无论如何。 git status将跳过工作树版本,因为Git现在声称索引版本与工作树版本匹配。 有点,因为如果您再次运行git add,索引版本与将被添加匹配。

实际实现使用时间戳,通常具有一秒的分辨率。 Git将继续相信索引版本与工作树版本匹配,除非并且直到操作系统触及文件的工作树版本上的时间戳。 即使您更改了要应用的过滤器和/或行结束转换的集合,也是如此。 Git没有意识到您已经更改了行结尾的工作方式,或者更改了"清洁"过滤以做一些不同的事情:它只是看到索引""缓存"方面说"我匹配工作树版本时间戳 T "。只要工作树版本的时间戳仍然是 T ,文件必须是" clean"。

因此,要在更改任何文本转换设置后更新这些内容,您需要让Git意识到文件不干净。您可以touch <path>设置&#34;现在&#34;的新时间戳,它不会与索引中的旧时间戳匹配。现在git add -a(或其他)会像往常一样扫描,但由于时间戳不匹配,它会在这次找到文件,并会重新过滤它以将其添加到索引中。

同样,当您git add文件时会发生这些转换。

通常,在类似Windows的系统上,您的目标是获取仅使用LF的存储库格式文件并将其转换为CR-LF文件以供Windows处理。该转换发生在索引 out 的路上, 工作树:即git checkout期间。那么你会希望在git add过程中将这些CR-LF工作树文件转换为仅LF格式,这样就可以在存储库中形成Linux(以及Linus Torvalds和Git :-)的方式。喜欢他们。但是你可以以CR-LF格式将它们存储在存储库中,如果你真的想要惹恼所有的Unix / Linux人员。如果有的话,您应用以下步骤进行转换:git checkout时间和git add时间。

.gitattributes文件指定要应用于哪些文件的转换。 core.autocrlfcore.eol设置不要 Git必须最好地猜测哪些文件在哪一步获得哪些转换。

1 从技术上讲,索引中的所有内容都是文件的哈希ID。文件本身存储为存储库数据库中的Git blob 对象。与提交对象一样,这些blob对象也是不可变的。那个为什么它无法在索引中更改:它实际上只是一个哈希ID。

2 git add进程只需编写一个 new blob,并在任何过滤后写入新的blob。如果新blob与某些现有blob完全匹配,则新blob重新使用现有blob的数据库条目和散列ID,并且实际上不会保存 - 现有blob就足够了。如果不是,则blob的数据将作为新文件存储,并带有新ID。它是进入索引的新哈希ID。