首先,git filter-branch
旨在改写历史,而不是与另一个平行的历史。如果你filter-branch
通过合并完成了你的操作,你就用错了。
这确实会导致混乱,因为您有时可能会看到一条历史线,有时会看到另一条历史线。任何时候你有多个历史记录进行相同的更改,这是一件坏事。想象一下诸如bisect
or之类的操作blame
,您试图在其中找到引入特定更改的提交。现在,经常有两个历史提交实际上做同样的事情——你想要哪一个?
即使是git log
按日期排序的基本操作,如 ,也可能会显示长时间的“重复”提交。显然不是想要的行为。
从更理想的角度来看:你是否应该重写历史来纠正这样一个小问题?git 具有针对这种确切情况的功能:“ mailmap ”。
您通常应该避免重写已发布的历史记录,除非存在安全问题(即:披露问题......即使这样,一旦秘密泄露,最好使秘密无效,而不是在可能的情况下简单地限制其公开) ,或者像这样的情况,其中发布了一些糟糕的历史,这使得存储库难以使用。
请注意,运行历史重写命令(例如发布filter-branch
的rebase
历史记录)将使 git 不再将您的本地提交视为“基于”现有的上游提交。因此,正常推送会导致如下错误:
! [rejected] master -> master (non-fast forward)
所以你需要“强制”推动,即:git push -f
. 关于 apply 的标准警告-f
(确保不要破坏其他任何人的提交),当然还有关于重写 public history的警告。
除了那些关于重写公共历史的警告之外,只要你真的重写,而不是创建平行的历史,那么就没有必要担心了。为了完整起见,让我们总结一下主要的潜在问题:
- 任何拥有现有副本的人,如果在推送之前没有重新调整到您的新历史记录,将收到“非快进”警告,并可能认为他们需要合并。
- 任何将旧历史与新历史合并并推送的人都会导致“旧”历史被恢复。
- 邮件列表、电子邮件等中从“旧”历史提交 id 的旧引用将不再相关。
由于第三点,我建议保留“旧”历史的标记,以便任何提及提交 ID 的历史讨论仍然指向有效的地方。但是,一定要使用一些可以明显表明该标签不用于新开发的东西来命名标签。