Git换行符问题根源在于core.autocrlf跨平台默认行为不一致,唯一可靠解法是用.gitattributes按文件类型精准声明换行策略,禁用core.autocrlf并明确标记二进制文件。

Git为什么在Windows和Mac/Linux上自动改换行符
因为Git默认开启core.autocrlf,但它在不同系统上的默认行为不一致:Windows默认设为true(检出时转CRLF,提交时转LF),Mac/Linux默认是input(只在提交时转LF,检出不动),而Linux新手常误设成true导致文件被莫名修改。
常见错误现象:git status 显示一堆“modified”但git diff 看不出内容变化;CI构建失败提示“invalid byte sequence”或“^M”残留;协作时别人一提交,你的编辑器就标红一堆换行符。
- 别信“Git会自己搞定”——它只是按配置机械转换,不是智能识别文本类型
-
.gitattributes的规则优先级高于core.autocrlf,但很多人根本没配它 - 二进制文件(如
.png、.zip)一旦被当成文本转了换行符,就直接损坏
怎么用.gitattributes精准控制换行符
这是唯一靠谱的跨平台方案:把换行策略声明写进项目根目录的.gitattributes文件,Git会按文件后缀逐个处理,不依赖系统默认设置。
使用场景:团队混用Windows和Mac开发;项目含脚本(.sh)、配置(.yml)、代码(.py、.js)等多种文本文件;需要保证CI环境和本地行为一致。
- 必须放在仓库根目录,且要先
git add .gitattributes提交,否则不生效 - 写法示例:
* text=auto eol=lf<br>*.sh text eol=lf<br>*.bat text eol=crlf<br>*.png binary
-
text=auto让Git自动探测是否为文本,比盲目设text更安全 - 设了
eol=lf后,Windows用户检出的.py文件仍是LF,编辑器需支持LF(VS Code、PyCharm默认支持)
core.autocrlf该关还是该开
除非你一个人独占项目且永远只用一个系统,否则不要依赖它。它的全局设置容易被新人覆盖,且无法区分文件类型。
GInstall OneClick — 一键安装 GitHub 项目:规划、克隆、安装 Node 依赖、运行开发脚本。适用于想要获取 GitHubNode.js 项目的用户。
参数差异:core.autocrlf=true(Windows)会在检出时强行加\r,可能破坏shell脚本;core.autocrlf=input(Linux/macOS)看似安全,但遇到没声明.gitattributes的老项目,依然会漏掉某些后缀(比如.env)。
- 推荐统一执行:
git config --global core.autocrlf false,彻底禁用自动转换 - 禁用后,所有换行符行为完全由
.gitattributes决定,可控性翻倍 - 如果已有历史提交混入CRLF,运行
git rm --cached -r . && git reset --hard可重置工作区(注意先备份未提交改动)
哪些文件绝对不能参与换行符转换
二进制文件一旦被当作文本处理,\r\n插入进去就等于损坏。Git靠.gitattributes里的binary标记或-text来跳过它们。
容易踩的坑:有人给.json设eol=lf,结果API返回的JSON里带\r\n(比如日志字段),Git转完反而破坏原始结构;还有人把.sql当纯文本转,但某些导出工具生成的SQL含二进制blob。
- 明确声明:
*.zip binary、*.jpg binary、*.pdf binary - 对模糊类型,宁可保守:
*.log -text(-text表示“不要当文本处理”,比binary更轻量) - 检查是否生效:用
git check-attr -a <file>看Git实际应用了哪些属性
Git的换行符问题本质不是“转不转”,而是“谁来决定怎么转”。.gitattributes写错一行,就可能让整个团队的git diff失去意义。最麻烦的是那种已经污染的历史提交——它不会报错,但每次git checkout都会悄悄改你的文件。

















