git filter-branch 的 --prune-empty 开关不会在分支开始时修剪空提交



我在主分支的开头有一个包含.gitignore文件的提交。

当我跑步时

git filter-branch -f --tree-filter 'git rm .gitignore' --prune-empty

新树仍然包含该节点,尽管为空(.gitignore 文件已被删除),因此已完成一半的工作。

为什么--prune-empty不修剪空提交?还是我误解了那个开关?

2016:git filter-branchprune-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函数。

最新更新