在 git 中,如果想忽略每个文件,可以在.gitignore 文件中设置。但是有没有不修改.gitignore 又能让 git 忽略文件的方法呢,答案按肯定是有的。
新建文件
对于新建文件,可以在.git -> info -> exclude 文件中配置。exclude 文件一般在 git 初始化时会自动创建,语法和效果与.gitignore 一致,但与.gitignore 不同的是,它总是被 git 忽略的。
和.gitignore 一样,它只能忽略那些原来没有被 track 的文件,如果某些文件已经被纳入了版本管理中,则修改 exclude 是无效的,所有这个方法基本只针对新建的文件。
修改文件
对于已经提交到仓库的文件,可以使用
git update-index --assume-unchanged PATH //在PATH处输入要忽略的文件
这个方法会忽略对应文件,但对于新建的文件是无效的。
忽略当前修改文件
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