git filter-branch尊重我的初始提交.gitignore

时间:2016-04-27 14:11:43

标签: git git-filter-branch

我正在尝试使用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 .'

2 个答案:

答案 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自己处理递归吗?和文件名中的空格,如何支持那些?