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

标签 windows git merge git-merge line-endings

在与使用不同操作系统的人一起工作时,我遇到了由于行尾导致的 merge 冲突问题。我在 Windows 上工作,而我的同事在 Mac 上工作。当他推送他的更改时,有时他没有处理的文件会在 diff 中显示为已更改,因为行结尾现在显示 ^M在每个文件上。这导致了 merge 冲突。我在 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.

这是有道理的,但我仍然不清楚这些文件是如何实际提交到 repo 协议(protocol)中的。例如,如果他在他的系统上创建了一个文件,它将包含所有 LF行尾,对吗?因此,当他提交时,我认为这些行结尾将按原样保留。当我 pull 时,我的 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行尾和 commit+push,它们是否作为 CRLF 存储在 repo 中?或 LF

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

最佳答案

Q1 Enforcing consistent lineendings

Q2 Enforcing at commit as well as checkout (comment)

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

练习

扩展code-apprentice's建议

  1. 严格避免 autocrlf — 查看原因 autocrlf is always wrong . 和 here对于核心 git 开发人员争论 autocrlf 的考虑不周。请特别注意,实现者对批评感到恼火,但并不否认批评
  2. 虔诚地使用 .gitattributes 代替
  3. 使用 safecrlf=true 强制提交清洁。 safecrlf 是您 Q2 的答案——一个在 checkin checkout 往返过程中会更改的文件会在 checkin 阶段本身出错。

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

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

原则

数据存储

我们可以将 git 视为数据存储,大致类似于 USB 驱动器。

如果我们放入的东西输出相同,我们就说驱动器工作正常。否则它已损坏。同样,如果我们提交的文件在 checkout 时出现相同,则 repo 很好,否则(某些东西)很无聊。关键问题是

“相同”是什么意思?

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

二进制文件

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

文本文件

...不同

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

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

  • 象征性地:
    输入 Line = [Char]
    输入文件 = [行]

  • 在 1st unspecified 展开给我们 ASCII、Latins、Unicode 等等...与这个问题无关

  • 扩展2号是windows *nix等的区别 JFTR this kind of 文件可能鲜为人知,但也存在。记住“线条序列”的概念可以在许多不同的层次上应用是特别有用的。

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

回到我们的

USB 驱动类比

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

牵强附会?? ¡¡Think again!!

感谢像 Theodore T 这样杰出的人,所以我们认为 Linux 可以读取 Windows 文件(系统)是理所当然的。发生这种情况是因为

  • 抽象匹配
  • 抽象 stash

发生在幕后。

回到 Git

因此,我们希望 checkin git 的文件与 checkout 的文件相同......在不同的时间......和操作系统!

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

关于windows - 如何在具有跨平台兼容性的 Git 提交中强制执行一致的行结尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57960566/

相关文章:

c++ - SFML 全屏和居中

Java ProcessBuilder + bash : "No such file or directory"

ios - JUCE 中的视频播放器 (C++) - 在 Windows 上构建并在 iOS 上运行

windows - 如何检查Windows中的vbs脚本是否正在运行?

git - 如何在gitlab存储库中下载单个文件夹或文件

c# - 如何在 C# 中将两个 List<dynamic> 对象合并为一个具有特定条件的对象?

java - 通过复杂比较合并多个排序的 csv 文件

c# - 当我尝试将我的代码添加到 GitHub 上的存储库时,出现类似 "Failed to push to the remote repositor..."的错误

git - 如果检测到更改中的特定短语,如何防止 git commit?

Git - 区分范围但忽略 merge