git用CRLF替换LF


838

使用bash在Windows XP计算机上运行git。我从SVN导出了我的项目,然后克隆了一个裸仓库。

然后,我将导出粘贴到裸仓库目录中,并执行以下操作:

git add -A

然后,我得到了一条消息列表:

LF将被CRLF取代

这种转换的后果是什么?这是Visual Studio中的.NET解决方案。


14
@apphacker,因为标准化行尾比在比较两个文件时不必自己更改它们要麻烦。(当然,如果您不同意,则可以关闭core.autocrlf功能)。
RJFalconer

2
除非整个行都被触及,否则行尾为何会有所不同
Bjorn

3
我经常碰到很多行,因为我正在尝试不同的想法,添加跟踪语句以查看其工作原理,等等。然后,我可能只想对两三行进行更改,而git完全忽略其他行,因为我以我找到它们的方式将它们放回原处(或因此认为)。
MatrixFrog

5
@MatrixFrog:您的编辑器似乎坏了,无法自动检测行尾。哪有 我在混合项目中工作,该项目必须在同一存储库中包含一些LF文件和一些其他CRLF文件。对于任何现代编辑者来说都不是问题。使版本控制(或文件传输)与行尾混淆以解决编辑器限制是有史以来最糟糕的想法-从下面的简短解释中可以明显看出。
MarcH 2014年

4
我所知道的唯一做错事情的现代编辑器是Visual Studio。Visual Studio将愉快地打开带有LF行尾的文件。如果您随后插入新行,它将插入CRLF,并保存混合的行尾。微软拒绝修复此问题,这在其他方面还不错的IDE上是一个很大的缺陷:-(
乔恩·瓦特

Answers:


954

这些消息是由于core.autocrlfWindows上的默认值不正确所致。

的概念autocrlf是透明地处理行尾的转换。确实如此!

坏消息:价值需要手动配置。
好消息:每次git安装一次只能完成一次(也可以按项目设置)。

如何autocrlf工作

core.autocrlf=true:      core.autocrlf=input:     core.autocrlf=false:

        repo                     repo                     repo
      ^      V                 ^      V                 ^      V
     /        \               /        \               /        \
crlf->lf    lf->crlf     crlf->lf       \             /          \      
   /            \           /            \           /            \

这里crlf= Win风格的行尾标记,lf= Unix风格(和Mac OSX)。

(pre-osx cr不受以上三个选项影响)

何时显示此警告(在Windows下)

    – autocrlf= true如果您lf的文件之一具有unix样式(=很少),
    – autocrlf= input如果您的文件之一具有winn 样式crlf(=几乎总是),
    – autocrlf= false–绝不!

这个警告是什么意思

警告“ LF将被CRLF替换 ”表示您(具有autocrlf= true)将在提交检出周期后丢失unix样式的LF(它将被Windows样式的CRLF替换)。Git不希望您在Windows下使用Unix风格的LF。

警告“ CRLF将被LF取代 ”表示您(具有autocrlf= input)将在提交检出周期后丢失Windows风格的CRLF(它将被unix风格的LF取代)。不要input在Windows下使用。

展示autocrlf工作原理的另一种方式

1) true:             x -> LF -> CRLF
2) input:            x -> LF -> LF
3) false:            x -> x -> x

其中x是CRLF(Windows风格)或LF(unix风格),箭头表示

file to commit -> repository -> checked out file

怎么修

core.autocrlfgit的默认值是在git安装期间选择的,并存储在系统范围内的gitconfig(%ProgramFiles(x86)%\git\etc\gitconfig)中。也有(按以下顺序层叠):

   - “全球”(每用户)gitconfig位于~/.gitconfig,另一个
   - “全球”(每用户)在gitconfig $XDG_CONFIG_HOME/git/config$HOME/.config/git/config
   - “本地”(每回购)gitconfig在.git/config在工作目录。

因此,写入git config core.autocrlf工作目录以检查当前使用的值并

   –添加autocrlf=false到系统范围内的gitconfig#每个系统解决方案
   – git config --global core.autocrlf false            #每个用户解决方案
   – git config --local core.autocrlf false              #每个项目解决方案

警告
git config设置可以被gitattributes设置覆盖。
crlf -> lf转换仅在添加新文件时发生,crlf回购中已经存在的文件不受影响。

道德(适用于Windows):
    -使用core.autocrlf= true如果您计划使用该项目在Unix下,以及(和不愿配置编辑器/ IDE使用Unix行结尾),
    -使用core.autocrlf= false如果你打算只(使用这个项目在Windows下或者您已将您的编辑器/ IDE配置为使用Unix行尾),
    - 除非您有充分的理由(例如,如果您在Windows下使用Unix实用程序,或者遇到makefiles问题),请不要使用core.autocrlf= ,input

