【问题标题】:How to remove a section of a project's commit history in Git?如何在 Git 中删除项目提交历史的一部分?
【发布时间】:2017-08-07 21:49:29
【问题描述】:
我一直在从事一个 Git 项目,该项目很快就会与其他开发人员共享。我的项目中有一部分包含我不允许分享的信息。
如果我的项目历史看起来像 A -> B -> C -> D -> E -> F,并且提交 C 和 D 中包含的信息是私有的,是否可以修改我的项目历史,使其看起来在共享之前像 A -> B -> E' -> F' (其中 E' 和 F' 是没有机密信息的 E 和 F)?
我的理解是,如果我在 F 和 B 之间执行手动合并以创建 F',那么最终提交将是我想要的,但它不会保留项目历史记录。我认为它看起来像 A -> B -> F' 而不是 A -> B -> E' -> F'。
【问题讨论】:
标签:
git
git-rewrite-history
【解决方案1】:
我相信您正在寻找的是一个变基。
如果提交 C 和 D 是自包含的,即如果提交 E 和 F 不需要它们来干净地应用,这应该没问题。
适当的语法是:
$ git rebase --onto B D F
其中 B、D 和 F 是哈希或对这些提交的引用。
如果这些提交已经被推送到公共存储库,那么在执行此操作时要小心,因为重写已经公开的提交的历史通常是危险的并且不鼓励。
【解决方案2】:
有简单和复杂的方法来实现这一点。这是一个非常简单的方法,它可以让您轻松地grep diffs 来查找麻烦的 sn-ps 以验证它们是否存在。
创建一个新的 repo 来分享。 (您可以将无历史记录的 F' 快照存储在其中并完成,除非您希望保留一些历史记录。)
在旧存储库中使用 git format-patch 将 A、B、E'、F' 的差异存储在 /tmp 中。
使用 git am 将这些差异应用到新的 repo。发布它。
【解决方案3】:
有一个强大的工具可以让您删除敏感信息,而不管它是什么提交:BFG,The Big Repo Cleaner。
BFG 将允许您有选择地从您的回购历史记录中删除敏感信息。例如,您可以使用它来删除错误添加到存储库中的文件。它还允许从存储库中的文件历史记录中删除特定字符串。
BFG 与其他方法相比的优势在于,它可以在不影响无关紧要的提交的情况下清理历史记录。但是,它将更改存储库中已经存在的某些提交的提交 ID。有关详细信息,请参阅其常见问题解答。