了解与配置 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 优雅处理行结束符,也可看看。

相关推荐
GISer_Jing5 小时前
Git协作开发:feature分支、拉取最新并合并
大数据·git·elasticsearch
柳鲲鹏6 小时前
WINDOWS最快布署WEB服务器:apache2
服务器·前端·windows
专注VB编程开发20年8 小时前
开机自动后台运行,在Windows服务中托管ASP.NET Core
windows·后端·asp.net
高山莫衣11 小时前
git rebase多次触发冲突
大数据·git·elasticsearch
码农藏经阁11 小时前
工作中常用的Git操作命令(一)
git
李洋-蛟龙腾飞公司11 小时前
HarmonyOS NEXT应用元服务常见列表操作分组吸顶场景
linux·运维·windows
kobe_OKOK_11 小时前
【团队开发】git 操作流程
git·elasticsearch·团队开发
码农垦荒笔记11 小时前
Git 安装闭坑指南(仅 Windows 环境)
windows·git
阿幸软件杂货间12 小时前
Windows 10 2016 长期服务版
windows·系统·win10
木头左15 小时前
Windows环境下Docker容器化的安装与设置指南
windows·docker·容器