rip*_*per 6 git git-filter-branch git-rewrite-history
主分支中Git repo foo的结构
foo/refs/a.txt
foo/bar/refs/b.txt
Run Code Online (Sandbox Code Playgroud)
在其他分支refs/可能在许多其他地方
从Git(历史)环境中删除目录引用的所有实例(及其内容):使用Git Bash的Windows 7
find . -name refs -depth -exec rm -rf {} \;
Run Code Online (Sandbox Code Playgroud)
成功,所有refs/和他们的内容被删除(如果我不使用-depth,find会报告一个错误,即dirs不存在,即使它们被正确删除).
git filter-branch --index-filter \
'find . -name refs -depth -exec git rm -rf --cached --ignore-unmatch {} \;' \
--prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)

如可以在图片中可以看出(想temp/a为temp/foo)命令贯穿并重写所有提交,但没有refs/被取出,让不知何故发现的输出没有恢复到filter-branch --index-filter预期.
类似的事情似乎对其他人有用.
我错过了什么?
PS.是的,我已经阅读了数百个关于此的数小时的帖子,文章等,但它对我来说无效.
小智 6
尽管我的旧答案显然帮助原始海报部分解决了他的问题,但似乎我实际上可能不正确,因为--index-filter只有使用 Git 命令才能使用,因为在 的文档中git filter-branch,它给出了与非 Git 一起使用的过滤器的示例除了 Git 命令之外,还有 shell 命令:
git filter-branch --index-filter \
'git ls-files -s | sed "s-\t\"*-&newsubdir/-" |
GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
git update-index --index-info &&
mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
Run Code Online (Sandbox Code Playgroud)
可能只是这样,如果您打算将非 Git 命令与 一起使用--index-filter,则它们必须对存储库的索引进行操作,如文档中的上述示例所示。
所以基本上,我不确定为什么原始海报的原始索引过滤器不起作用,但可能是他试图访问索引过滤器不允许访问的存储库的一部分,或者他使用的任何非 Git 命令实际上都没有修改索引。
另外,正如我在评论中指出的那样,
Git 实际上将它的所有引用存储
.git/refs/在非裸存储库中,在工作副本根目录下......因此该命令find . -name refs -depth实际上也会挖掘这些目录。
那么也许这会导致过滤器分支期间出现严重错误?
我认为问题可能在于您尝试使用带有filter-branch --index-filter选项而不是--tree-filter选项的非 Git shell 工具:
git filter-branch --index-filter \
'find . -name refs -depth -exec git rm -rf --cached --ignore-unmatch {} \;' \
--prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)
与 不同--tree-filter,它为每次提交检出一个新的工作目录并在其上运行传递的 shell 脚本,它--index-filter仅对 Git 存储库本身的索引文件进行操作(它不检出要操作的工作副本)......所以只有 Git 命令可以使用它。
这可能就是为什么你有更好的运气,因为它传递了 Git 命令到filter-branch --index-filter:
git filter-branch --index-filter \
'git rm -f --cached --ignore-unmatch *.zip && \
git rm -rf --cached --ignore-unmatch refs' \
--prune-empty --tag-name-filter cat -- --all
Run Code Online (Sandbox Code Playgroud)
这是git-filter-branch(1) 的文档--tree-filter:
这是用于重写树及其内容的过滤器。该参数在 shell 中进行评估,工作目录设置为检出树的根目录。
这是--index-filter(强调我的)的文档:
这是重写索引的过滤器。它类似于树过滤器,但不检查树,这使得它更快。经常与 一起使用
git rm --cached --ignore-unmatch ...,请参见下面的示例。对于毛茸茸的情况,请参阅git-update-index(1)。