如何在具有跨平台兼容性的 Git 提交中强制使用一致的行结尾 [英] How to force consistent line endings in Git commits with cross-platform compatibility

查看:30
本文介绍了如何在具有跨平台兼容性的 Git 提交中强制使用一致的行结尾的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having issues with merge conflicts due to line endings while working with someone who uses a different OS. I work on Windows and my colleague is on Mac. When he pushes his changes, sometimes files he hasn't worked on show up in the diff as being changed, because the line endings now show ^M on each file. This has lead to merge conflicts. I read in the Git docs the following:

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

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 如果您使用的是 Linux 或 macOS使用 LF 行结尾的系统,那么你不希望 Git签出文件时自动转换它们;然而,如果一个意外引入了带有 CRLF 结尾的文件,那么您可能想要Git 来修复它.您可以告诉 Git 在提交时将 CRLF 转换为 LF 但通过将 core.autocrlf 设置为输入而不是相反:

$ 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 这个设置应该离开你在 Windows 结帐中以 CRLF 结尾,但在 macOS 和 LF 中以 LF 结尾Linux 系统和存储库中.

$ 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 中实际提交的.例如,如果他在他的系统上创建一个文件,它的所有行结尾都是 LF,对吗?因此,当他提交时,我认为这些行结尾保持原样.当我拉时,我的 autocrlftrue 将用 CRLF 行结尾检查它们,据我所知.(我收到警告 warning: LF will be替换为 CRLF in <file x>; 该文件将在您的工作目录中以原始行结尾)

This makes sense, but I am still unclear on how the files are actually committed in the repo. For example, if he creates a file on his system, it will have all LF line endings, correct? So when he commits, I presume those line endings are retained as-is. When I pull, my autocrlf being true will check them out with CRLF line endings, as far as I understand. (I get the warnings 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 或 <代码>LF?

A couple questions about this: when the warning says "working directory", what is that referring to? Also, when I then make changes, or create other files, all of which have the CRLF line endings and commit+push, are they stored in the repo as CRLF or LF?

我认为理想的情况是每次提交时都让 repo 删除任何内容,但 LF 除外;这是怎么回事?幕后发生了什么,我们如何才能强制其行为一致?

I imagine the ideal is to have the repo strip anything but LF everytime a commit is made; is this what happens? What's going on under the hood and how can we force this to behave consistently?

推荐答案

Q1 强制使用一致的行尾

Q1 Enforcing consistent lineendings

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

Q2 Enforcing at commit as well as checkout (comment)

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

I'll divide this into 2 parts: Practice and Principle

扩展代码学徒的建议

  1. 严格避免 autocrlf — 看看为什么 autocrlf 总是错误的.和 这里 用于核心 git 开发人员争论 autocrlf 的深思熟虑.特别要注意的是,实现者对批评感到恼火,但并不否认批评.
  2. 宗教上使用.gitattributes代替
  3. 使用 safecrlf=true 强制提交清洁.safecrlf 是您的 Q2 的答案——一个在签入签出往返时会更改的文件会在签入阶段本身出错.
  1. Strictly avoid autocrlf — See why autocrlf is always wrong. And here for the core git devs arguing about the ill-thoughtout-ness of autocrlf. Note particularly that the implementor is annoyed at the critic but doesn't deny the criticism.
  2. Religiously use .gitattributes instead
  3. Use safecrlf=true to enforce commit-cleanliness. safecrlf is the answer to your Q2 – a file that would change on check-in check-out round tripping would error out on the check-in stage itself.

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

When a new repo is init-ed:
Go through ls -lR and choose for it's type text, binary or ignore (ie put it in .gitignore)

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

Debugging:
Use git-check-attr to check that attribute matching and computation are as desired

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

We may treat git as a data-store loosely analogous to how a USB drive is one.

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

We say the drive is working if the stuff we put in comes out the same. Else it's corrupted. Likewise if the file we commit comes out the same on checkout the repo is fine else (something) is borked. The key question is

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

It's non-trivial because we implicitly apply different standards of "sameness" in different contexts!

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

...不一样

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

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

How these lines are separated (or terminated) is again unspecified

象征性地:
type Line = [Char]
类型文件 = [行]

Symbolically:
type Line = [Char]
type File = [Line]

在未指定的第 1 个扩展给我们 ASCII、拉丁语、Unicode 等...与此问题无关

Expanding on the 1st unspecified gives us ASCII, Latins, Unicode etc etc... Not relevant to this question

2 号扩展是 windows *nix 等的区别.JFTR 这种<文件的/a> 可能年轻一代鲜为人知,但也存在.记住行的顺序"这个概念特别有用.可以在许多不同的层次上施加.

Expanding on the 2nd is what distinguishes windows *nix etc. JFTR this kind of file may be little known by the younger generation but also exists. And is particularly useful to remember that the notion "sequence of lines" can be imposed at many different levels.

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

返回我们的

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

When I copy foo.txt from Windows to Linux I expect the contents to be invariant. However I'm quite satisfied if H:foo.txt changes to /media/name/Transcend/foo.txt. In fact it would be more than a bit annoying if the windowsisms came through untranslated or vice versa.

牵强??¡¡再想一想!!

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

IOW thanks to splendid folks like Theodore T'so we take it for granted that Linux can read a windows file (system). This happens because a non-trivial amt of

  • 抽象匹配
  • 抽象隐藏

发生在幕后.

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

We therefore expect that a file checked in to git is the same that's checked out... at a different time... And OS!

问题在于,相同的概念非常重要,因此 git 需要我们的一些帮助才能实现相同".令我们满意...该帮助称为 .gitattributes!

The catch is that the notion of same is sufficiently non-trivial that git needs some help from us in achieving that "sameness" to our satisfaction... That help is called .gitattributes!

这篇关于如何在具有跨平台兼容性的 Git 提交中强制使用一致的行结尾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