1

我曾经git filter-branch在我的一个存储库中更新大量提交(更正错误的作者和提交者电子邮件)。我使用的命令是:

git filter-branch -f --env-filter "GIT_AUTHOR_EMAIL='mike.r.anderson.13@gmail.com'; GIT_COMMITTER_EMAIL='mike.r.anderson.13@gmail.com';"

然后是 git pull 以与远程存储库同步

这很好用,但是当我查看 GitHub 中的历史记录时,我看到了两个完整的历史记录,一个在更改之前,一个在更改之后。最终在一个点合并。

这是一个问题吗?或者我可以安全地将这两个历史都留在那里吗?

4

2 回答 2

5

首先,git filter-branch旨在改写历史,而不是与另一个平行的历史。如果你filter-branch通过合并完成了你的操作,你就用错了。

这确实会导致混乱,因为您有时可能会看到一条历史线,有时会看到另一条历史线。任何时候你有多个历史记录进行相同的更改,这是一件坏事。想象一下诸如bisector之类的操作blame,您试图在其中找到引入特定更改的提交。现在,经常有两个历史提交实际上做同样的事情——你想要哪一个?

即使是git log按日期排序的基本操作,如 ,也可能会显示长时间的“重复”提交。显然不是想要的行为。

从更理想的角度来看:你是否应该重写历史来纠正这样一个小问题?git 具有针对这种确切情况的功能:“ mailmap ”。

您通常应该避免重写已发布的历史记录,除非存在安全问题(即:披露问题......即使这样,一旦秘密泄露,最好使秘密无效,而不是在可能的情况下简单地限制其公开) ,或者像这样的情况,其中发布了一些糟糕的历史,这使得存储库难以使用。

请注意,运行历史重写命令(例如发布filter-branchrebase历史记录)将使 git 不再将您的本地提交视为“基于”现有的上游提交。因此,正常推送会导致如下错误:

! [rejected]        master -> master (non-fast forward)

所以你需要“强制”推动,即:git push -f. 关于 apply 的标准警告-f(确保不要破坏其他任何人的提交),当然还有关于重写 public history的警告。

除了那些关于重写公共历史的警告之外,只要你真的重写,而不是创建平行的历史,那么就没有必要担心了。为了完整起见,让我们总结一下主要的潜在问题:

  • 任何拥有现有副本的人,如果在推送之前没有重新调整到您的新历史记录,将收到“非快进”警告,并可能认为他们需要合并。
  • 任何将旧历史与新历史合并并推送的人都会导致“旧”历史被恢复。
  • 邮件列表、电子邮件等中从“旧”历史提交 id 的旧引用将不再相关。

由于第三点,我建议保留“旧”历史的标记,以便任何提及提交 ID 的历史讨论仍然指向有效的地方。但是,一定要使用一些可以明显表明该标签用于新开发的东西来命名标签。

于 2012-09-30T17:23:07.327 回答
2

好吧,对于初学者来说,您仍然会在历史记录中使用错误的已提交电子邮件进行提交,那么您真的得到了什么吗?:-)

除此之外,我认为这主要是让用户感到困惑而不是工具,这可能是更糟糕的情况。无论选择哪个提交,例如git blame将选择一定是相当随机的,很可能取决于合并提交的第一个父级......

一般来说,任何类型的历史浏览都会很痛苦——对你来说,而不是工具。所以现在以某种方式修复它是个好主意,因为随着时间的推移修复它只会变得更加困难。

于 2012-09-30T17:14:48.480 回答