如何删除git历史记录中的特定修订版?
假设git历史记录如下:
1个
2个
3
4
5
15是单独的修订版。我们需要删除3,同时仍然保留1、2、4和5. 如何做到这一点?
当要删除的修订有数百个修订时,有没有一种有效的方法?
解决方案
回答
要将版本3和版本4合并为一个版本,可以使用git rebase。如果要删除版本3中的更改,则需要在交互式变基模式下使用edit命令。如果要将更改合并为一个修订版,请使用squash。
我已经成功使用了这种壁球技巧,但是之前从未需要删除修订版。希望"分裂提交"下的git-rebase文档应该给我们足够的想法来解决它。 (或者其他人可能知道)。
从git文档中:
Start it with the oldest commit you want to retain as-is: git rebase -i <after-this-commit>
将使用当前分支中的所有提交(忽略合并提交)来激发编辑器,这些提交是在给定提交之后进行的。我们可以按照自己的喜好对列表中的提交进行重新排序,也可以将其删除。该列表大致如下所示:
pick deadbee The oneline of this commit pick fa1afe1 The oneline of the next commit ...
单行描述纯粹是为了愉悦; git-rebase不会查看它们,而是查看提交名称(在此示例中为" deadbee"和" fa1afe1"),因此请勿删除或者编辑名称。
通过用命令" edit"替换命令" pick",我们可以告诉git-rebase在应用该提交后停止,以便我们可以编辑文件和/或者提交消息,修改提交,并继续进行基础调整。
如果要将两个或者多个提交折叠为一个,请在第二次及以后的提交中将命令" pick"替换为" squash"。如果提交的作者不同,它将被压缩的提交归因于第一个提交的作者。
回答
如果我们要做的只是删除修订版3中所做的更改,则可能要使用git revert。
Git revert只需使用更改创建新修订,即可撤消要还原的修订中的所有更改。
这意味着我们将保留有关不需要的提交和删除这些更改的提交的信息。
如果这同时完全有可能有人从存储库中拉出了,这可能会更加友好,因为还原基本上只是一个标准的提交。
回答
这是一种只知道要删除的<commit-id>
而是非交互式地删除特定的<commit-id>`的方法:
git rebase --onto <commit-id>^ <commit-id> HEAD
回答
如前所述,git-rebase(1)是朋友。假定提交在master
分支中,我们将执行以下操作:
git rebase --onto master~3 master~2 master
前:
1---2---3---4---5 master
后:
1---2---4'---5' master
从git-rebase(1):
A range of commits could also be removed with rebase. If we have the following situation: E---F---G---H---I---J topicA then the command git rebase --onto topicA~5 topicA~3 topicA would result in the removal of commits F and G: E---H'---I'---J' topicA This is useful if F and G were flawed in some way, or should not be part of topicA. Note that the argument to --onto and the parameter can be any valid commit-ish.