微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

更改行尾 git 配置 在.gitattributes中设置什么这行 * text eol=lf 是什么意思不要使用core.autocrlf底层机制

如何解决更改行尾 git 配置 在.gitattributes中设置什么这行 * text eol=lf 是什么意思不要使用core.autocrlf底层机制

所以现在我在另一所大学的一个项目中工作,他使用 mac,我使用 windows,所以我们在文件的 EOL(行尾)方面遇到了问题。我们决定,我们希望所有文件都是 LF。对他来说没问题,因为他使用的是 mac,但我必须将所有文件CRLF 更改为 LF,我已经完成了,而且我还设置了一个每次添加文件时,配置它以 LF 开头。问题是当我想对我们的存储库提交更改时,它给了我这个警告。

The file will have its original line endings in your working directory warning: LF will be replaced by 
CRLF in tsconfig.build.json.

我想达到什么目标?我想禁用 github 的这种“自动”替换。我不希望我的文件CRLF 替换,我希望我的所有文件始终都是 LF。有什么建议吗?

解决方法

首先是一些重要的术语说明:GitHub 永远不要取代任何东西。他们确实不能。这里不用担心 GitHub;它们无关紧要。 不要担心你自己的 Git,除了以相同的三个字母开头之外,它与 GitHub 几乎没有关系。 GitHub 是一个托管服务提供商,您可以在其中存储和访问 Git 存储库。 Git 是实现版本控制系统的软件。

你的 Git 是问题所在和/或应该解决的地方。好吧,您的 Git,以及您朋友或同事的 Git,等等,取决于他们使用的系统。你的文件编辑器也可能扮演角色,但 Git 可以并且会覆盖它们,如果你设置它这样做。

我希望我的所有文件始终为 LF。

您提到了 Visual Studio Code,它可能也有自己处理文件的方法。如果它适合您的目的,您可以对此进行调查和配置。这个答案只涉及 Git 本身。

.gitattributes中设置什么

要确保新添加或更新的文件获得并查看仅 LF 行结尾,请修改您现有的 .gitattributes 文件以列出您希望受影响的文件名或模式,并包括:

<pattern> text eol=lf

此处的 pattern 部分可以包含 *.json*.sh 之类的内容,甚至仅包含 *(匹配所有文件名)。

如果您没有 .gitattributes 文件,只需创建一个。确保它包含纯文本,最好是简单的 ASCII 或 UTF-8,没有字节顺序标记。

这行 * text eol=lf 是什么意思

如上所述,第一部分是一个模式:它是该行其余部分适用的文件集。通过包含多行,您可以列出多个模式,或多次列出同一模式。 last 匹配模式通常会覆盖较早的匹配模式。1

text 部分告诉 Git 这个文件是 text,即由行组成的可编辑内容,而不是二进制文件,Git 不能假设它包含文本.这会在文件上启用行尾转换2

eol=lf 告诉 Git 行尾应该是什么样子。此处的 lf 表示使用换行结尾,而不是 Windows 程序通常似乎更喜欢或需要的 CRLF 行结尾。

您可以为 eol 设置的另一个值是 eol=crlf,但鉴于您上面的陈述,您不希望这样。


1这也是它在 .gitignore 中的工作方式。但是,在 .gitattributes 文件中,这可能会变得复杂,因为每一行都可以设置不同的内容。例如,你可以这样写:

* text
*.bin -text

-text 覆盖 text,因此最后一行优先,但仅适用于名称以 .bin 结尾的文件。但你也可以写:

* text zorg
*.bin -text

那么您已经为所有文件设置了 zorg 属性,包括 *.bin 文件。 -text 取消设置 text*.bin,但保留 zorg 设置。

2从技术上讲,如果您使用 text 部分,则可以完全忽略 eol=lf 部分。将 eol 设置为某个值意味着设置 text。不过,The gitattributes documentation 在示例中使用了 text eol=lf,因此这似乎是必要


不要使用core.autocrlf

非常旧的 Git 版本使用 core.autocrlfcore.eol 和其他类似的 core 设置来执行此类操作。除此之外,您可以(但不应)在 text=auto 行中使用 .gitattributes。这告诉 Git 猜测文件是否包含文本,因此行尾可以更改,还是二进制(因此不应该弄乱它的行尾,因为它们只是巧合类似于行尾,但实际上是宝贵的二进制数据)。

您看到的警告与这些内容有关。如果 Git 计划弄乱某个文件,而 Git 计划弄乱文件的方式在 Git 看来有点可疑,Git 会警告你。

底层机制

可能有一段时间——或者可能已经到来——您想要查看存储库本身中的内容,而不是您使用的文件。你可能想知道这个声明是什么意思。毕竟,存储库不是您使用的文件的集合吗?但答案是:不,不是!

