我在Windows 10上使用GitHub Desktop。我想设置一个git存储库,它包含一些文本文件(.md或.adoc)和Freemind思维导图(.mm)。 Freemind使用基于XML的文件格式和Unix风格的换行符(LF)。
在过去的4个小时里,我想我已经阅读了每个StackOverflow讨论以及每个可以在网上找到EOL规范化的git文档 - 它仍然让我发疯!许多讨论似乎已经过时,意见似乎相互矛盾。这是我到目前为止的方式:
core.autocrlf
和core.safecrlf
保留为默认值.gitattributes
文件* text=auto
- 我可以自动转换文本文件。*.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)?
非常感谢任何提示!
答案 0 :(得分:1)
我没有使用Windows,因此犹豫了一些提出建议,但我可以在这里描述各种机制,并至少制作一些。 : - )
转换文件数据的操作,包括修改行结尾的任何内容,在将数据从存储库中提取到工作树中时应用(通常有一些特定的例外) - 基本上{ {3}},但请查看最后的注释或添加到存储库中,基本上是git checkout
。
为了转换转换文件数据,Git必须知道哪些文件被转换和转换为应用。 Git必须对每个文件进行分类以决定要做什么。
有些文件显然是二进制文件,有些文件几乎肯定是文本文件,有些文件很模糊。 Git会猜测是否必须。您可以(我猜,或许,过去常常?)告诉通过设置core.autocrlf=true
或core.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=crlf
或eol=lf
。这使得转换成为可能,即,在决定是否在提取(git checkout
)和插入(git add
)时弄乱行结尾时,文件被视为文本。在工作树中结束的是CRLF或仅LF。在任何一种情况下,工作树中的CRLF在git add
期间仅用LF替换。我怀疑,但尚未测试,此不会影响git diff
。
(毫无疑问,旧的crlf
,-crlf
和crlf=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-filters
在git show
中完成或禁止。
答案 1 :(得分:0)
为text
文件取消设置.mm
会阻止git对它们进行crlf
次转换,但它不会开始将它们视为二进制文件,因此git-diff和其他功能将会仍然表现得很好。
* text=auto
*.mm -text
那应该解决你的第二个问题。但是,因为git不会强制执行.mm
文件的行结尾,所以当你上市并且贡献者开始在OS-X和Linux上修改它们时,它可能会引起一些麻烦。如果你可以描述.mm
行结尾的规则,也许可以调整配置,或者也许一个commit-hook可以帮助你强制执行它,除此之外我不知道如何解决你的第一个和第一个第二个问题同时出现。