我尝试使用以crlf结尾的行提交文件,但失败了。

我花了一整天的时间在我的Windows电脑上尝试不同的策略,几乎要停止尝试使用Git,而是尝试使用Mercurial。

如何正确处理CRLF行结束符?


当前回答

试着设定核心。自专制配置选项为true。还要看看核心。safecrlf选项。

实际上它听起来像核心。Safecrlf可能已经在你的存储库中设置了,因为(强调我的):

如果这不是当前设置的核心的情况。专制者,git将拒绝文件。

如果是这种情况,那么您可能需要检查您的文本编辑器是否配置为一致地使用行结束符。如果文本文件混合包含LF和CRLF行结束符,您可能会遇到问题。

最后,我觉得在Windows上简单地“使用您所给予的”和使用LF终止行的建议会导致比它解决的问题更多的问题。Git有上述选项来尝试以合理的方式处理行结束符,因此使用它们是有意义的。

其他回答

这只是一个变通的解决方案:

在正常情况下,使用git附带的解决方案。这些在大多数情况下都很有效。如果您通过设置.gitattributes在Windows和Unix系统上共享开发,则强制到LF。

以我为例,有10个程序员在Windows上开发一个项目。该项目与CRLF进行了核对,没有强制到LF的选项。

一些设置是在我的机器内部编写的,对LF格式没有任何影响;因此,在每次小文件更改时,一些文件被全局更改为LF。

我的解决方案:

windows机器: 让一切顺其自然吧。什么都不关心,因为你是一个默认的windows“独狼”开发人员,你必须处理这样的问题:“在这个广阔的世界上没有其他系统了,是吗?”

unix机器上

Add following lines to a config's [alias] section. This command lists all changed (i.e. modified/new) files: lc = "!f() { git status --porcelain \ | egrep -r \"^(\?| ).\*\\(.[a-zA-Z])*\" \ | cut -c 4- ; }; f " Convert all those changed files into dos format: unix2dos $(git lc) Optionally ... Create a git hook for this action to automate this process Use params and include it and modify the grep function to match only particular filenames, e.g.: ... | egrep -r "^(\?| ).*\.(txt|conf)" | ... Feel free to make it even more convenient by using an additional shortcut: c2dos = "!f() { unix2dos $(git lc) ; }; f " ... and fire the converted stuff by typing git c2dos

使用核心。当我在Visual Studio 2010项目中检出文件时,selflf =false会阻止所有文件被标记为更新。开发团队的另外两名成员也使用Windows系统,因此混合环境没有发挥作用,但存储库附带的默认设置总是将所有文件标记为克隆后立即更新。

我认为最重要的是找到适合您的环境的CRLF设置。特别是在我们的Linux盒子上的许多其他存储库中,设置selff = true会产生更好的结果。

20多年后,我们仍然在处理操作系统之间的行尾差异……伤心。

——UPDATE 3——(与UPDATE 2不冲突)

考虑到windows用户更喜欢在CRLF上工作,而linux/mac用户更喜欢在文本文件上使用LF。从存储库维护者的角度提供答案:

对我来说,最好的策略(要解决的问题较少)是:将所有文本文件与LF保存在git repo中,即使你正在开发一个仅支持windows的项目。然后让客户自由选择他们喜欢的行结束风格,前提是他们选择了一个核心。在为提交暂存文件时,该属性值将尊重您的策略(回购上的LF)。

分期是许多人在试图理解换行策略如何工作时所困惑的。在为core选择正确的值之前,有必要了解以下几点。autocrlf属性:

Adding a text file for commit (staging it) is like copying the file to another place inside .git/ sub-directory with converted line-endings (depending on core.autocrlf value on your client config). All this is done locally. setting core.autocrlf is like providing an answer to the question (exact same question on all OS): "Should git-client: a. convert LF-to-CRLF when checking-out (pulling) the repo changes from the remote? b. convert CRLF-to-LF when adding a file for commit?" and the possible answers (values) are: false: "do none of the above", input: "do only b" true: "do a and and b" note that there is NO "do only a"

幸运的是

Git客户端默认值(windows: core。linux/mac: 核心。selflf: false)将与LF-only-repo策略兼容。 含义:windows客户端在签出存储库时默认转换为CRLF,在添加提交时转换为LF。linux客户端默认情况下不进行任何转换。这理论上保持你的回购只有lf。

不幸的是:

可能有GUI客户端不尊重git核心。autocrlf价值 可能有些人不使用一个值来尊重你的lf-回购策略。例如,他们使用核心。selflf =false并添加一个带有CRLF的文件用于提交。

要检测上述客户端提交的ASAP非lf文本文件,您可以遵循——update 2——(git grep -I——files-with-matches——perl-regexp '\r' HEAD,在使用:with-libpcre标志编译的客户端上)

这里有个问题:。我作为一个回购维护者保持一个git。selflf =input,这样我就可以修复任何错误提交的文件,只需再次添加它们即可提交。我提供了一个提交文本:“修复错误提交的文件”。

至于.gitattributes。我不指望它,因为有更多的ui客户端不理解它。我只使用它来为文本和二进制文件提供提示,并可能标记一些异常文件,这些文件应该在任何地方保持相同的行尾:

