Git忽略本地的文件修改,保留其在远程仓库的状态
项目中的一些配置文件,需要在本地根据实际情况配置和修改,但同时这些配置仅在本地使用,并不想提交到远程仓库,这个时候仅使用
.gitignore
就办不到了...
如引言中的使用场景,在项目中有一些配置文件在远程仓库存在,但是本地的修改并不具有普适性,因此是不需要提交到远程仓库的,天真的我一开始将项目拉下后,直接在.gitingnore
中添加了相关文件,但是在修改后发现,根本不会生效
失效的.gitignore
查了下.gitignore
不生效的问题,发现如下解释:
The files/folder in your version control will not just delete themselves just because you added them to the
.gitignore
. They are already in the repository and you have to remove them.
即文件已经被track后,再添加到.gitignore
是无效的,因为git不会自动的帮你删除文件,这一步需要手动去做,即:
git rm -rf --cached .
git add .
这个操作是删除仓库中的所有文件,然后再将他们添加回来,注意添加进仓库的时候,track的规则就会根据最新的.gitignore
进行。
好家伙,这肯定不行啊,因为这个操作是直接把配置文件给干掉了,即远程仓库也不再会有这个文件,这显然不是我想要的效果。因此,开始寻找新的方案
探寻方案
我们的核心诉求并不是'ingnore'文件,删除以及不上传这些文件,而是Only keep it in the remote repo
。
但是在我的知识体系中,还没有一个很好的解决方式,遂google探索之,终于找到了非常符合场景需求的一个git操作:
- 忽略跟踪
git update-index --assume-unchanged <file>
- 查看被忽略的跟踪文件
git ls-files -v | grep '^h '
- 恢复忽略文件,重新被版本控制
git update-index --no-assume-unchanged <file>
git update-index
只能忽略单个文件,想要忽略整个文件夹下的文件,可以使用以下命令:
cd dir
git update-index --assume-unchanged $(git ls-files | tr '\n' ' ')
方案优化
以上指令的确可以满足一开始的诉求,但是正开开心心搞完,切花分支时,一个checkout
竟然失败了,提示
error: Your local changes to the following files would be overwritten by merge ...
但是查看git tree并没有任何跟踪文件是没有保存和提交的状态,也就是说之前被设置忽略的文件,犹如掩耳盗铃般,只是不被提交,但是在merge
、checkout
的时候还是会被提示覆盖风险而导致git操作失败。
所以最终选择使用了--skip-worktree
指令, 与之前的方案非常类似:
# 原指令
git update-index --no-assume-unchanged -- <file>
# 优化指令
git update-index --skip-worktree -- <file>
至于和原指令的差别,可以查看这篇文章Difference Between 'assume-unchanged
' and 'skip-worktree
'
最终方案
- 忽略文件
git update-index --skip-worktree -- <file>
- 查看忽略的文件
git ls-files -v | grep -i ^S
- 取消标志,恢复版本控制
git update-index --no-skip-worktree -- <file>
- 批量忽略文件
cd dir
git update-index --skip-worktree $(git ls-files | tr '\n' ' ')