Git 忽略机制
· 4 min read
Git 提供三个层级的忽略机制,作用范围依次为团队级、仓库级、机器级。
三个忽略层级
1. .gitignore -- 团队级
位于项目根目录,被 Git 追踪,随提交共享给全团队。适合放整个团队都需要忽略的文件。
2. .git/info/exclude -- 仓库级
位于每个仓库的 .git/info/exclude,语法与 .gitignore 相同,但不被 Git 追踪,只对当前仓库本地生效,不会随 git push 到远程:
# .git/info/exclude
_my_scripts/
scratchpad.py
*.local
3. ~/.config/git/ignore -- 机器级
位于用户目录下(旧版可能是 ~/.gitignore_global),对本机所有 Git 仓库全局生效。适合放操作系统生成的文件:
| 系统 | 建议忽略 |
|---|---|
| macOS | .DS_Store |
| Windows | Thumbs.db |
| Linux | *~(vim 交换文件) |
通过 git config 定制全局忽略文件位置:
git config --global core.excludesFile ~/.gitignore_global
git config --global --unset core.excludesFile # 恢复默认
忽略规则优先级
从高到低:
- 命令行直接指定的文件(
git add -f强制添加) .gitignore(工作树内、被追踪).git/info/exclude(仓库级、本地、不被追踪)- 全局忽略文件
.gitignore 优先级高于 .git/info/exclude:若 .gitignore 有 !important.log(取反规则),而 exclude 写了 *.log,取反规则生效。
诊断命令:git check-ignore -v
精确到行号定位是哪条规则生效,输出格式为 文件:行号:规则 匹配文件:
$ git check-ignore -v .DS_Store
.gitignore:1:.DS_Store .DS_Store
$ git check-ignore -v my_notes.txt
.git/info/exclude:7:my_notes.txt my_notes.txt
$ git check-ignore -v .DS_Store
/Users/nelson/.config/git/ignore:2:.DS_Store .DS_Store
无输出表示该文件未被任何忽略规则覆盖。
比 ignore 更底层的文件隐藏:git update-index
与 ignore 不同体系,作用于已追踪的文件,标记存储在 .git/index 二进制文件中。
--assume-unchanged
告知 Git 跳过该文件的变更检测:
git update-index --assume-unchanged <文件>
git update-index --no-assume-unchanged <文件> # 恢复
--skip-worktree
忽略工作树中的版本,本地修改不会被提交:
git update-index --skip-worktree <文件>
git update-index --no-skip-worktree <文件> # 恢复
查看被标记的文件
git ls-files -v 输出中,被标记文件前缀为小写 h(assume-unchanged)或大写 S(skip-worktree):
git ls-files -v | grep '^h' # assume-unchanged
git ls-files -v | grep '^S' # skip-worktree
总结
| 层级 | 文件 | 作用范围 | 是否被追踪 |
|---|---|---|---|
| 团队级 | .gitignore | 全团队 | 是 |
| 仓库级 | .git/info/exclude | 当前仓库本地 | 否 |
| 机器级 | ~/.config/git/ignore | 本机所有仓库 | 否 |
| 命令 | 作用 |
|---|---|
git check-ignore -v <文件> | 定位生效的忽略规则 |
git update-index --assume-unchanged <文件> | 跳过变更检测 |
git update-index --skip-worktree <文件> | 忽略工作树版本 |
git ls-files -v | 查看文件标记状态 |