Add .gitattributes pinning *.sh to LF so the embedded bootstrap.sh is not CRLF #5

Closed
opened 2026-07-28 12:20:56 +09:00 by FLYEMOJ1 · 1 comment
FLYEMOJ1 commented 2026-07-28 12:20:56 +09:00 (Migrated from github.com)

问题

仓库里没有 .gitattributes。deploy/bootstrap.sh 在 index 里是 LF,在 Windows 工作区里是 CRLF(2374 个 CR),而 go:embed 嵌的是工作区的字节,不是 index 的。

于是在 Windows 上构建的 felis 二进制里,嵌进去的 bootstrap.sh 带 CRLF。TUI 安装路径把这段脚本直接 pipe 进目标 Linux 主机的 bash -s —— shebang 后面挂着 \r、变量赋值末尾带 \r、[ "$x" = yes ] 的比较对象是 yes\r。

CI 用 Linux runner 构建,所以发布的二进制不受影响。受影响的是任何在 Windows 上 go build 出来的 felis,包括开发过程中用来装测试环境的那一个。

证据

Identified by Claude Opus 5 (claude-opus-5) while auditing the embed path on 2026-07-28.

bootstrap_asset.go:10-11:

//go:embed deploy/bootstrap.sh
var bootstrapScript string

当前状态:

$ git ls-files --eol deploy/bootstrap.sh
i/lf    w/crlf  attr/                   deploy/bootstrap.sh
$ ls .gitattributes
ls: cannot access '.gitattributes': No such file or directory

attr/ 那一栏是空的 —— 没有任何属性规则在管这个文件,core.autocrlf=true 说了算。

验收

加 .gitattributes 之后 git ls-files --eol deploy/bootstrap.sh 报 w/lf,且 attr/text eol=lf。

备注

规则应该覆盖所有会被嵌进二进制或送到 Linux 上执行的文本:*.sh、Dockerfile、entrypoint。改完要 git add --renormalize . 一次,否则已有的工作区文件不会自动转。

## 问题 仓库里没有 `.gitattributes`。`deploy/bootstrap.sh` 在 index 里是 LF,在 Windows 工作区里是 CRLF(2374 个 CR),而 `go:embed` 嵌的是**工作区的字节**,不是 index 的。 于是在 Windows 上构建的 `felis` 二进制里,嵌进去的 bootstrap.sh 带 CRLF。TUI 安装路径把这段脚本直接 pipe 进目标 Linux 主机的 `bash -s` —— shebang 后面挂着 `\r`、变量赋值末尾带 `\r`、`[ "$x" = yes ]` 的比较对象是 `yes\r`。 CI 用 Linux runner 构建,所以**发布的二进制不受影响**。受影响的是任何在 Windows 上 `go build` 出来的 felis,包括开发过程中用来装测试环境的那一个。 ## 证据 Identified by Claude Opus 5 (claude-opus-5) while auditing the embed path on 2026-07-28. `bootstrap_asset.go:10-11`: ```go //go:embed deploy/bootstrap.sh var bootstrapScript string ``` 当前状态: ``` $ git ls-files --eol deploy/bootstrap.sh i/lf w/crlf attr/ deploy/bootstrap.sh $ ls .gitattributes ls: cannot access '.gitattributes': No such file or directory ``` `attr/` 那一栏是空的 —— 没有任何属性规则在管这个文件,`core.autocrlf=true` 说了算。 ## 验收 加 `.gitattributes` 之后 `git ls-files --eol deploy/bootstrap.sh` 报 `w/lf`,且 `attr/text eol=lf`。 ## 备注 规则应该覆盖所有会被嵌进二进制或送到 Linux 上执行的文本:`*.sh`、Dockerfile、entrypoint。改完要 `git add --renormalize .` 一次,否则已有的工作区文件不会自动转。
FLYEMOJ1 commented 2026-07-28 14:23:01 +09:00 (Migrated from github.com)

71e1664。.gitattributes 加上 * text=auto eol=lf(*.bat 例外,gradle 的 Windows 启动器要 CRLF),并 renormalize 了整个索引。

现在 git ls-files --eol 里 i/crlf 的条目数是 0,deploy/bootstrap.sh 的 CR 字节数是 0 —— 这条要紧是因为 bootstrap_asset.go 是把它逐字 embed 进二进制再 bash -s 管进去的,带 CR 的 shebang 和 heredoc 终止符在 Linux 上会直接坏掉。

Verified by Claude Opus 5 (claude-opus-5) on 2026-07-28.

71e1664。`.gitattributes` 加上 `* text=auto eol=lf`(`*.bat` 例外,gradle 的 Windows 启动器要 CRLF),并 renormalize 了整个索引。 现在 `git ls-files --eol` 里 `i/crlf` 的条目数是 **0**,`deploy/bootstrap.sh` 的 CR 字节数是 **0** —— 这条要紧是因为 `bootstrap_asset.go` 是把它逐字 embed 进二进制再 `bash -s` 管进去的,带 CR 的 shebang 和 heredoc 终止符在 Linux 上会直接坏掉。 Verified by Claude Opus 5 (claude-opus-5) on 2026-07-28.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: FelisMC/Felis#5