禁用git EOL转换


100

我试图让git不更改任何操作的任何行尾。不幸的是,这似乎无关紧要。我将其简化为以下测试案例,该案例具有我发现的多种禁用此行为的机制。


  • 从两台机器开始(Windows计算机= A,Linux计算机= B)
  • 在两台机器上: git config --global core.autocrlf false
  • 在两台机器上:(git config --global core.eol crlf以防万一)

  • 在A上新建存储库。从一个空文件夹中:
    • git init --shared(然后取消隐藏创建的.git目录)
    • .gitignore在存储库中创建一个新文件
    • .gitattributes用单行在存储库中创建一个新文件:* -text
    • git add .,然后再git commit -m "initial commit"解决,例如this
    • git branch master_recv
    • 添加遥控器
  • document.txt在包含CRLF的存储库中制作一个新文件
  • 提交:git add -A,然后git commit -m "<something>"
  • 请注意,A document.txt仍然包含CRLF(并删除它并用重置会--hard返回仍使用CRLF的版本)

  • SCP将整个目录保存到计算机B
  • 添加一个new file包含CRLF 的新文件
  • 提交:git add -A,然后git commit -m "<something>"
  • 请注意,B document.txt和B new file都仍包含CRLF

  • 将B的主人拉到A: git pull <remote> master:master_recv
  • A document.txt已更改为LF。添加的文件new file还包含LF。

如果B是Windows计算机,则不会发生此问题。


一直core.autocrlf 一直以来假的?听起来\n您的存储库中已经有行尾了吗?有没有设置来改变\n在你的仓库到\r\n你的工作目录。
爱德华·汤姆森

并非总是设置它(例如,最初创建存储库时)。但是,回购中不应已经有任何CR行结尾。同样,我也不希望任何更改发生。
imallett 2014年

我问是因为您的设置应将行尾保留为CRLF。您是否可以将某些文件及其对象ID 发布到您的存储库中以供我(很可能很烦人)教ification?
爱德华·汤姆森2014年

@EdwardThomson你是什么意思?该仓库不是公开的(因为Linux机器不是公开的)。我假设您想要一个示例文件。参见编辑。
imallett 2014年

是的,我同意该文件具有CRLF行尾。您能否澄清一件事:您提到“ Windows机器的换行符更改为CR!”。这肯定是一个错字,还是您真的得到Mac OS 9风格的回车线结尾吗?
爱德华·汤姆森

Answers:


74

在您的项目中,应该有一个.gitattributes文件。在大多数情况下,它看起来应该如下图所示(或此屏幕截图):

# Handle line endings automatically for files detected as text 
# and leave all files detected as binary untouched.
* text=auto

# Never modify line endings of our bash scripts
*.sh -crlf

#
# The above will handle all files NOT found below
#
# These files are text and should be normalized (Convert crlf => lf)
*.css           text
*.html          text
*.java          text
*.js            text
*.json          text
*.properties    text
*.txt           text
*.xml           text

# These files are binary and should be left untouched
# (binary is macro for -text -diff)
*.class         binary
*.jar           binary
*.gif           binary
*.jpg           binary
*.png           binary

更改* text=auto* text=false以禁用自动处理(请参阅截屏)。

像这样:

在此处输入图片说明

如果您的项目没有.gitattributes文件,则行尾由git配置设置。要更改您的git配置,请执行以下操作:

转到此目录中的配置文件:

1)C:\ ProgramData \ Git \ config

2)在Notepad ++(或您喜欢的任何文本编辑器)中打开配置文件

3)将“ autocrlf =”更改为false。

在此处输入图片说明


31
为什么使用图片代替代码标签?非常不便
克林特(Clint)

31
因为我可以在图片中添加一个大红色框以突出显示内容。
基因

21
使用* text=false不会取消设置文本:它将文本设置为字符串值false。这与保留未指定文本(未明确设置)的效果相同。使用* -text为它提供特殊的未设置。在路径上未设置text属性会告诉git在签入或签出时不要尝试任何行尾转换。
JustAMartin

谢谢@Gene的回答。这使我整日发疯,而这个为我解决了!
LeopardSkinPillBoxHat

7
对不起,我不能对这个答案表示感谢。我花了半天时间才发现有人遵循了误导性的建议。正如@JustAMartin所指出的那样,* text=false它没有效果。请修正答案!
Paul B.

47

一种简单的解决方案是:

  • 确保将所有存储库的core.autocrlf设置为false :
    git config --global core.autocrlf false
  • 重新克隆您的仓库,并检查是否没有EOL转换完成。
  • 或者,自Git 2.16(Q1 2018)起,保留当前的回购,然后执行git add --renormalize .

如果有自动完成的转换,则表示存储库中存在.gitattributes core.eol指令

使用Git 2.8+(2016年3月),检查是否仍然存在以下eol转换:

git ls-files --eol

2
就是autocrlf今天不用!未设置autocrlf等效于false。您落后于Git的潮流运动
Lazy Badger 2014年

1
如上所述,我已经尝试过了(尽管没有使用全局标志),但是它没有用。git版本是1.8.5.2
imallett 2014年

@IanMallett“这时,Linux机器似乎仍然具有CRLF”:它将直到您重新规范其内容或对其进行克隆(就像在Windows上一样)
VonC 2014年

11

我想到了。SCP程序似乎正在转换行尾。当我尝试故意制作带有LF结尾的文件,然后观察它在下载时显示为CRLF时,我注意到了这一点。

由于这是我的解决方案,因此我接受此答案,但是将来的人们也应该参考其他答案以获取更通用的解决方案。


1
好收获,比我的回答更具体。+1
VonC

4

摘自gitattributes(5)手册页 “效果”主题

text

此属性启用并控制行尾规范化。对文本文件进行规范化后,其行尾将在存储库中转换为LF。要控制在工作目录中使用哪种行尾样式,请eol对单个文件使用属性,core.eol 对所有文本文件使用配置变量。

Set

在路径上设置text属性可启用行尾规范化并将路径标记为文本文件。行尾转换不会猜测内容类型。

Unset 在路径上取消设置text属性会告诉Git在签入或签出时不要尝试任何行尾转换。

core.autocrlf在新版本(1.7.2+)中未使用Git,core.eol而将文本属性的正确设置视为更可靠的方法


.gitattributes文件中,我已明确禁用所有内容为文本,对吗?另外,我看不到带有不进行转换的选项(尽管crlf可能没有效果)吗?
imallett 2014年

6
经常混淆的重要事项-要取消设置text并阻止任何转换,应将.gitattributes设置为* -text 而不是* text=falsefalse不是text属性的有效值-git无法识别该属性,而是会恢复为默认的autocrlf设置。另外,更改text值后,您必须从本地存储库备份所有文件,进行提交,然后根据需要使用正确的行尾还原文件,然后将其提交回来。这样您的行尾将不再被git修改。
JustAMartin19年
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.