如何在 Git 提交中强制执行一致的行结尾并具有跨平台兼容性
How to force consistent line endings in Git commits with cross-platform compatibility
我在与使用不同 OS 的人一起工作时遇到了由于行尾导致的合并冲突问题。我在 Windows 工作,我的同事在 Mac。当他推送更改时,有时他没有处理过的文件会在 diff 中显示为已更改,因为行尾现在在每个文件上显示 ^M
。这导致了合并冲突。我在 Git 文档中阅读了以下内容:
Git can handle this by auto-converting CRLF line endings into LF when
you add a file to the index, and vice versa when it checks out code
onto your filesystem. You can turn on this functionality with the
core.autocrlf setting. If you’re on a Windows machine, set it to
true — this converts LF endings into CRLF when you check out code:
$ git config --global core.autocrlf true If you’re on a Linux or macOS
system that uses LF line endings, then you don’t want Git to
automatically convert them when you check out files; however, if a
file with CRLF endings accidentally gets introduced, then you may want
Git to fix it. You can tell Git to convert CRLF to LF on commit but
not the other way around by setting core.autocrlf to input:
$ git config --global core.autocrlf input This setup should leave you
with CRLF endings in Windows checkouts, but LF endings on macOS and
Linux systems and in the repository.
这是有道理的,但我仍然不清楚这些文件是如何实际提交到回购协议中的。例如,如果他在他的系统上创建了一个文件,那么它将有所有 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
)
关于此的几个问题:当警告说 "working directory" 时,它指的是什么?此外,当我随后进行更改或创建其他文件时,所有这些文件都具有 CRLF
行结尾和提交+推送,它们是否作为 CRLF
或 LF
存储在回购协议中?
我想理想的情况是每次提交时都让 repo 剥离 LF
以外的任何东西;这是怎么回事?引擎盖下发生了什么,我们如何强制其行为一致?
autocrlf
被广泛认为已损坏。处理行结尾的现代方法是 .gitattributes
. GitHub has a great tutorial about how to use it here.
Q1 Enforcing consistent lineendings
Q2 Enforcing at commit as well as checkout (comment)
我将把它分成两部分:实践和原理
练习
扩展 建议
- 严格避免
autocrlf
— 查看原因 autocrlf is always wrong。
here 核心 git 开发人员争论 autocrlf 的考虑不周。请特别注意,实施者对 批评 感到恼火,但并不否认批评。
- 虔诚地使用
.gitattributes
而不是
- 使用
safecrlf=true
强制提交清洁。 safecrlf
是您 Q2 的答案——在签入签出往返过程中更改的文件会在签入阶段本身出错。
当一个新的 repo 被初始化时:
通过 ls -lR
并选择它的类型 text, binary
或忽略(即把它放在 .gitignore)
调试中:
使用 git-check-attr 检查属性匹配和计算是否符合要求
原则
数据存储
我们可以将 git 视为数据存储,大致类似于 USB 驱动器。
如果我们放入的东西出来一样,我们就说驱动器工作正常。否则它已损坏。同样,如果我们提交的文件在结帐时出现 相同 ,则回购很好,否则(某些东西)很无聊。关键问题是
“相同”是什么意思?
这很重要,因为我们在不同的上下文中隐含地应用了不同的“相同性”标准!
二进制文件
- 二进制文件是一个字节序列
- 如实保留该序列等同于复制文件
文本文件
...不同
一个文本文件由一系列“可打印字符”组成——让我们不指定可打印字符的概念,只是说 no cr no lf!
这些行如何分隔(或终止)再次未指定
象征性地:
输入 Line = [Char]
输入文件 = [行]
未指定的 1 日扩展给我们 ASCII、拉丁文、Unicode 等...与此问题无关
扩展2号是区分windows *nix等的JFTR this kind文件可能鲜为人知但也存在。记住“线条序列”的概念可以在许多不同的层次上应用是特别有用的。
我们不关心相同性如何尊重未指定的部分
到return到我们的
USB 驱动器类比
当我将 foo.txt 从 Windows 复制到 Linux 时,我希望 contents 是不变的。不过如果H:foo.txt
变成/media/name/Transcend/foo.txt
我就很满意了。事实上,如果 windows 主义是未经翻译的,反之亦然。
牵强?? ¡¡Think again!!
IOW 感谢像 Theodore T 这样的杰出人士,所以我们理所当然地认为 Linux 可以读取 windows 文件(系统)。发生这种情况是因为
的非平凡金额
- 抽象匹配
- 抽象隐藏
发生在幕后。
返回Git
因此,我们希望签入 git 的文件与签出的文件相同...在不同的时间...并且OS!
要注意的是,相同的概念非常重要,git 需要我们的一些帮助来实现令我们满意的“相同”...这种帮助称为 .git属性!
我在与使用不同 OS 的人一起工作时遇到了由于行尾导致的合并冲突问题。我在 Windows 工作,我的同事在 Mac。当他推送更改时,有时他没有处理过的文件会在 diff 中显示为已更改,因为行尾现在在每个文件上显示 ^M
。这导致了合并冲突。我在 Git 文档中阅读了以下内容:
Git can handle this by auto-converting CRLF line endings into LF when you add a file to the index, and vice versa when it checks out code onto your filesystem. You can turn on this functionality with the core.autocrlf setting. If you’re on a Windows machine, set it to true — this converts LF endings into CRLF when you check out code:
$ git config --global core.autocrlf true If you’re on a Linux or macOS system that uses LF line endings, then you don’t want Git to automatically convert them when you check out files; however, if a file with CRLF endings accidentally gets introduced, then you may want Git to fix it. You can tell Git to convert CRLF to LF on commit but not the other way around by setting core.autocrlf to input:
$ git config --global core.autocrlf input This setup should leave you with CRLF endings in Windows checkouts, but LF endings on macOS and Linux systems and in the repository.
这是有道理的,但我仍然不清楚这些文件是如何实际提交到回购协议中的。例如,如果他在他的系统上创建了一个文件,那么它将有所有 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
)
关于此的几个问题:当警告说 "working directory" 时,它指的是什么?此外,当我随后进行更改或创建其他文件时,所有这些文件都具有 CRLF
行结尾和提交+推送,它们是否作为 CRLF
或 LF
存储在回购协议中?
我想理想的情况是每次提交时都让 repo 剥离 LF
以外的任何东西;这是怎么回事?引擎盖下发生了什么,我们如何强制其行为一致?
autocrlf
被广泛认为已损坏。处理行结尾的现代方法是 .gitattributes
. GitHub has a great tutorial about how to use it here.
Q1 Enforcing consistent lineendings
Q2 Enforcing at commit as well as checkout (comment)
我将把它分成两部分:实践和原理
练习
扩展
- 严格避免
autocrlf
— 查看原因 autocrlf is always wrong。 here 核心 git 开发人员争论 autocrlf 的考虑不周。请特别注意,实施者对 批评 感到恼火,但并不否认批评。 - 虔诚地使用
.gitattributes
而不是 - 使用
safecrlf=true
强制提交清洁。safecrlf
是您 Q2 的答案——在签入签出往返过程中更改的文件会在签入阶段本身出错。
当一个新的 repo 被初始化时:
通过 ls -lR
并选择它的类型 text, binary
或忽略(即把它放在 .gitignore)
调试中:
使用 git-check-attr 检查属性匹配和计算是否符合要求
原则
数据存储
我们可以将 git 视为数据存储,大致类似于 USB 驱动器。
如果我们放入的东西出来一样,我们就说驱动器工作正常。否则它已损坏。同样,如果我们提交的文件在结帐时出现 相同 ,则回购很好,否则(某些东西)很无聊。关键问题是
“相同”是什么意思?
这很重要,因为我们在不同的上下文中隐含地应用了不同的“相同性”标准!
二进制文件
- 二进制文件是一个字节序列
- 如实保留该序列等同于复制文件
文本文件
...不同
一个文本文件由一系列“可打印字符”组成——让我们不指定可打印字符的概念,只是说 no cr no lf!
这些行如何分隔(或终止)再次未指定
象征性地:
输入 Line = [Char]
输入文件 = [行]未指定的 1 日扩展给我们 ASCII、拉丁文、Unicode 等...与此问题无关
扩展2号是区分windows *nix等的JFTR this kind文件可能鲜为人知但也存在。记住“线条序列”的概念可以在许多不同的层次上应用是特别有用的。
我们不关心相同性如何尊重未指定的部分
到return到我们的
USB 驱动器类比
当我将 foo.txt 从 Windows 复制到 Linux 时,我希望 contents 是不变的。不过如果H:foo.txt
变成/media/name/Transcend/foo.txt
我就很满意了。事实上,如果 windows 主义是未经翻译的,反之亦然。
牵强?? ¡¡Think again!!
IOW 感谢像 Theodore T 这样的杰出人士,所以我们理所当然地认为 Linux 可以读取 windows 文件(系统)。发生这种情况是因为
的非平凡金额- 抽象匹配
- 抽象隐藏
发生在幕后。
返回Git
因此,我们希望签入 git 的文件与签出的文件相同...在不同的时间...并且OS!
要注意的是,相同的概念非常重要,git 需要我们的一些帮助来实现令我们满意的“相同”...这种帮助称为 .git属性!