忽略提交文件

在 git 中,如果想忽略每个文件,可以在.gitignore 文件中设置。但是有没有不修改.gitignore 又能让 git 忽略文件的方法呢,答案按肯定是有的。

新建文件

对于新建文件,可以在.git -> info -> exclude 文件中配置。exclude 文件一般在 git 初始化时会自动创建,语法和效果与.gitignore 一致,但与.gitignore 不同的是,它总是被 git 忽略的。

和.gitignore 一样,它只能忽略那些原来没有被 track 的文件,如果某些文件已经被纳入了版本管理中,则修改 exclude 是无效的,所有这个方法基本只针对新建的文件。

修改文件

对于已经提交到仓库的文件,可以使用

git update-index --assume-unchanged PATH //在PATH处输入要忽略的文件

这个方法会忽略对应文件,但对于新建的文件是无效的。

忽略当前修改文件

jsx
git ls-files -m | xargs git update-index --assume-unchanged

取消忽略文件:

git update-index --no-assume-unchanged PATH //在PATH处输入要忽略的文件

显示忽略的文件:

git ls-files -v | grep '^h\ ' | awk '{print $2}'

git ls-files -v会显示所有跟踪的文件,可以根据开头 h 字母的大小写的判断文件是否被 update-index 命令忽略,忽略的文件会以 h 开头,未忽略的文件会以 H 开头。上面的命令其实是有三个连续的小命令组成:1、获取列表,2、grep 正则过滤,3、awk 提取。

我们还可以再继续组合方法,例如一个取消所有被忽略的文件的方法如下:

git ls-files -v | grep '^h\ ' | awk '{print $2}' |xargs git update-index --no-assume-unchanged

题外话

在项目中我经常看到配置了 tsconfig.json 但使用的是.js 文件,这样配置虽然没什么问题,但可能会使编辑器的一些功能失效。

例如 vscode 的转到定义功能。如果我们在 jsconfig.json 中配置了 paths,对于.js 文件绝对路径的导入,选中某个导入再点击 F12 是可以跳转对应定义的。但如果配置了 tsconfig.json,无论是否配置 jsconfig.json,都是没发正常跳转的。

可以删除 tsconfig.json 并加上 jsconfig.json,并添加到忽略文件中。为此我写了个 shell 脚本,有需要的可以参考一下,脚本运行完可能需要重启 vscode 才能生效。

ignore.sh

#!/bin/bash # 在根目录运行 CURRENT_DIR=$( cd dirname $0 pwd ) jsConfigContent='{ "compilerOptions": { "emitDecoratorMetadata": true, "experimentalDecorators": true, "baseUrl": ".", "paths": { "components/*": ["../../node_modules/hzero-front/lib/components/*"], "utils/*": ["../../node_modules/hzero-front/lib/utils/*"], "@common/*": ["../../node_modules/o2-console-front-common/lib/*"], "@/*": ["./src/*"] } }, "include": ["src/**/*"] }' # 添加jsconfig.json for file in $CURRENT_DIR/packages/*; do if [ -d "$file" ]; then # 注释掉的效果一样,但会判断jsconfig.json是否存在 # if [ -f "$file/jsconfig.json" ]; then # echo "$file/jsconfig.json exists" # else # echo $jsConfigContent >$file/jsconfig.json # echo "$file/jsconfig.json added" # fi echo $jsConfigContent >$file/jsconfig.json echo "$file/jsconfig.json added" fi done echo "jsconfig.json" >.git/info/exclude $(git ls-files -v | grep 'H packages/.*/tsconfig.json' | awk '{print $2}' | xargs rm -rf) $(git ls-files -v | grep 'H packages/.*/tsconfig.json' | awk '{print $2}' | xargs git update-index --assume-unchanged) $(git ls-files -v | grep 'H packages/.*/jsconfig.json' | awk '{print $2}' | xargs git update-index --assume-unchanged) echo echo "ignore file done"

清除改动

reset.sh

#!/bin/bash # 先stash保存当前工作区 stashRes=$(git stash -u) # 清除所有忽略 echo "" >.git/info/exclude $(git ls-files -v | grep '^h\ ' | awk '{print $2}' | xargs git update-index --no-assume-unchanged) # # 清空工作区 $(git checkout .) $(git clean -f -q) # 恢复stash if [ "No local changes to save" != "$stashRes" ]; then $(git stash pop) fi