如何在具有跨平台兼容性的 Git 提交中强制使用一致的行结尾

tee*_*pee 5 windows git merge line-endings git-merge

在与使用不同操作系统的人一起工作时,由于行结束,我遇到了合并冲突问题。我在 Windows 上工作,我的同事在 Mac 上工作。当他推送他的更改时,有时他没有处理过的文件会在 diff 中显示为已更改,因为现在^M每个文件上都会显示行尾。这导致了合并冲突。我在 Git 文档中阅读了以下内容:

当您将文件添加到索引时,Git 可以通过将 CRLF 行结尾自动转换为 LF 来处理此问题,反之亦然,当它检出代码到您的文件系统时。您可以使用 core.autocrlf 设置打开此功能。如果您使用的是 Windows 计算机,请将其设置为 true?—?这会在您检出代码时将 LF 结尾转换为 CRLF:

$ git config --global core.autocrlf true 如果你在使用 LF 行尾的 Linux 或 macOS 系统上,那么你不希望 Git 在检出文件时自动转换它们;但是,如果意外引入了带有 CRLF 结尾的文件,那么您可能需要 Git 修复它。您可以通过将 core.autocrlf 设置为输入来告诉 Git 在提交时将 CRLF 转换为 LF,而不是相反:

$ git config --global core.autocrlf input 这个设置应该让你在 Windows 结账中使用 CRLF 结尾,但在 macOS 和 Linux 系统以及存储库中使用 LF 结尾。

这是有道理的,但我仍然不清楚这些文件是如何在 repo 中实际提交的。例如,如果他在他的系统上创建一个文件,它会有所有的LF行结尾,对吗?因此,当他提交时,我认为这些行结尾保持原样。据我所知,当我拉动时,我的autocrlf存在true会用CRLF行尾检查它们。(我收到警告warning: LF will be replaced by CRLF in <file x>; The file will have its original line endings in your working directory

关于此的几个问题:当警告说“工作目录”时,它指的是什么?此外,当我再进行更改,或者创建其它文件,所有这些都将CRLF行结束并提交+推,都存储在回购作为CRLFLF

我想理想的是让 repo 剥离任何东西,但LF每次提交时;这是怎么回事?引擎盖下发生了什么,我们如何才能强制其行为一致?

Rus*_*usi 14

Q1 强制执行一致的行尾

Q2 在提交和结帐时强制执行(评论)

我将把它分为两部分:实践和原则

实践

码徒弟建议的扩展

  1. 严格避免autocrlf——看看为什么autocrlf 总是错的。而在这里为核心的git开发者争论autocrlf的不良thoughtout的烦躁。特别要注意的是,实现者对批评者感到恼火,但并不否认批评
  2. 宗教上使用.gitattributes,而不是
  3. 使用safecrlf=true强制提交洁净度。 safecrlf是您的 Q2 的答案——一个在签入签出往返时会更改的文件会在签入阶段本身出错。

当一个新的 repo 被初始化时:
通过ls -lR并选择它的类型text, binary或忽略(即把它放在 .gitignore 中)

调试:
使用git-check-attr检查属性匹配和计算是否符合要求

原则

数据存储

我们可以将 git 视为一种类似于 USB 驱动器的数据存储。

如果我们放入的内容相同,我们就说驱动器正在工作。不然坏了。同样,如果我们提交的文件在结帐时输出相同,则 repo 很好,否则(某些东西)被 borked。关键问题是

“相同”是什么意思?

这很重要,因为我们在不同的上下文中隐含地应用了不同的“相同”标准!

二进制文件

  • 二进制文件是一个字节序列
  • 忠实地保留该序列相当于再现文件

文本文件

...是不同的

  • 一个文本文件由一系列“可打印字符”组成——除了说no cr no lf之外,让我们不指定可打印字符的概念

  • 这些行如何分隔(或终止)再次未指定

  • 象征性地:
    type Line = [Char]
    type File = [Line]

  • 在第一个未指定的情况下扩展给我们 ASCII、拉丁语、Unicode 等...与这个问题无关

  • 2号展开就是区分windows *nix etc. JFTR这种文件可能年轻一代鲜为人知,但也存在。记住“行的序列”的概念可以在许多不同的层次上强加特别有用。

    我们不在乎相同性如何尊重未指定的部分

回到我们的

U盘类比

当我将 foo.txt 从 Windows 复制到 Linux 时,我希望内容是不变的。但是,如果H:foo.txt 更改为 /media/name/Transcend/foo.txt. 事实上,如果windowsisms 是通过未翻译的,反之亦然,那将会很烦人。

牵强?? 再想想!!

IOW 感谢像 Theodore T' 这样出色的人,所以我们理所当然地认为 Linux 可以读取 windows 文件(系统)。发生这种情况是因为一个非平凡的

  • 抽象匹配
  • 抽象隐藏

发生在引擎盖下。

回到 Git

因此,我们希望签入 git 的文件与签出的文件相同......在不同的时间......还有操作系统!

问题是相同的概念非常重要,git 需要我们的一些帮助来实现我们满意的“相同”......这种帮助称为 .gitattributes!


Cod*_*ice 9

autocrlf被广泛认为已损坏。处理行尾的现代方法是使用.gitattributes. GitHub 有一个很棒的教程,介绍如何在此处使用它。

  • 感谢您提供教程链接!它救了我的命。对我来说,问题是二进制“.whl”文件在推送到存储库时发生更改。我可以通过将“*.whl binary”添加到“.gitattributes”文件中来防止这种情况。 (2认同)