如何在跨平台兼容的情况下强制Git提交中使用一致的行尾

lmvvr0a8  于 2023-01-01  发布在  Git
关注(0)|答案(2)|浏览(107)

当我和使用不同操作系统的人一起工作时,我遇到了由于行尾引起的合并冲突问题。我在Windows上工作,而我的同事在Mac上工作。当他推送他的更改时,有时他没有处理过的文件会在diff中显示为正在更改,因为每个文件的行尾现在都显示为^M。这导致了合并冲突。我在Git文档中读到了以下内容:
Git可以在你向索引添加文件时自动将CRLF行结尾转换为LF,反之亦然。你可以通过核心的.autocrlf设置来打开这个功能。如果你在Windows机器上,将其设置为true -这会在你 checkout 代码时将LF行结尾转换为CRLF:
$ git config --global core.autocrlf true如果你使用的是使用LF行结尾的Linux或macOS系统,那么你不希望Git在你 checkout 文件时自动转换它们;但是,如果一个文件以CRLF结尾,你可能需要Git来修正它。你可以通过设置core.autocrlf为input来告诉Git在提交时将CRLF转换为LF,而不是相反:
$ git config --global core.autocrlf input这个设置应该会在Windows checkout 中留下CRLF结尾,但在macOS和Linux系统以及存储库中留下LF结尾。
这是有道理的,但是我仍然不清楚文件实际上是如何在repo中提交的。例如,如果他在他的系统上创建了一个文件,它将具有所有LF行结尾,对吗?所以当他提交时,我假设这些行结尾保持原样。当我拉取时,我的autocrlftrue,将使用CRLF行结尾 checkout 它们。据我所知。(我得到警告warning: LF will be replaced by CRLF in <file x>; The file will have its original line endings in your working directory
关于这一点有几个问题:当警告说“工作目录”时,那是指什么?另外,当我随后进行更改或创建其他文件时,所有这些文件都有CRLF行结束和commit+push,它们在repo中存储为CRLF还是LF
我认为理想的做法是每次提交时,让repo剥离除LF以外的任何内容;这是发生了什么?引擎盖下发生了什么?我们如何强制它一致地运行?

uurv41yg

uurv41yg1#

Q1强制一致的行结束
Q2在提交和 checkout 时执行(注解)
我将此分为两部分:实践与原则

练习

code-apprentice's建议扩展
1.严格避免autocrlf--看看为什么要使用autocrlf is always wronghere,因为核心git开发者在争论autocrlf的欠考虑。特别要注意的是,实现者对 * 批评者 * 很恼火,但并不否认 * 批评 *。
1.请改用.gitattributes
1.使用safecrlf=true来强制执行commit-cleanness。safecrlf是您的问题2的答案-在签入 checkout 往返过程中更改的文件将在签入阶段本身出错。
当初始化新的存储库时:
通过ls -lR并选择它的类型text, binary或忽略(即把它放在. gitignore)
调试:
使用git-check-attr检查属性匹配和计算是否符合要求

原则

数据存储

我们可以将git视为一个数据存储,大致类似于USB驱动器。
如果我们放进去的东西出来是一样的,我们就说驱动器在工作。否则它就坏了。同样,如果我们提交的文件出来是一样的,那么回收是好的,否则(某些东西)就坏了。关键问题是
"相同"是什么意思?
这并不简单,因为我们在不同的语境中隐含地应用了不同的"相同"标准!

二进制文件

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

文本文件

......是不同的

  • 一个文本文件由一系列"可打印字符"组成--让我们不指定可打印字符的概念,而是说no cr no lf!
  • 如何分隔(或终止)这些行再次未指定
  • 象征性:

类型行=[字符]
类型文件=[行]

  • 扩展第一个未指定的字符,我们可以得到ASCII、拉丁语、Unicode等...与此问题无关
  • 扩展2号是什么区分windows * nix等文件的JFTR this kind可能是鲜为人知的年轻一代,但也存在。特别有用的是要记住,概念"行序列"可以强加在许多不同的水平。
    • 我们不在乎相同性如何影响未指明的部分**

回到我们的

U盘类比

当我把foo.txt从Windows复制到Linux时,我希望 * contents * 是不变的。然而,如果H:foo.txt变成/media/name/Transcend/foo.txt,我就很满意了。事实上,如果windowsisms是未经翻译的,或者反之亦然,那就太烦人了。
牵强的??¡¡Think again!!
感谢像Theodore T'这样杰出的人,所以我们认为Linux可以读取Windows文件(系统)是理所当然的。

  • 抽象匹配
  • 抽象隐藏

发生在引擎盖下。

返回Git

因此,我们希望签入到git的文件与 checkout 的文件是 * 相同的 *...在不同的时间...和操作系统!
问题是,相同的概念非常重要,git需要我们的帮助来实现我们满意的"相同性"...这种帮助被称为.gitattributes!

new9mtju

new9mtju2#

autocrlf被广泛认为是坏的,处理行结束的现代方法是用.gitattributes,GitHub在这里有一个很棒的关于如何使用它的教程。

相关问题