PS 为Windows安装git时要选择什么?
如果您不打算在Unix下使用任何项目,请不要同意默认的第一个选项。选择第三个(按原样签出,按原样提交)。您不会看到此消息。曾经

PPS我个人的喜好是将编辑器/ IDE配置为使用Unix样式的结尾,并设置core.autocrlffalse


28
对于我花了很多时间才能达到的目标,我一直希望有一个core.crlf = rackoff ;-)
PandaWood 2014年

10
我重组了内容,也许这样阅读起来会更容易
Antony Hatchkins 2014年

7
抱歉,我希望我的评论不被视为对您答案的批评。“达到目标”是指在找到此答案之前。
PandaWood

10
这真令人困惑。我在编辑器中设置了低频。所有的回购代码都使用LF。全局autocrlf设置为false,而我的主目录中的核心gitconfig设置为false。但我仍然收到消息LF被CRLF取代
isimmons

17
如果已将编辑器配置为使用Unix样式结尾,为什么不设置core.autocrlf为input?根据我从您的答案中收集到的信息,将其设置为输入可确保存储库和工作目录始终具有unix样式的行尾。为什么您在Windows中永远都不想这么做?
Hubro 2014年

763

Git有三种处理行尾的方式:

$ git config core.autocrlf
# that command will print "true" or "false" or "input"

您可以通过在上面的命令行中添加true或的附加参数来设置要使用的模式false

如果core.autocrlf设置为true,则意味着您每次将文件添加到git认为是文本文件的git repo中时,都会将所有CRLF行尾都变为LF,然后再将其存储在提交中。无论何时git checkout,所有文本文件都会自动将其LF行结尾转换为CRLF结尾。这允许跨平台开发使用不同行尾样式的项目,而不会造成很大的干扰,因为每个编辑者都会更改行尾样式,因为行尾样式始终是LF。

这种便捷转换的副作用是警告,它的意思是,如果您最初编写的文本文件以LF结尾而不是CRLF,它将照常与LF一起存储,但是在选中时以后将有CRLF结尾。对于普通的文本文件,通常就可以了。在这种情况下,警告是“仅供参考”,但是如果git错误地将二进制文件评估为文本文件,则这是重要的警告,因为git会破坏您的二进制文件。

如果core.autocrlf设置为false,则不会执行任何行尾转换,因此将按原样检查文本文件。只要您所有的开发人员都在Linux上或全部在Windows上,这通常都可以。但是根据我的经验,我仍然倾向于获得文本文件,这些文件的行尾混合在一起,最终导致出现问题。

我个人的喜好是将设置保留为Windows开发人员的状态。

有关包含“输入”值的更新信息,请参见http://kernel.org/pub/software/scm/git/docs/git-config.html


116
如此处所述(stackoverflow.com/questions/1249932/…),我谨对此表示不同意,并将该设置保留为OFF(并使用Notepad ++或任何其他能够处理-并保留-结束线字符的编辑器)它发现)
VonC

23
我喜欢这个答案,更喜欢将autocrlf设置为true。作为替代,是否有一种方法可以自动取消警告消息?
克里斯(Krisc)2011年

12
通过与core.eol设置进行比较(也许与.gitattributes配置相结合)来增加这个写得很好的答案会很好。我一直在尝试通过实验找出差异和重叠之处,这非常令人困惑。
SEH

5
要获得更永久的解决方案,请将您的.gitconfig更改为:[core] autocrlf = false
RBZ

9
有什么简单的方法可以抑制警告?我希望它为true,并且知道我已将其设置为true。我不需要一直看到所有警告...没关系,真的...:p
UmaN 2013年

158

如果您已签出代码,则文件已被索引。更改git设置后,请运行以下命令:

git config --global core.autocrlf input 

你应该用刷新索引

git rm --cached -r . 

然后用重写git index

git reset --hard

https://help.github.com/articles/dealing-with-line-endings/#refreshing-a-repository-after-changing-line-endings

注意:这将删除您的本地更改,请考虑在执行此操作之前将其存储。


23
感谢您使用简单,跨平台的清晰方法修复它,而不是对配置含义进行大量讨论。
伊里斯(Eris)

2
如果git reset --hard我的本地更改是否有可能丢失?我只是按照上面的所有评论提法
Freddy Sidauruk

