我在主分支的开头有一个包含.gitignore
文件的提交。
当我跑步时
git filter-branch -f --tree-filter 'git rm .gitignore' --prune-empty
新树仍然包含该节点,尽管为空(.gitignore 文件已被删除),因此已完成一半的工作。
为什么--prune-empty
不修剪空提交?还是我误解了那个开关?
2016:git filter-branch
的prune-empty
选项确实提到了:
此开关仅适用于具有一个且只有一个父项的提交
如果修改后的提交是"在master
分支的开头",则它有 0 个 parent.
该特定提交(即使为空)也不会被修剪。
如果修改后的提交是"在分支的开头",
beginning of a branch b
|
v
--x--Y--z--z
b--b
仅当该空提交与上一个提交相同时,才应修剪它。
正如托雷克在这里提到的:*
"空提交"实际上是与上一个提交具有相同树的提交:并不是说它根本没有文件,而是它具有与其父提交相同的文件、相同的模式和相同的内容.
这是因为 git 存储每个提交的完整快照,而不是从一个提交到下一个提交之间的差异。
正如文档所说:
因此,从过滤器分支的角度来看,具有"0 文件"的提交某种过滤器将生成空提交,使树保持不变。
不是"空提交",除非父提交也有"0 文件"(即相同的空"半机密"树)
<小时 />注意:这在 Git 2.13(2017 年第 2 季度)中发生了变化:"git filter-branch --prune-empty
"(man) 删除了成为无操作的单父提交,但没有删除树为空的根提交。
请参阅提交 32da746、提交 a582a82、提交 4dacc8f、提交 377a354 (2017 年 2 月 23 日),作者:Devin J. Pohly ( djpohly
).
(由Junio C Hamano -- gitster
-- 2017年3月14日提交5296357合并)
filter-branch
:修复无父提交时的修剪空签名者:德文·波利
以前,
git_commit_non_empty_tree
函数总是将任何没有父级的提交传递给git-commit-tree
,无论树是否为非空.
然后,新的提交将被记录在过滤器分支修订图中,并且保持树不变的后续提交将被正确过滤。通过此更改,具有空树的无父提交将被正确修剪,并在修订映射中记录一个空文件,表示它已重写为"无提交"。 这自然适用于后续提交的父映射。
git filter-branch
现在在其手册页中包含:
一些过滤器将生成空提交,使树保持不变。此选项指示 git-filter-branch 删除此类提交,如果它们只有一个或零个未修剪的父母;合并提交将因此保持完整。 此选项不能与
--commit-filter
,尽管通过使用在提交筛选器中提供了git_commit_non_empty_tree
函数。