我使用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中查看历史时,我看到了两个完整的历史,一个在变化之前,一个在变化之后。最终合并在一起。
这是一个问题吗?或者我可以安全地将这两个历史留在那里吗?
答案 0 :(得分:5)
首先,git filter-branch
旨在重写历史记录,而不是创建并行历史记录。如果您通过合并完成了filter-branch
操作,则表示您使用不当。
这确实会导致混乱,因为有时您可能会看到历史记录中的一条,有时是另一条。每当你有多条历史记录做出同样的改变时,这都是一件坏事。想象一下诸如bisect
或blame
之类的操作,您正试图找到引入特定更改的提交。现在,通常有两个历史提交实际上做同样的事情 - 你想要哪一个?
即使是日期排序的git log
等基本操作,也可能会显示长时间的“重复”提交。显然不是理想的行为。
更多的思想说明:你是否应该重写历史来纠正这样一个小问题? git具有针对这种情况的功能:“mailmap”。
除非存在安全问题,否则通常应避免重写已发布的历史记录(即:披露问题......即使这样,一旦秘密出现,最好使秘密失效,而不是简单地限制其曝光,如果可能的话),或者像这样的情况,其中一些不良的历史已经发布,这使得存储库难以使用。
请注意,在已发布的历史记录上运行历史记录重写命令(如filter-branch
或rebase
)会使git不再认为您的本地提交“基于”现有的上游提交。因此,正常推送将导致错误,例如:
! [rejected] master -> master (non-fast forward)
所以你需要“强迫”推动,即:git push -f
。有关-f
的标准警告适用(请确保不要破坏任何其他人的提交),当然还有关于rewriting public history的警告。
除了有关重写公共历史的警告之外,只要你实际重写,而不是创建并行历史,那么就没有必要担心了。让我们回顾一下主要潜在问题的摘要,为了完整性:
由于第三点,我建议保留一个标记“旧”历史记录,以便任何提交提交ID的历史讨论仍然指向某个地方有效。然而,请将标记命名为明显标记为而不是以用于新开发的标记。
答案 1 :(得分:2)
嗯,对于初学者来说,你的历史记录中仍然会提交错误的已发送邮件,那么你真的获得了什么吗? : - )
除此之外,我认为用户而不是工具主要是混乱,这可能是更糟糕的情况。无论哪个提交,例如git blame
将选择绑定是相当随机的,很可能取决于合并提交的第一个父...
一般来说,任何类型的历史浏览都会让您感到痛苦 - 对您而言,不是对于工具。所以现在以某种方式修复它是个好主意,因为随着时间的推移修复它会变得更加困难。