一、问题背景及.gitignore文件不起作用
当我们用 git 时常常会习惯把我们不想上传到远程代码库中的一些本地文件(夹)放在一个叫做 .gitignore 的文件中,例如常见的本地 build 文件夹,一些 IDE 如Intellig、Eclipse的项目管理文件,比如下面一些配置
// 此为注释 – 将被 Git 忽略
*.a // 忽略所有 .a 结尾的文件
!lib.a // 但 lib.a 除外
/TODO // 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
node_modules
.project
.vscode
build/ // 忽略 build/ 目录下的所有文件
doc/*.txt // 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt
但有些时候我们会遇到这样的问题:明明写好了.gitignore规则,但不起作用,每次还是重复提交,当你通过 git status 显示文件状态时,他们并没有被忽略。
1、问题场景
当你在git库中编写某些代码文件,并已经stage该文件之后,你发现某个文件你不想用了,想在以后的改变中忽略它。然后你再你的.gitignore文件中加入该文件名,结果它并没有被忽略。
当你从远程代码库中 git clone 一份代码中本地并做些修改,build,然后通过 git add .** 等 stage了这些改变,当你通过 git status 查看状态时发现不小心把build/文件夹给add进来了。于是你在.gitignore文件中加入了build/,但发现并不起作用。
2、根本原因
.gitignore 文件只是 ignore 没有被 staged(cached) 文件,对于已经被 staged 的文件,加入 ignore 文件时一定要先从 staged 移除。下面这段话来自github:
因此,要想用 gitignore 忽略文件,必须先把它们从staged中移除:commit你已有的改变,保存当前的工作。
git rm --cached file/path/to/be/ignored。
git add .
git commit -m "fixed untracked files"
二、解决办法
当文件夹是目录时,需要使用 -r 参数(递归)否则会报错
git rm -r --cached .
git add .
git commit -m "update .gitignore" // windows使用的命令时,需要使用双引号
经过上面几个命令操作后,目录就会被 git 忽略了。
三、总结
.gitignore文件里的规则对已经追踪的文件是没有效果的,所以我们需要使用 rm 命令清除一下相关的缓存内容,这样文件将以未追踪的形式出现,然后再重新添加提交一下 .gitignore 文件里的规则就可以起作用了。
四、补充
当我们需要删除暂存区
或分支
上的文件, 同时工作区也不需要这个文件了, 可以使用
1 git rm file_path
2 git commit -m 'delete somefile'
3 git push
当我们需要删除暂存区
或分支
上的文件, 但本地又需要使用, 只是不希望这个文件被版本控制, 可以使用
git rm --cached file_path
git commit -m 'delete remote somefile'
git push