Git 就是关于提交的。Git 存储库包含和使用的内容,至少在大多数情况下是提交。虽然提交包含文件,但提交本身不是一个文件,也不是它包含的文件。提交是它自己的东西。这是真实的东西,它是一个单元——嗯,主要是单元——你的 Git 传递给其他 Git,反之亦然。

每个提交都有一个唯一的编号。这不是您的 存储库中的唯一编号,而是全局或通用唯一编号:UUID or GUID。为了确保每个 ID 对于每个特定提交都真正唯一,Git 为提交分配了非常长且看起来随机的哈希 ID。这些实际上是每个提交的真实名称。您的 Git 与其他一些 Git 聚集在一起,并且这两个通过共享这些 ID 来共享提交。如果你的 Git 有一些他们没有的 ID,那就意味着你的 Git 有一些他们没有的提交,反之亦然。

这个 ID 实际上是提交的所有数据的加密校验和。因此,一旦提交,任何提交的任何部分都不能改变。这就是为什么您不必担心 GitHub。你在你的计算机上进行提交,从那时起,没有任何东西——甚至 Git 本身——可以改变它们。它们是完全、完全只读的。任何提交中的任何文件内的任何行结尾都是永远——以及该行的其余部分,以及该文件中的所有其他行。每次提交中的文件都被永久冻结。

因此,提交包含文件——这是它的主要数据,真的——以及我们不会在这个答案中涉及的其他一些元数据。提交中的文件和元数据一直被冻结。它们还以去重格式存储,只有 Git 本身可以读取。这两个因素使得文件对于完成任何实际工作毫无用处,因为:

  • 我们需要能够读取文件(在程序中,在我们的编辑器中,等等),并且
  • 我们需要能够更改文件,以进行新的工作。

这意味着要使用来自某个提交的文件,Git 必须提取这些文件。当它这样做时,它会将提取的文件放在工作区中。 Git 将此工作区称为您的工作树工作树。这很简单:这是您工作的地方。

您在工作树中处理的文件不是 Git 的 文件。提交的文件在某个提交中。那些不能改变。 Git 的文件在别处。工作树文件是你的,根本不在 Git 中。

因为 Git 必须先提取文件才能看到并使用它们,所以这是一个理想的地方,可以获取只有 LF 行结尾的文件,并将它们转换为 CRLF 结尾的文件,以便你可以看到和一起工作。如果您选择让 Git 弄乱行尾,Git 将始终尝试存储仅 LF 行尾的文件,并在提取过程中将它们转换为 CRLF 尾。

因为 Git 必须先将文件压缩成其冻结格式,然后才能将任何新文件或更改过的文件放入提交中,因此这是获取已CRLF 行结尾,并将它们转换为只有 LF 行结尾的文件,然后将它们存储在新的提交中。如果您选择让 Git 弄乱行尾,当用新内容替换文件内容时,Git 将始终将这些行转换为 LF-only 行。

此机制适用于整个文件。当您使用 git add 时—如果您更新了某些文件,则必须这样做3—Git届时,将进行行尾转换将文件压缩为冻结格式,准备提交。4同样,当您使用 git checkout要从一个提交切换到另一个提交,Git 必须从您的工作树中删除任何与您正在切换的新提交不同(或完全消失!)的文件 >,并将其替换为从该提交中取出的文件。然后它将提交的文件扩展为您的工作树中可用的文件,并且在这样做的同时,可以用 CRLF 行结尾替换 LF-only 行结尾。

其中特别棘手的部分是,如脚注 4 所述,Git 努力不去打扰没有更改的文件。这一切假设之前可能应用的任何 eol= 设置现在仍然适用。因此,有时,当您更改 eol= 设置时,您必须删除 Git 的索引以使其无效,或者触摸工作树中的所有文件,或者使用 git add --renormalize ,如果您的 Git 足够新,可以有“重新规范化”选项。

这在实践中归结为如果您更改 eol= 设置,您可能想要运行 git add --renormalize --all 或类似的。如果你没有它,有一些相当丑陋的解决方法,但最好的办法可能是升级你的 Git 版本。


3虽然您可以使用 git commit -agit commit --include 和文件名列表,但其内部工作方式或多或少,对这些文件运行 git add或多或少部分有很多内容,但这个答案不会涉及这些细节。

4这个的机制涉及到 Git 调用的内容,以不同的方式,索引,或暂存区 ,或者——现在很少——缓存。这三个词都是指同一个东西。这件事的缓存方面试图跟踪您可能在工作树中实际更改了哪些文件,以及您在工作树中绝对没有更改了哪些文件。这让 Git 在您从提交更改到提交时不理会这些文件,从而加快 Git 速度。它还允许 git add skip 添加一些文件,从而加快 Git 速度。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。