我正在尝试使用git filter-branch,并让我的一个由.gitignore组成的初始提交(之后重新加入分支)生效。
这就是我的目的:
git filter-branch -f --tree-filter 'git rm -r --cached . && git add .' --prune-empty
但是,此命令会使存储库保持不变。
为什么?
我也想知道为什么以下命令不会删除存储库中的所有文件:
git filter-branch -f --tree-filter 'git rm -r --cached .'
答案 0 :(得分:2)
--tree-filter
不对索引进行操作。 1 而是将每个提交复制到用作工作树的临时目录,在该临时目录中运行命令,并使临时目录中保留和/或新文件的新提交。您在此过程中对索引本身所做的更改实际上会被忽略。
这意味着您必须从工作树中删除新.gitignore
阻止添加的文件。您可以使用git rm --cached
中的--index-filter
手动执行此操作,这会更快,但如果您想让git在--tree-filter
中为您完成工作,则可以使用git本身使用的相同技巧(参见脚注):使用git clean
(带-x
)来清理临时目录。
1 这不完全正确:filter-branch
的{{1}}代码使用--tree-filter
填充索引(重新)填充临时目录(反过来意味着它必须做一些工作来清除之前提交的临时目录,它使用git read-tree
)。然后,在git clean
过滤器之后,它再次使用索引来检查临时目录中的操作。当您eval
然后git rm -r --cached .
时,它会将结果索引(不再包含您忽略的文件)与工作树进行比较,并且... 添加您忽略的文件。哎呀!
答案 1 :(得分:0)
此解决方案有效,但它不支持文件名中的空格:
git filter-branch -f --tree-filter 'ls -r | xargs --no-run-if-empty \
git check-ignore --no-index | xargs --no-run-if-empty rm' --prune-empty
它还会为git check-ignore
生成极长的行,即工作目录中所有文件的列表(递归)。不能git check-ignore
自己处理递归吗?和文件名中的空格,如何支持那些?