更新
虽然我的旧答案显然帮助原始发帖人部分解决了他的问题,但似乎我实际上可能不正确,--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
可能的情况是,如果您要使用带有 的非 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
不像--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
这是git-filter-branch(1) --tree-filter
的文档:
这是用于重写树及其内容的过滤器。该参数在 shell 中进行评估,工作目录设置为签出树的根目录。
这是--index-filter
(强调我的)的文档:
这是用于重写索引的过滤器。它类似于树过滤器,但不检查树,这使它更快。经常与 一起使用git rm --cached --ignore-unmatch ...
,请参见下面的示例。对于多毛的情况,请参阅git-update-index(1)。