5
是的,您的本地更改将丢失。--hard参数将重置索引和工作树,因此对跟踪文件的任何更改都将被丢弃。git-scm.com/docs/git-reset
Jacques

2
是什么意思git rm --cached -r .?为什么git reset --hard还不够?
gotnkoa

2
@gavenkoa @max git rm --cached -r .如果git reset --hard更改core.autocrlf设置后需要这样做,它将不会重新转换行尾。您需要清理git索引。
wisbucky

79
git config core.autocrlf false

6
确保在存储库根目录中运行此文件
Hammad Khan 2014年

23
我不知道这有什么用。一半的人要求autocrlf为真才能工作,另一半则要求为false / input。那么,他们应该将这些一次性的答案随机地扔到他们的控制台墙上,直到有东西粘住并分类为“作品”吗?这没有生产力。
佐兰·帕夫洛维奇

我收到错误消息:“致命:不在git目录中”。我尝试将CD
刻录

2
@mbb设置autcrlffalse这个问题只是平底船到项目的每个用户。
jpaugh

5
@pixelwiz:此命令仅为项目设置属性(因此您需要在git存储库下运行它)。如果要全局设置,请git config --global core.autocrlf false改用。
迈克尔Polla

48

两个unix2dosDOS2UNIX的是与gitbash窗口可用。您可以使用以下命令执行UNIX(LF)-> DOS(CRLF)转换。因此,您将不会收到警告。

unix2dos filename

要么

dos2unix -D filename

但是,请不要在任何现有的CRLF文件上运行此命令,否则每隔两行都会得到空的换行符。

dos2unix -D filename不适用于所有操作系统。请检查此链接的兼容性。

如果由于某种原因需要强制执行命令,请使用--force。如果显示无效,则使用-f


8
它有什么作用?
Salman von Abbas

1
这是帮助选项的内容:`--u2d,-D执行UNIX-> DOS转换`
Larry Battle

1
@Rifat我很困惑。您的评论说,这dos2unix -D会将Windows行尾转换为linux行尾。与DOS(CRLF)-> UNIX(LF)转换不同吗?但是dos2unix -h-D将执行UNIX(LF)-> DOS(CRLF)转换的状态。dos2unix更多信息: gopherproxy.meulie.net/sdf.org/0/users/pmyshkin/dos2unix
Larry Battle

1
@LarryBattle是的,您对-D是正确的。实际上,我是Windows用户时发布了答案。而且,一年多以后,当我是Mac用户:D BTW时,我发表了评论,谢谢您的澄清。
里法特

1
这对我有用。我正在使用Cygwin,它似乎不支持-D开关-但是有一个“ unix2dos”命令,它执行相同的操作。我希望我知道导致问题的原因-我有core.autocrlf = false,它是仅Windows的存储库。
理查德·拜尔

27

我认为@Basiloungas的答案很接近,但已经过时了(至少在Mac上如此)。

打开〜/ .gitconfig文件并将其设置safecrlf为false

[core]
       autocrlf = input
       safecrlf = false

*显然会使它忽略char的结尾(无论如何对我来说还是有用的)。


1
应该是safecrlf(带有“ f”)
alpipego,

21

一个GitHub的就行结束文章谈论这个话题时,通常提及。

我在使用经常推荐的core.autocrlf配置设置时的个人经历非常复杂。

我将Windows与Cygwin一起使用,在不同时间处理Windows和UNIX项目。即使是我的Windows项目,有时也使用bash需要UNIX(LF)行尾的shell脚本。

使用GitHub推荐core.autocrlf的Windows设置,如果我签出UNIX项目(在Cygwin上确实能很好地工作-或者我正在为我在Linux服务器上使用的项目做贡献),则文本文件将通过Windows(CRLF)签出。 )行尾,会产生问题。

基本上,对于像我这样的混合环境,core.autocrlf在某些情况下将global设置为任何选项都无法正常工作。可以在本地(存储库)git config上设置此选项,但是对于同时包含与Windows和UNIX相关的内容的项目(例如,我有一个带有一些bash实用程序脚本的Windows项目),这甚至还不够好。

我发现最好的选择是创建每个存储库的.gitattributes文件。在GitHub的文章提到它。
该文章的示例:

# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

在我的项目的存储库之一中:

* text=auto

*.txt         text eol=lf
*.xml         text eol=lf
*.json        text eol=lf
*.properties  text eol=lf
*.conf        text eol=lf

*.awk  text eol=lf
*.sed  text eol=lf
*.sh   text eol=lf

*.png  binary
*.jpg  binary

*.p12  binary

