你如何删除git历史中的特定版本?
假设你的git历史logging如下所示:
1 2 3 4 5
1-5是单独的修订。 你需要删除3,同时保持1,2,4和5.这个怎么做?
有一个有效的方法,当有一个被删除的数以百计的修改后?
要将版本3和版本4合并成一个版本,可以使用git rebase。 如果要删除修订版本3中的更改,则需要在交互式底线模式下使用编辑命令。 如果您想要将更改合并到一个修订版本中,请使用压扁。
我已经成功地使用了这种压扁技术,但从来没有需要删除修订。 “拆分提交”下的git-rebase文档应该有希望给你足够的想法。 (或者别人可能知道)。
从git文档 :
用你想要保留的最旧的提交开始它:
git rebase -i <after-this-commit>
一个编辑器将会触发当前分支中的所有提交(忽略合并提交),这是在给定提交之后发生的。 您可以将此列表中的提交重新sorting,以便将其删除。 列表看起来或多或less是这样的:
挑选死虫这个提交的oneline selectfa1afe1下一个提交的oneline ...在线描述纯粹是为了您的乐趣; git-rebase不会看着它们,而是在提交名称(本例中为“deadbee”和“fa1afe1”),所以不要删除或编辑名称。
通过使用命令“edit”replace命令“pick”,可以告诉git-rebase在应用该提交后停止,以便可以编辑文件和/或提交消息,修改提交并继续重新绑定。
如果要将两个或多个提交合并为一个,请将“pick”命令replace为“squash”作为第二个提交。 如果提交具有不同的作者,它将把压扁的提交归因于第一次提交的作者。
这是一种非交互式地删除特定的<commit-id>
,只知道你想删除的<commit-id>
:
git rebase --onto <commit-id>^ <commit-id> HEAD
根据这个评论 (我检查了这是真的),拉多的答案是非常接近,但离开了头部状态的混帐。 相反,删除HEAD
并使用它从您所在的分支中删除<commit-id>
:
git rebase --onto <commit-id>^ <commit-id>
如前所述, 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):
一系列的提交也可以用rebase去除。 如果我们有以下情况:
E---F---G---H---I---J topicA
那么命令
git rebase --onto topicA~5 topicA~3 topicA
会导致提交F和G:
E---H'---I'---J' topicA
如果F和G以某种方式存在缺陷,或者不应该成为topicA的一部分,这是非常有用的。 请注意,参数 – 参数和参数可以是任何有效的提交ish。
如果您只想删除修订版3中所做的更改,则可能需要使用git还原。
Git还原只是简单地创build一个新的修订版本,其中的更改会撤销正在还原的修订版本中的所有更改。
这意味着,您保留有关不需要的提交和删除这些更改的提交的信息。
这可能是更友好的,如果有可能的话,这个人同时从你的仓库中取出,因为回复基本上只是一个标准的提交。
迄今为止所有的答案都没有解决尾随的问题:
有一个有效的方法,当有一个被删除的数以百计的修改后?
下面的步骤,但作为参考,让我们假设以下历史:
[master] -> [hundreds-of-commits-including-merges] -> [C] -> [R] -> [B]
C :提交后提交被删除(干净)
R :要删除的提交
B :提交之前提交被删除(基地)
由于“数百修订”的限制,我假定以下前提条件:
- 有一些你不希望存在的尴尬承诺
- 有零后续的提交,实际上取决于那个尴尬承诺(回复零冲突)
- 你不在乎你将被列为数百个干预提交的“提交者”(“作者”将被保留)
- 你从来没有共享知识库
- 或者你实际上对所有曾经克隆过历史的人都有足够的影响力,让他们说服他们使用你的新历史
- 你不在乎 重写历史
这是一个相当严格的约束条件,但是有一个有趣的答案,实际上在这个angular落案例中起作用。
这里是步骤:
-
git branch base B
-
git branch remove-me R
-
git branch save
-
git rebase --preserve-merges --onto base remove-me
如果真的没有冲突的话,那就不要再打扰了。 如果有冲突,你可以解决它们并rebase --continue
或决定只是生活在尴尬和rebase --abort
。
现在你应该在master
身上,不再有提交R了。 save
分支指向您以前的位置,以防您想调和。
你想如何安排其他人转移到你的新历史取决于你。 你将需要熟悉stash
, reset --hard
和cherry-pick
。 你可以删除base
, remove-me
,并save
分支机构
所以这是我面对的情况,以及我如何解决它。
[branch-a] [Hundreds of commits] -> [R] -> [I]
这里R
是我需要删除的提交,而I
是R
之后的一个提交
我做了一个恢复承诺,把他们压在一起
git revert [commit id of R] git rebase -i HEAD~3
在交互式重新压缩最后2次提交。
我也遇到了类似的情况。 使用下面的命令使用交互式底图,select时,放弃第三次提交。
git rebase -i remote/branch
rado和kareem的答案对我没有帮助(只显示“Current branch is up to date”的消息)。 可能发生这种情况是因为'^'符号在Windows控制台中不起作用。 但是,根据这个评论,用'〜'代替'^'解决了这个问题。
git rebase --onto <commit-id>^ <commit-id>