了解与配置 Git autocrlf 文本换行符处理

计算机目前有两个文本换行符的事实标准。涉及两个字符:

  • CR Carriage Return 回车符。转义符 \r ASCII 码 13 (0x0D)
  • LF Line Feed 换行符。转义符 \n ASCII 码 10 (0x0A)

顾名思义,这是古早打字机时期流传下来的控制指令。

用法上:

  • Windows 采用 CRLF 两个字符做行尾,最大程度照顾兼容性。
  • Linux/macOS 采用 LF。其中 macOS 自 2001 年起从 CR 改为 LF

Git 默认使用 LF,即:文本文件检入至仓库时(checkin)换行符使用 LF,检出至工作目录时(checkout)换行符使用 LF

这跟 Windows 的默认值不同,需要处理。Git 提供了一些相关配置项。

首先,Git 只对文本文件做修改 。那么首先要标记或检测一个文件是否为文本文件。这是 .gitattributes 的用途(之一)。

这个片段简要说明其用法:

.gitattributes 复制代码
# auto detect, not mark as text unconditionally
*           text=auto

*.c         text
*.cpp       text

# binary = -text -diff
*.exe       binary
*.lib       binary
*.obj       binary

.gitattributes 可以是仓库级配置,置于仓库根目录;也可以是用户级配置,位置和命名跟 .gitconfig 相同($HOME/.gitattributes $HOME/.config/git/attributes)。

.gitattributes 自上而下后者覆盖前者、仓库级覆盖用户级

其次,Git 会修改文本文件的换行符(End of Line,EOL)和文本编码(Text Encoding)。当然本文只关心换行符。

autocrlf 取值及效果如下所示:

  • $autocrlf=false : checkout as-is, checkin as-is
  • $autocrlf=input : checkout as-is, checkin eol=lf
  • $autocrlf=true : checkout $eol, checkin eol=lf

EOL 取值如下所示:

  • $eol=native : platform preference
  • $eol=lf
  • $eol=crlf

还挺清晰,对吗?考虑考虑下面两种情形:

  1. 检入了文件,文件 eol=crlf
  2. 文本文件的不同的行混用了 crlf lf

#1 很常见,尤其是下载使用他人的代码仓库的时候。这时,如果将其作为文本文件,那么检出时就会遵循 autocrlf,如果配置是 input or true,那么 git diff 全文件每行都不匹配,因为再次检入就会改成 eol=lf 了。

针对这种情况,Git attribute text 的自动检测写法 text=auto 能处理好:

  • text 显式标记为文本文件,处理视同 autocrlf=true
  • text=auto 自动检测是否为文本文件。如果是文本,处理视同 autocrlf=true
    • 特殊情况:如果是文本、已检入过 eol=crlf,处理视同 autocrlf=false

因此 .gitattributes 最佳写法是:

.gitattributes 复制代码
*.c         text=auto eol=native
*.cpp       text=auto eol=native

为何这么做好呢?因为你不是原仓库的唯一所有人,避免破坏原仓库文件 eol 可以避免合并冲突。

可以使用如下命令观察当前状态:

bash 复制代码
> git ls-files --eol a-file-whose-eol-is-crlf
i/crlf    w/crlf    attr/text          a-file-whose-eol-is-crlf

如果你只是仓库消费者,最简单做法是 .gitattributes 写成这样:

.gitattributes 复制代码
*.c         -text eol=input autocrlf=false

如果你是唯一所有人,那么你可以将全量扫描并统一 eol:

bash 复制代码
git add --renormalize .

茴字的另一种写法:

bash 复制代码
git filter-branch --tree-filter 'find . -type f -exec dos2unix {} \;' -- --all

autocrlf eol 不仅可以在 .gitattributes 中配置,还有 .gitconfig 内的一组配置项:

  • core.autocrlf 文本文件处理时的默认值
  • core.eol 默认 =native 所以一般无需配置
  • core.safecrlf 如果要发生不可逆的转换,则 =true 阻止;=warn 发出警告

临了,发现隔壁也有一篇参考文档 Git 优雅处理行结束符,也可看看。

相关推荐
maply1 小时前
VSCode 中的 Git Graph扩展使用详解
ide·git·vscode·编辑器·扩展
行十万里人生5 小时前
Qt事件处理:理解处理器、过滤器与事件系统
开发语言·git·qt·华为od·华为·华为云·harmonyos
会敲代码的Steve8 小时前
git笔记-简单入门
笔记·git
大道戏8 小时前
如何本地部署DeepSeek
windows·ai·deepseek
画船听雨眠aa10 小时前
gitlab云服务器配置
服务器·git·elasticsearch·gitlab
skywalk816310 小时前
在Windows下安装Ollama并体验DeepSeek r1大模型
人工智能·windows·ollama·deepseek
康世行15 小时前
Windows环境下MaxKB大模型 Docker部署图文指南
windows·docker·容器
Tangcan-1 天前
Linux中基础开发工具(yum,vim,gcc/g++,git,gdb/cgdb)
linux·git·vim
苏-言1 天前
Git进阶之旅:分支管理策略
git
初级代码游戏1 天前
git:恢复纯版本库
git·恢复·纯版本库