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

相关推荐
极小狐27 分钟前
极狐GitLab 项目功能和权限解读
运维·git·安全·gitlab·极狐gitlab
极小狐34 分钟前
极狐GitLab 如何 cherry-pick 变更?
人工智能·git·机器学习·gitlab
子非衣2 小时前
Windows云主机远程连接提示“出现了内部错误”
服务器·windows
剁椒排骨3 小时前
win11什么都不动之后一段时间黑屏桌面无法显示,但鼠标仍可移动,得要熄屏之后才能进入的四种解决方法
运维·windows·经验分享·计算机外设·win11·win10
前端太佬3 小时前
从拧螺丝到造火箭:Git高阶玩家生存报告
前端·git·github
前端太佬3 小时前
从青铜到塑料:Git逃难指南(附救命指令大全)
前端·git·github
Athel3 小时前
git 建立本地仓库并且推送到github上
git
李菠菜3 小时前
Windows Terminal 集成 Git Bash 的简洁配置指南
windows·git
高级IT技术专家secops9984 小时前
在统信UOS/麒麟Kylin OS操作系统中配置APT和GIT代理
运维·服务器·git·系统安全·kylin
大数据魔法师4 小时前
Hadoop生态圈框架部署 - Windows上部署Hadoop
大数据·hadoop·windows