禁用 git EOL 转换
Posted
技术标签:
【中文标题】禁用 git EOL 转换【英文标题】:Disable git EOL Conversions 【发布时间】:2014-03-16 08:52:03 【问题描述】:我试图让 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
添加遥控器
在包含 CRLF 的存储库中创建一个新文件 document.txt
提交:git add -A
,然后是git commit -m "<something>"
请注意,A 的 document.txt
仍然包含 CRLF(删除它并使用 --hard
重置会返回仍然带有 CRLF 的版本)
SCP 整个目录到计算机 B 添加一个包含 CRLF 的新文件
new file
提交:git add -A
,然后是git commit -m "<something>"
请注意,B 的 document.txt
和 B 的 new file
仍然包含 CRLF
将B的master拉到A:
git pull <remote> master:master_recv
A 的 document.txt
已更改为 LF。添加的文件new file
也包含LF。
如果 B 是 Windows 机器,则不会出现此问题。
【问题讨论】:
core.autocrlf
总是 是假的吗?听起来您的存储库中已经有 \n
行尾? no 设置可将存储库中的 \n
更改为工作目录中的 \r\n
。
它并不总是被设置(例如最初创建 repo 时)。但是,回购中不应该有任何 CR 行结尾。此外,我再次希望发生任何变化。
我问是因为您的设置应该将您的行尾保留为 CRLF。您能否在您的存储库中发布一些文件和它的对象 ID 只是为了我(诚然可能很烦人)的启迪?
@EdwardThomson 你是什么意思?回购不是公开的(因为 Linux 机器不是)。我假设你想要一个示例文件。见编辑。
是的,我同意该文件具有 CRLF 行结尾。您能否澄清一件事:您提到“windows 机器的换行符更改为 CR!”这肯定是一个错字,还是你真的得到了 Mac OS 9 风格的回车行结尾?
【参考方案1】:
一个简单的解决方案是:
确保 all 存储库的 core.autocrlf 设置为 false:git config --global core.autocrlf false
Git 2.16 (Q1 2018) and above,运行git add --renormalize .
否则,请重新克隆您的存储库,并检查没有完成 EOL 转换。
如果有自动完成的转换,这意味着一个 .gitattributes
core.eol
directive 在 repo 中。
用Git 2.8+ (March 2016),检查是否还有eol转换用:
git ls-files --eol
【讨论】:
今天不要使用autocrlf
!未设置的autocrlf
等同于false
。你落后于 Git 的流行趋势
和上面一样,我试过这个(虽然没有使用全局标志),但它没有用。 git 版本是1.8.5.2
。
@IanMallett "此时,Linux 机器似乎仍然有 CRLF":它会直到你重新规范化它的内容,或者克隆它(就像你在 windows 上所做的那样)
如果你只想为一个 repo 做这个,那么只需运行git config core.autocrlf false
- 提到这一点,因为通常 autocrlf 对于 windows 应该是 true
对于其他人来说应该是 input
,但有时你需要特定于奇怪的边缘情况的东西。就我而言,我已经下载了一些文件并想记录我所做的更改,以便我可以记住我做了什么(而不是跟踪对代码的更改)。我不知道行尾是否重要(并且希望差异对“真实”的东西有意义)所以我禁用了 autocrlf。【参考方案2】:
来自gitattributes(5) Manual Page“效果”话题
text
此属性启用和控制行尾标准化。当一个 文本文件被规范化,它的行尾在 存储库。控制工作中使用的行尾样式 目录,对单个文件使用
eol
属性和core.eol
所有文本文件的配置变量。
Set
在路径上设置文本属性可启用行尾规范化 并将路径标记为文本文件。发生行尾转换 无需猜测内容类型。
Unset
取消设置路径上的文本属性告诉 Git 不要 在签入或结帐时尝试任何行尾转换。
core.autocrlf
在新(1.7.2+)Git 中未使用,core.eol
和正确设置|取消设置文本属性被认为是更可靠的方式
【讨论】:
在.gitattributes
文件中,我已经明确禁用了所有文本,对吧?另外,我没有看到它有一个选项可以让它不进行转换(尽管crlf
可能没有效果)?
经常混淆的重要事情 - 取消设置 text
并防止任何转换,您应该将 .gitattributes 设置为 * -text
而不是 * text=false
。 false
不是 text
属性的有效值 - git 不会识别它,而是会回退到其默认的 autocrlf 设置。此外,在更改 text
值后,您必须从本地存储库备份所有文件,进行提交,然后根据需要使用正确的行尾恢复文件,然后将它们提交回来。这样你的行尾就不会再被 git 修改了。【参考方案3】:
我想通了。似乎 SCP 程序正在转换行尾。当我尝试故意制作一个以 LF 结尾的文件然后观察它在下载时显示为 CRLF 时,我注意到了这一点。
因为这对我来说是解决方案,所以我接受这个答案,但未来的人也应该参考其他答案以获得更通用的解决方案。
【讨论】:
很好,比我的回答更具体。 +1【参考方案4】:在您的项目中,应该有一个.gitattributes
文件。大多数时候,它应该如下所示(或screen-shot):
# 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
以禁用自动处理(请参阅screen-shot)。
像这样:
如果您的项目没有 .gitattributes 文件,则行尾由您的 git 配置设置。要更改您的 git 配置,请执行以下操作:
进入该目录下的配置文件:
1) C:\ProgramData\Git\config
2) 在 Notepad++(或任何你喜欢的文本编辑器)中打开配置文件
3) 将“autocrlf=”更改为 false。
【讨论】:
为什么使用图片而不是代码标签?很不方便 因为我可以在图片中添加一个大红框来突出显示内容。 使用* text=false
不会取消设置文本:它会将文本设置为字符串值 false。这与未指定文本(不是特别未设置)具有相同的效果。使用* -text
为其提供了特殊的未设置设置。取消设置路径上的文本属性告诉 git 在签入或签出时不要尝试任何行尾转换。
很抱歉,我不能对这个答案表示感谢。我花了半天时间才发现有人听从了误导性的建议。正如@JustAMartin 指出的* text=false
没有效果。请修正答案!
这个答案不正确。正如下面@JustAMartin 和上述评论部分所指出的,您必须使用* -text
和not * text=false
。在这个答案确定之前,我已经投了反对票。请修正这个答案。【参考方案5】:
以下是您如何为单个 repo 执行此操作。
在 repo 的根目录下创建文件.gitattributes
,并在其中包含这一行
* -text
就是这样。这是一个匹配所有文件的通配符,告诉 git 取消设置 text 属性。这意味着 git 将所有文件视为二进制文件,因此不执行任何行尾转换。
【讨论】:
以上是关于禁用 git EOL 转换的主要内容,如果未能解决你的问题,请参考以下文章