设置起来还有很多事情,但是每个项目要做一次,并且任何OS上的任何贡献者在使用该项目时都不会遇到行尾的麻烦。


现在运行此操作,尝试使用Cygwin脚本以及其他基本文本文件来管理存储库。您将如何处理没有扩展名的文件(例如“ fstab”,“ sshd_config”)?链接的文章没有涵盖这种情况。
Mike Loux

1
@MikeLoux请尝试以下方法:stackoverflow.com/a/44806034/4377192
Gene Pavlovsky

我发现它的text=false eol=false工作方式与相似binary。听起来对吗?指出“我知道这些是文本文件,但我不希望对其进行规范化”可能会很有用
joeytwiddle

18

在vim中打开文件(例如:):e YOURFILEENTER,然后

:set noendofline binary
:wq

2
只需使用进行编辑,vim所有行尾都将保持完整。
Eye

我在某些Cocoapods文件中遇到了这个问题。以上解决了大多数问题;其余的,s / {control-v} {control-m} //完成了。这两个控制代码共同构成了^ M,这是我们OS X上的我们经常在Windows文件中看到的。
janineanne

14

我也有这个问题。

SVN不执行任何行尾转换,因此在提交时应完整保留CRLF行尾。如果您随后使用git-svn将项目放入git,则CRLF结尾将一直保留到git存储库中,这不是git期望进入的状态-默认状态是仅具有unix / linux(LF)行结尾入住。

然后,当您在Windows上签出文件时,autocrlf转换会使文件保持原样(因为它们已经具有当前平台的正确结尾),但是决定签入文件是否存在差异的过程将执行反向转换。比较之前,将检出的文件中的LF与存储库中的意外CRLF进行比较。

据我所知,您的选择是:

  1. 在不使用git-svn的情况下将代码重新导入到新的git存储库中,这意味着行尾在初始git commit --all中进行了转换
  2. 将autocrlf设置为false,并忽略行尾不是git首选样式的事实
  3. 停用autocrlf即可检出文件,修复所有行尾,重新检入所有内容,然后重新打开。
  4. 重写存储库的历史记录,以使原始提交不再包含git不需要的CRLF。(有关历史记录重写的一般注意事项适用)

脚注:如果选择选项#2,则我的经验是某些辅助工具(变基,修补程序等)无法处理CRLF文件,并且您迟早会使用CRLF和LF混合文件(行不一致)结局)。我不知道如何同时兼顾两者。


2
我认为有一个第四种方法可以添加到列表中,假设您有能力重写历史记录:您可以使用最初使用git-svn创建的git repo,然后重写其历史记录以不再具有CRLF换行符。这将使您在整个svn历史记录中向后延伸的标准化换行符。用户keo在stackoverflow.com/a/1060828/64257上提出了一种解决方案。
克里斯

关于您的脚注:rebaseCRLF没问题。我知道的唯一问题是标准git merge工具将仅使用LF插入其冲突标记(“ <<<<<<”,“ >>>>>>”等),因此带有冲突标记的文件将具有混合的行尾。但是,一旦删除标记,一切都会好起来。
sleske 2013年

在过去的三年中,git的处理方式可能发生了变化,这是我当时的直接经验,从那时起,我就无需再讨论此特定问题了。嗯
蒂姆·阿贝尔2014年

1
@sleske从git 2.8开始,合并标记将不再引入混合行结尾。参见stackoverflow.com/a/35474954/6309
VonC

@VonC:太酷了。很高兴知道我需要在Windows上工作的时间。
sleske '16

11

从〜/ .gitattributes文件中删除以下内容

* text=auto

将阻止git首先检查行尾。


6
不正确 该行(如果存在)将覆盖 core.autocrlf的配置。如果将其设置为“ true”,则否,删除该行不会阻止git检查行尾。
Arafangion

1
尽管如此,如果将core.autocrlf设置为false,如果不删除该选项,将autocrlf设置为false不会有太大帮助,所以这一点对我有帮助(但仅靠它是不够的)。
马蒂2015年

2
赞这个!!虽然“将阻止git检查”部分在技术上不正确,但这是唯一专门提及text=设置的唯一答案.gitattributes(如果存在,它将成为阻止程序)。因此,其他答案是不完整的。我正想坚果试图找出为什么我的文件继续显示为“改性”不管多少次,我改变了我autocrlf,并safecrlf设置和检查了与清除的git缓存和硬复位。
jdunk

9

它应显示为:

警告:(如果您将其检出/或克隆到当前core.autocrlf为的另一个文件夹true,)LF将替换为CRLF

该文件将在您的(当前)工作目录中具有其原始行结尾。

