如何为混合LF / CRLF文件设置新的git存储库

时间:2017-02-21 00:09:11

标签: git github freemind

我在Windows 10上使用GitHub Desktop。我想设置一个git存储库,它包含一些文本文件(.md或.adoc)和Freemind思维导图(.mm)。 Freemind使用基于XML的文件格式和Unix风格的换行符(LF)。

在过去的4个小时里,我想我已经阅读了每个StackOverflow讨论以及每个可以在网上找到EOL规范化的git文档 - 它仍然让我发疯!许多讨论似乎已经过时,意见似乎相互矛盾。这是我到目前为止的方式:

  • 我已将core.autocrlfcore.safecrlf保留为默认值
  • 根据建议我使用.gitattributes文件* text=auto - 我可以自动转换文本文件。
  • 要保留我.mm文件的LF,我添加了*.mm text eol=LF

令我困惑的是这个警告:

> git add Mindmap.mm
warning: LF will be replaced by CRLF in Mindmap.mm.
The file will have its original line endings in your working directory.

据我了解,* text=auto相当于core.autocrlf=true,并确保在提交时所有EOL都转换为LF - 在这种情况下,LF-gt; LF。并且*.mm text eol=LF确保LF在结账时保留 - LF-> LF在另一个方向。没有CRLF参与!那么为什么Git警告我某些转换会导致CRLF?

问题1 :当我在GitHub上公开我的项目时,我想确保我不会遇到UNIX用户的跨平台问题。我的案例的最佳做法是什么?如果我做的一切都好,我可以忽略警告吗?

问题2 :在某些情况下.mm文件也可以包含CRLF。当然,我可以将它们作为二进制文件处理,但是我不会再看到GitHub Desktop中的任何差异。有没有办法将它们视为文本文件,同时保留混合换行符(LF和CRLF)?

非常感谢任何提示!

2 个答案:

答案 0 :(得分:1)

我没有使用Windows,因此犹豫了一些提出建议,但我可以在这里描述各种机制,并至少制作一些。 : - )

转换文件数据的操作,包括修改行结尾的任何内容,在将数据从存储库中提取到工作树中时应用(通常有一些特定的例外) - 基本上{ {3}},但请查看最后的注释或添加到存储库中,基本上是git checkout

为了转换转换文件数据,Git必须知道哪些文件被转换转换为应用。 Git必须对每个文件进行分类以决定要做什么。

有些文件显然是二进制文件,有些文件几乎肯定是文本文件,有些文件很模糊。 Git会猜测是否必须。您可以(我猜,或许,过去常常?)告诉通过设置core.autocrlf=truecore.autocrlf=input进行猜测,但请看下一段。

如果您有一个.gitattributes文件,您可以根据文件的路径名称告诉Git文件,例如*.txt应该始终被视为文本文件,而*.bin文件应该永远不会被视为文本文件。这样可以更好地控制,因为不仅可以根据这样的路径名进行匹配,还可以编写以下任何一个:

*.ex1   text      # definitely text
*.ex2   -text     # definitely not text
*.ex3   text=auto # please guess for me based on file contents
# don't mention *.ex4: check core.autocrlf to decide whether to guess

基于这一部分,我建议core.autocrlf永远不会好用,因为猜测似乎首先是可疑的。至少在text=auto时,你有一个显而易见的地方请求猜测。

独立于猜测或确定,您可以在路径后列出eol=crlfeol=lf。这使得转换成为可能,即,在决定是否在提取(git checkout)和插入(git add)时弄乱行结尾时,文件被视为文本。在工作树中结束的是CRLF或仅LF。在任何一种情况下,工作树中的CRLF在git add期间仅用LF替换。我怀疑,但尚未测试,此不会影响git diff

(毫无疑问,旧的crlf-crlfcrlf=input设置无法再使用,但如果您确实使用它们,则其行为与git add中所述相同。)

现在,您突出显示的一个明显问题是使用-text将文件标记为"从不接触过autocrlf或其他猜测的转换"与git diff进行互动,因为git diff 必须在生成差异之前猜测文件是否为文本。在这里,我们可以返回the gitattributes documentation,我们发现路径名称可以有diff属性:

*.ex5   -text diff  # not text for crlf treatment, but text for diff
*.ex6   -text -diff # not text for either one
*.ex7   text -diff  # definitely text for crlf, but binary for diff
*.ex8   diff=my-diff-driver # use my diff driver; no opinion about text

离开diff完全让Git猜测,就像对待crlf一样。

请注意.gitattributes中的路径名称不一定是模式:您可以列出:

path/to/some/file       -text
path/to/another/file    text

如果Git猜错某些文件。

我还没有提到core.safecrlf,但我认为the gitattributes documentation中的讨论非常充分。它包含一系列在各种命令中运行的特殊测试,稍早在两个方向上进行转换,最后结帐阶段转到一个立即抛出的临时文件,只是为了查看文件工作树现在中的将保持现在的方式。也就是说,如果您立即执行git add path; git commit -m dummy; rm path; git checkout -- path 路径中的文件是否会更改内容?如果是这样,那么转换就不是'#34;安全"。

最后,我应该提一些特殊情况。转换(行结尾和污迹过滤器)在文件从索引中出来时完成;这包括the git config documentation命令。通过添加--textconv--path=--filters,可以在绕过索引的操作期间有意地完成它们:the git checkout-index; git cat-file--textconv,虽然详细信息因特定的Git版本而有所不同(其中许多选项不适用于旧版本的Git)。同样,转换(行结尾和清除过滤器)在文件进入索引时完成,但也可以使用--path--no-filtersgit show中完成或禁止。

答案 1 :(得分:0)

text文件取消设置.mm会阻止git对它们进行crlf次转换,但它不会开始将它们视为二进制文件,因此git-diff和其他功能将会仍然表现得很好。

在.gitattributes文件中:

* text=auto

*.mm -text

那应该解决你的第二个问题。但是,因为git不会强制执行.mm文件的行结尾,所以当你上市并且贡献者开始在OS-X和Linux上修改它们时,它可能会引起一些麻烦。如果你可以描述.mm行结尾的规则,也许可以调整配置,或者也许一个commit-hook可以帮助你强制执行它,除此之外我不知道如何解决你的第一个和第一个第二个问题同时出现。