*.java          text !eol # Don't do auto-detection. Treat as text (don't set any eol rule. use client's)
*.jpg           -text     # Don't do auto-detection. Treat as binary
*.sh            text eol=lf # Don't do auto-detection. Treat as text. Checkout and add with eol=lf
*.bat           text eol=crlf # Treat as text. Checkout and add with eol=crlf

问:但是我们为什么对换行处理策略感兴趣呢?

答:为了避免单个字母的更改提交,请显示为5000行更改,因为执行更改的客户端在添加提交之前自动将整个文件从crlf转换为lf(或相反)。当涉及到冲突解决时,这可能是相当痛苦的。或者在某些情况下,它可能是不合理冲突的原因。


——更新2——

git客户端的错误在大多数情况下都可以工作。即使你只有windows客户端,linux客户端或者两者都有。这些都是:

windows:核心。selflf =true表示在签出时将行转换为CRLF,在添加文件时将行转换为LF。 linux:核心。selflf =input意味着在签出时不转换行(不需要,因为文件预计将使用LF提交),并在添加文件时将行转换为LF(如果需要)。 (——update3——:默认情况下这似乎是假的,但这也是好的)

该属性可以在不同的作用域中设置。我建议显式地在——global范围内设置,以避免后面描述的一些IDE问题。

git config core.autocrlf
git config --global core.autocrlf
git config --system core.autocrlf
git config --local core.autocrlf
git config --show-origin core.autocrlf

此外,我强烈反对在windows上使用git配置全局核心。与git文档中建议的内容相反,自专制错误(如果你只有Windows客户端)。设置为false将在repo中使用CRLF提交文件。但真的没有理由。您永远不知道是否需要与linux用户共享项目。另外,对于每个加入项目的客户端来说,这是一个额外的步骤,而不是使用默认值。

现在对于一些特殊情况的文件(例如*.bat *.sh),你想用LF或CRLF签出它们,你可以使用.gitattributes

对我来说,最好的做法是:

Make sure that every non-binary file is committed with LF on git repo (default behaviour). Use this command to make sure that no files are committed with CRLF: git grep -I --files-with-matches --perl-regexp '\r' HEAD (Note: on windows clients works only through git-bash and on linux clients only if compiled using --with-libpcre in ./configure). If you find any such files by executing the above command, correct them. This in involves (at least on linux): set core.autocrlf=input (--- update 3 --) change the file revert the change(file is still shown as changed) commit it Use only the bare minimum .gitattributes Instruct the users to set the core.autocrlf described above to its default values. Do not count 100% on the presence of .gitattributes. git-clients of IDEs may ignore them or treat them differrently.

如前所述,一些东西可以添加到git属性中:

# Always checkout with LF
*.sh            text eol=lf
# Always checkout with CRLF
*.bat           text eol=crlf

我认为.gitattributes的其他安全选项,而不是对二进制文件使用自动检测:

-text(例如*.zip或*.jpg文件:不会被视为文本。因此不会尝试行结束转换。Diff可能通过转换程序实现) eol(例如,对于*.java,*.html:作为文本处理,但未设置eol样式首选项。所以使用客户端设置。) -text -diff -merge(例如*.)hugefile:不作为文本处理。没有差异/合并可能)

——之前的更新——

一个令人痛苦的客户端错误提交文件的例子:

netbeans 8.2(在windows上)会错误地使用crlf提交所有文本文件,除非你显式地设置了core。专制作为全球。这与标准的git客户端行为相矛盾,并在稍后更新/合并时导致许多问题。这就是为什么即使在还原时,某些文件也会显得不同(尽管它们并不是)。 即使您在项目中添加了正确的.gitattributes,在netbeans中也会发生相同的行为。

在提交后使用以下命令,至少可以帮助您及早检测git回购是否存在行结束问题

我花了几个小时来想出.gitattributes的最佳使用方法,最终意识到我不能指望它。 不幸的是,只要存在基于jgit的编辑器(它不能正确地处理.gitattributes),安全的解决方案就是在所有地方强制使用LF,即使是在编辑器级别。

使用以下抗crlf消毒剂。

Windows /linux客户端:core. selflf =input 提交。gitattributes: * text=auto eol=lf 提交的。editorconfig (http://editorconfig.org/),这是一种标准化的格式,结合编辑器插件: https://github.com/editorconfig/ https://github.com/welovecoding/editorconfig-netbeans/

试着设定核心。自专制配置选项为true。还要看看核心。safecrlf选项。

实际上它听起来像核心。Safecrlf可能已经在你的存储库中设置了,因为(强调我的):

如果这不是当前设置的核心的情况。专制者,git将拒绝文件。

如果是这种情况,那么您可能需要检查您的文本编辑器是否配置为一致地使用行结束符。如果文本文件混合包含LF和CRLF行结束符,您可能会遇到问题。

最后,我觉得在Windows上简单地“使用您所给予的”和使用LF终止行的建议会导致比它解决的问题更多的问题。Git有上述选项来尝试以合理的方式处理行结束符,因此使用它们是有意义的。

不要转换行结束符。VCS的工作不是解释数据——只是存储和版本它。每个现代文本编辑器都可以读取这两种行尾。