返回博客

FastAdmin 默认 .gitignore 静默吞掉所有 *.sql 文件

某次交付时,约定要把若干张表的 DDL 归档进代码仓库,供后续 review 和线上复现问题时对照。文件写好了,git add 也毫无报错,但 git status 里就是看不到新文件。反复检查路径、文件名,一切正常——文件明明在磁盘上,git 就是视而不见。

现象

# 写入 DDL 归档
$ echo "CREATE TABLE ..." > application/extra/schema_archive/orders_v1.sql
 
# 尝试暂存
$ git add application/extra/schema_archive/orders_v1.sql
 
# 检查状态
$ git status
# 输出:nothing to commit, working tree clean
# ——新文件消失了

git check-ignore 一查,真相立刻出来:

$ git check-ignore -v application/extra/schema_archive/orders_v1.sql
.gitignore:24:*.sql    application/extra/schema_archive/orders_v1.sql

第 24 行,一条全局 *.sql 规则,把这个文件拦截了。

根因

FastAdmin 官方仓库的 .gitignore 模板里有一行:

*.sql

出发点是好的——防止开发者把 database.sqlbackup.sql 之类的数据库全量 dump 误提交到公共仓库,泄露生产数据。但 .gitignore 的规则是项目级生效,不区分子目录,结果连你精心管理的 schema 快照、migration 脚本也一并屏蔽掉了。

坑:git add 静默成功但文件从未进入仓库

.gitignore 规则命中时,git add 不会报错、不会警告,命令正常退出,但文件不会被暂存。git status 也不会把它显示为"未跟踪文件",它直接从 git 的视野里消失。

如果团队没有人去查 git check-ignore,这个问题可以无声地持续很久——本地有文件、仓库没有、线上复现问题时无法对照 DDL。

正解

根据实际用途选择其中一种方式。

方式一:改用 .sql.txt 后缀(推荐用于 DDL 归档 / schema 快照)

# 把后缀从 .sql 改为 .sql.txt
mv application/extra/schema_archive/orders_v1.sql \
   application/extra/schema_archive/orders_v1.sql.txt

好处:

  • .gitignore 改动,单人可处理,不影响团队其他成员
  • 文件仍可用编辑器和 cat 正常阅读
  • .txt 后缀明示"这是只读档案",不会被 MySQL 客户端或 phpMyAdmin 误当成可执行脚本导入
  • 审计友好

方式二:加白名单否定规则(推荐用于有实际 SQL 源码的场景)

如果项目有 migration 脚本必须以 .sql 形式存在,在 .gitignore 末尾追加否定规则:

# 全局屏蔽(原有规则,保持不动)
*.sql
 
# 但放行指定目录下的 SQL 文件
!application/extra/schema_archive/**/*.sql
!application/database/migrations/**/*.sql

注意两点:

  1. 否定规则必须放在屏蔽规则后面——gitignore 按顺序评估,后来居上
  2. 不能取消被父目录整体排除的文件——如果父目录自身被忽略(如 node_modules/),内部的文件无法用否定规则救回
正解:先用 git check-ignore 定位,再按用途选修复方式

遇到 git add 无反应时,第一动作是:

git check-ignore -v <文件路>

这是最终真相源,输出会精确告诉你哪个 .gitignore 文件的第几行命中了规则。比猜来猜去快 10 倍。

一句话外卖

.gitignore 静默屏蔽文件不报错——git check-ignore -v 是破案工具,不是摆设;FastAdmin 衍生项目的 *.sql 全局规则是新成员必踩坑,建议写进项目 README 顶部的 Gotchas。