首页 > 解决方案 > filter-branch --tree-filter 与 .gitignore

问题描述

我不走运,不知道为什么 git 在我的过滤器分支工作流程中不断将文件添加到索引中。

过滤器分支.sh

initDir="$1"
find . \( -name "*.gitignore" -or -name "*.gitkeep" -or -name "*.gitattributes" \) -exec rm -rf {} \; &>/dev/null # remove all git ignore stuff

cp -fR "$initDir"/* ./ && # Populate directory with initDir (new .gitignore)
    git rm --cached -qrf . && # Remove all files from index.
    git clean -fdqX || exit 1 # Clean all untracked files...

if [ "$(ls -1A "./storage" | wc -l)" != "1" ]; then
    echo "storage contains still more files....??"
    exit 1
fi

我用的

git filter-branch --tree-filter "bash filterBranch.sh /tmp/iniDir" --prune-empty -- --all

我检查了添加/覆盖$initDir/storage/.gitignore

*
!.gitignore

这应该删除./storage除了.gitignore. 但是不知何故,git不会删除子文件夹或文件,./storage并且历史记录不会被清除,导致exit 1上面...

这里有什么问题?

标签: git

解决方案


树过滤器根本不使用你.gitignore. 如果您希望自己.gitignore服从,请不要使用树过滤器;如果您想使用树过滤器,请确保每次调用都将您想要的文件集留在调用过滤器的临时树中。

(您编写的过滤命令似乎更多地针对索引过滤器,这会更快。但请注意,索引过滤器没有可使用的工作树:它必须在 Git 中完成所有工作指数。)

请注意,树过滤器非常慢,因为它通过让 Git 从字面上将每个提交检出到临时目录(不是您的正常工作树)中,然后在该临时目录中运行树过滤器来工作。在树过滤器退出后保留的任何文件都是新提交中的文件。如果.gitignore该目录中有文件,则该文件的内容将进入新提交,但其内容本身将被忽略:该临时目录中的所有其他文件将进入新提交。然后临时目录被销毁,并为下一次要复制的提交创建一个新的临时目录。

(请记住,git filter-branch通过将每个原始提交复制到一个新的和改进的提交,在制作新的之前运行您的过滤器。索引过滤器比树过滤器更快,因为这个“复制”过程仅包括复制到 Git 的索引,让您修改 Git 的索引,然后提交 Git 索引中剩余的任何内容。所有这些操作都使用临时索引进行,如果使用树过滤器,则使用临时工作树,在临时子目录中。使用-d选项filter-branch将此临时子目录放在“快速”位置以加速过滤器分支。更好的是,切换到新的git filter-repo。)


推荐阅读