Git提交文件忽略

在大部分使用 Git 作为版本管理的团队协作项目中,会遇到一些不需要纳入版本控制的文件。例如:自动生成的文件、编译产生的文件、日志文件、包含敏感信息的配置文件。忽略这些文件不仅能保持仓库的整洁,还能有效避免诸如密钥泄露等安全风险。本文将从最基础的配置 .gitignore 文件到进阶的本地忽略指令,全面解析 Git 中忽略文件的各种方法和最佳实践。

基础方式:.gitignore 文件

.gitignore 是 Git 中最常用的标准忽略文件方式。它是一个纯文本文件,在文件其中定义一系列匹配规则(如具体路径、通配符等),可以告诉 Git 哪些文件或目录不应该被追踪。将文件提交提交到仓库中,团队中的每一个人都能共享这套忽略规则。

  • 情况一:文件还未被 Git 追踪 (Untracked Files)

这是最简单直接的情况。如果一个文件从未被 git add 过,你只需要将它的路径或匹配模式添加到 .gitignore 文件中即可。操作步骤如下:

  1. 创建或编辑 .gitignore:在项目根目录下找到或新建 .gitignore 文件。

  2. 添加忽略规则:在文件中写入你想忽略的模式,一行一条匹配规则。

1
2
3
4
5
6
7
8
9
10
11
# 忽略所有 .log 结尾的文件
*.log
# 忽略整个 build 目录
build/
# 忽略一个具体的配置文件
.env
.eslintcache
# 忽略 JetBrains IDE 的配置目录
.idea/
# 忽略 Java 编译产物
target
  • 情况二:文件已经被 Git 追踪 (Tracked Files)

如果一个文件已经被 git commit 提交过,那么在 .gitignore 中添加规则是无效的。因为 Git 的版本历史中已经包含了这个文件,它会继续追踪其变更。

需要使用 git rm 命令先把文件从 Git 的追踪列表(索引)中移除,并且提交变更后,忽略规则才会生效。操作步骤如下:

1
2
3
4
5
6
# 移除文件
git rm -r <文件或目录路径>
# 如果想要移除Git索引同时保留本地文件,可以使用 git rm --cached -r <文件或目录路径>
# 然后修改 .gitignore 忽略规则
# 提交变更
git add .gitignore && git commit -m "chore: Stop tracking" && git push

进阶方式:–assume-unchanged 和 –skip-worktree

有时候,一个文件必须存在于仓库中(例如,一个项目的基础配置文件),但你需要在本地对修改以适应你的开发环境,同时又不希望将这些修改提交上去。这时可以使用 --assume-unchanged--skip-worktree 索引参数告诉 Git 忽略文件的修改。这两个指令都只影响本地仓库,不会影响团队中的其他人。

  • –assume-unchanged (⚠️ 有丢失文件的风险)

这个索引参数的初衷是为了提升在超大仓库中的性能。它告诉 Git:“请假设这个文件没有被修改过,不要花时间去检查它的状态了。”

需要注意的是,这是一个有风险的指令。Git 会认为这个文件没有被修改,如果执行 git checkout 切换分支或 git pull 合并代码时遇到了远端版本与当前文件内容不一致时,Git 会毫不犹豫地用远端的版本覆盖本地修改,导致修改永久丢失!

1
2
3
4
# 忽略文件
git update-index --assume-unchanged <filepath>
# 撤销忽略
git update-index --no-assume-unchanged <filepath>
  • –skip-worktree (✅ 安全、推荐)

这个索引参数的做法更安全。它告诉 Git:“我知道这个文件被追踪,但我打算在本地对它进行修改,请你跳过对这个文件工作区的检查。”

当切换分支或合并代码时,如果本地被忽略的修改与目标分支有冲突,Git 会阻止切换,从而保护了本地修改。这使得 --skip-worktree 成为更安全的选择。

1
2
3
4
# 忽略文件
git update-index --skip-worktree <filepath>
# 撤销忽略
git update-index --no-skip-worktree <filepath>
  • 忽略整个目录

以上两个索引参数只能对单个文件操作生效。需要借助其他命令辅助才能对整个目录下的所有文件应用忽略规则。

Linux & macOS & Windows Git Bash (使用 xargs):

1
2
3
4
# 忽略整个 'dist' 目录下的所有文件变更
git ls-files -z dist/ | xargs -0 git update-index --skip-worktree
# 取消忽略
git ls-files -z dist/ | xargs -0 git update-index --no-skip-worktree

Windows (使用 PowerShell):

1
2
3
4
# 忽略整个 'dist' 目录下的所有文件变更
git ls-files dist/ | ForEach-Object { git update-index --skip-worktree $_ }
# 取消忽略
git ls-files dist/ | ForEach-Object { git update-index --no-skip-worktree $_ }

Windows (使用 cmd):

1
2
3
4
# 忽略整个 'dist' 目录下的所有文件变更
FOR /F "tokens=*" %G IN ('git ls-files dist/') DO git update-index --skip-worktree "%G"
# 取消忽略
FOR /F "tokens=*" %G IN ('git ls-files path/to/your/folder') DO git update-index --no-skip-worktree "%G"

如果想把这个命令写在一个批处理脚本(.bat 文件)中,需要将 %G 改为 %%G

1
2
REM This is inside a .bat file
FOR /F "tokens=*" %%G IN ('git ls-files dist/') DO git update-index --no-skip-worktree "%%G"
  • 查看项目下文件状态

通过一条命令可以查看当前仓库中所有被设置了标记忽略的文件,运行下列命令,Git 会列出仓库中的文件,并在文件名前附加一个状态标记。

1
git ls-files -v 

小写 h 开头的文件,就是被设置为 assume-unchanged 的文件。大写 H 开头的文件,是正常的、被追踪的文件。小写 s 开头的文件,是被设置为 skip-worktree 的文件。示例输出:

1
2
3
4
H .gitignore
H package.json
s src/config/prod.js
h src/config/dev.js

如果项目文件非常多,只想精确地找出那些被标记忽略的文件,可以在命令后面加上 grep(在 Git Bash、Linux 或 macOS 中)或 Select-String(在 Windows PowerShell 中)进行过滤。

1
2
3
4
# 在 Git Bash / Linux / macOS 中
git ls-files -v | grep '^h'
# 在 Windows PowerShell 中, Select-String 默认大小写不敏感,需要加上参数 -CaseSensitive 区分
git ls-files -v | Select-String -Pattern '^h' -CaseSensitive

更适合的方式:模板文件

当项目运行需要一个配置文件(如 application-database.yml),但其中的内容(如端口、密码)对每个开发者来说都不同时,最佳实践就是使用“模板文件”。

  1. 创建模板文件:创建一个不包含任何敏感信息的配置文件范本,通常命名为 application-database.yml.exampleapplication-database.template.yml 并提交。
  2. 忽略实际文件:在 .gitignore 文件中,添加实际的配置文件名 application-database.yml
  3. 在文档中说明:在项目的 README.md 中,指导新成员如何使用模板文件。

这种方式既能让新成员快速配置好开发环境,又能确保敏感信息永远不会被意外地提交到版本库中,是团队极佳的协作模式。

总结

方法 .gitignore –assume-unchanged –skip-worktree
作用域 整个仓库 (共享) 仅限本地 仅限本地
意图 永久性忽略一类文件 性能优化,无视文件变化 在本地修改配置,且不提交
安全性 安全 有数据丢失风险 相对安全
推荐场景 日志、编译产物、配置文件 一般不推荐使用 开发环境特定的配置修改