该图片应说明其含义。 在此处输入图片说明


这也意味着发送到Subversion的内容(如果您这样做的话)将进行转换。
jpaugh

9

http://www.rtuin.nl/2013/02/how-to-make-git-ignore-different-line-endings/

echo "* -crlf" > .gitattributes 

在单独的提交上执行此操作,或者在进行单个更改时git仍可能会看到整个文件已被修改(取决于您是否更改了autocrlf选项)

这确实有效。Git将尊重混合行尾项目中的行尾,并且不会向您发出警告。


2
当您要在CRLF和LF之间进行转换,但是您有几个必须完整的.sh文件时,此功能特别有用。我*.sh -crlf一直都在用...
MartinTeeVarga 2015年

8

我对Windows上的git不太了解,但是...

在我看来,git正在转换返回格式以匹配运行平台(Windows)的格式。在Windows中,CRLF是默认的返回格式,而在大多数其他OS中,LF是默认的返回格式。

将代码移至另一个系统时,返回格式可能会适当调整。我还认为git足够聪明,可以保持二进制文件完整,而不是尝试将LF转换为JPEG格式的CRLF。

总而言之,您可能不需要为此转换而烦恼。但是,如果您将项目存档为tarball,则其他编码人员可能会更喜欢使用LF行终止符而不是CRLF。根据您的关心程度(并且取决于您是否不使用记事本),如果可以的话,您可能希望将git设置为使用LF返回:

附录:CR是ASCII码13,LF是ASCII码10。因此,CRLF是两个字节,而LF是1。


5
由于似乎没有人说过,CR代表“回车”,LF代表“换行”。作为第二个注意事项,许多Windows编辑器都将以LF字符表示换行符的文本文件静默更改为文本对CRLF。编辑器的用户甚至都不会受到警告,但是Git会看到更改。
user2548343 2015年

6

确保您已经安装了最新的git。当使用git(版本2.7.1)时,
我按照上述方法进行操作git config core.autocrlf false,但是没有用。
然后,当升级git(从2.7.1到2.20.1)时,它现在可以工作。


我认为您的意思是您拥有git 2.17.1。我遇到了同样的问题,并做了更新,这也解决了它。很高兴看到您的回答!
菲利普·麦克穆伦

4
  1. 在记事本++中打开文件。
  2. 转到编辑/终止转换。
  3. 单击以Windows格式。
  4. 保存文件。

1
也可以尝试使用git config --global core.autocrlf false来防止Git Unix在提交时将行尾设置为。跟进git config core.autocrlf检查是否确实将其设置为false。
Contango

4

OP的问题是与Windows有关的,由于管理员无法正常工作,我无法使用其他文件夹而不去目录甚至无法在Notepad ++中运行文件。

C:\Program Files (x86)\Git\etc>git config --global core.autocrlf false

2

许多文本编辑器允许您更改为LF,请参见下面的Atom说明。简单明了。


点击CRLF右下角:

在此处输入图片说明

LF在顶部的下拉菜单中选择:

在此处输入图片说明


1

在GNU / Linux shell提示符下,dos2unix和unix2dos命令使您可以轻松地转换/格式化来自MS Windows的文件


1

在两个不同的操作系统(Linux和Windows)中使用“代码”时,CRLF可能会引起一些问题。我的python脚本是用Linux docker容器编写的,然后使用Windows git-bash推送。它给了我警告,LF将被CRLF取代。我没有想太多,但是后来我启动脚本时说/usr/bin/env: 'python\r': No such file or directory。现在\r为您带来后果。Windows使用'CR'-回车符-在'\ n'顶部作为换行符- \n\r。您可能需要考虑这一点。


0

Windows中的大多数工具仅在文本文件中接受LF。例如,您可以使用以下示例内容(部分)在名为“ .editorconfig”的文件中控制Visual Studio的行为:

 indent_style = space
 indent_size = 2
 end_of_line = lf    <<====
 charset = utf-8

只有原始的Windows记事本不能与LF一起使用,但是有一些更合适的简单编辑器工具可用!

因此,您也应该在Windows的文本文件中使用LF。这是我的信息,强烈建议!没有理由在Windows中使用CRLF!

(相同的讨论是在C / ++中的include路径中使用\,这是胡说八道,使用#include <pathTo / myheader.h>加上斜杠!,它是C / ++标准,所有Microsoft编译器都支持它)。

因此git的正确设置是

git config core.autocrlf false

我的信息:忘记dos2unix和unix2dos之类的旧思想程序。在您的团队中确认LF适合在Windows下使用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.