logo

鱼肚的博客

Don't Repeat Yourself

Git忽略已在仓库中的文件的改动

在git中当我们想忽略一个文件的时候,只需要修改.gitignore文件,将要忽略的目录包含在内就可以了。

典型的如node_modules等。

但是有些情况下我们会既需要将文件提交到代码仓库中,又忽略它的后续改动。这种情况就不能使用.gitignore来解决了。

什么情况下会有这种问题呢?如工程中的配置,可能每个人在开发调试过程中都会略做调整,但是不希望将这些改动提交到仓库中,以免影响持续集成或他人的配置。

常规的解决方案,是将配置文件分成多套,如dotenv会有类似下面的文件:

1.env
2.env.local
3.env.production
4.env.development

我们可以将 .env.local文件的优先级设置为最高,同时在.gitignore文件中忽略掉它。每个用户自定义的时候,只改.env.local文件,就可以做到互相不影响了。

这种方法是比较好的,也是一般来说的推荐方法。但是并不是所有场景都能用这种方式解决,有一些工程不支持从多个位置读取配置,只能改动公共文件。这种情况就无法用上面的方式解决了。

下面我介绍另一种解决方案,通过修改Git仓库配置,使其忽略掉指定文件的改动。在配置之后,即使指定的文件发生了变化,也不会体现在git status中,也不会被git add提交。

具体的命令为:

1git update-index --assume-unchanged [<file> ...]

如果以后想要提交改动,可以撤销这个设置:

1git update-index --no-assume-unchanged [<file> ...]

相关说明文档

--[no-]assume-unchanged When this flag is specified, the object names recorded for the paths are not updated. Instead, this option sets/unsets the "assume unchanged" bit for the paths. When the "assume unchanged" bit is on, the user promises not to change the file and allows Git to assume that the working tree file matches what is recorded in the index. If you want to change the working tree file, you need to unset the bit to tell Git. This is sometimes helpful when working with a big project on a filesystem that has very slow lstat(2) system call (e.g. cifs).

Git will fail (gracefully) in case it needs to modify this file in the index e.g. when merging in a commit; thus, in case the assumed-untracked file is changed upstream, you will need to handle the situation manually.

快来试试吧!