假设您的git历史记录如下:
1 2 3 4 5
1-5是单独的修订。你需要删除3,同时仍然保持1,2,4和5.如何做到这一点?
在要删除的修订版之后有数百个修订版时,是否有一种有效的方法?
答案 0 :(得分:118)
以下是一种非交互式删除特定<commit-id>
的方法,只知道您要删除的<commit-id>
:
git rebase --onto <commit-id>^ <commit-id> HEAD
答案 1 :(得分:114)
Per this comment(我检查过这是真的),rado的答案非常接近,但是让git处于一个独立的头状态。相反,请移除HEAD
并使用此功能从您所在的分支中移除<commit-id>
:
git rebase --onto <commit-id>^ <commit-id>
答案 2 :(得分:74)
如前所述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的一部分。 请注意--onto和。的参数 参数可以是任意的 有效的commit-ish。
答案 3 :(得分:72)
要将版本3和版本4合并为单个版本,可以使用git rebase。如果要删除修订版3中的更改,则需要在交互式rebase模式下使用edit命令。如果要将更改组合到单个修订中,请使用squash。
我已成功使用此壁球技术,但以前从未需要删除修订版。 “Splitting commits”下的git-rebase文档应该会给你足够的想法来解决它。 (或其他人可能知道)。
使用您希望保留的最旧提交启动它:
git rebase -i <after-this-commit>
将在当前分支中的所有提交(忽略合并提交)启动编辑器,这些提交在给定的提交之后。您可以将此列表中的提交重新排序到您的内容,然后您可以删除它们。该列表看起来或多或少像这样:
pick deadbee The oneline of this commit pick fa1afe1 The oneline of the next commit ...oneline描述纯粹是为了您的乐趣; git-rebase不会查看它们,而是查看提交名称(本例中为“deadbee”和“fa1afe1”),所以不要删除或编辑名称。
通过使用命令“edit”替换命令“pick”,可以告诉git-rebase在应用该提交后停止,以便您可以编辑文件和/或提交消息,修改提交,然后继续垫底。
如果要将两个或多个提交折叠成一个,请将命令“pick”替换为“squash”以进行第二次和后续提交。如果提交有不同的作者,它会将压缩的提交归因于第一次提交的作者。
答案 4 :(得分:22)
如果您只想删除修订版3中所做的更改,则可能需要使用git revert。
Git revert只是创建一个新版本,其中包含撤消修订版本中所有更改的更改。
这意味着,您保留有关不需要的提交和删除这些更改的提交的信息。
如果有人在同一时间从你的存储库中撤出,这可能会更加友好,因为恢复基本上只是一个标准的提交。
答案 5 :(得分:15)
到目前为止,所有答案都没有解决拖尾问题:
当有数百个修订时,是否有一种有效的方法 在要删除之后?
以下步骤,但作为参考,我们假设以下历史记录:
[master] -> [hundreds-of-commits-including-merges] -> [C] -> [R] -> [B]
C 的: 提交之后提交要删除(干净)
- [R : 要删除的提交
乙: 提交之前提交要删除(基础)
由于&#34;数百次修订&#34;约束,我假设以下前提条件:
这是一组相当严格的约束,但有一个有趣的答案实际上适用于这个角落。
以下是步骤:
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
分支
答案 6 :(得分:2)
所以这是我遇到的情景,以及我是如何解决的。
[branch-a]
[Hundreds of commits] -> [R] -> [I]
此处R
是我需要删除的提交,而I
是R
之后的单个提交
我做了一个还原提交并将它们压在一起
git revert [commit id of R]
git rebase -i HEAD~3
在交互式rebase压缩期间,最后2次提交。
答案 7 :(得分:2)
我也陷入了类似的境地。使用以下命令使用交互式rebase,在选择时,删除第3次提交。
git rebase -i remote/branch
答案 8 :(得分:0)
rado和kareem的答案对我没有任何帮助(只有消息&#34;当前分支是最新的。&#34;出现)。可能会发生这种情况,因为&#39; ^&#39;符号在Windows控制台中不起作用。但是,根据this评论,替换&#39; ^&#39;通过&#39; ~1&#39;解决了这个问题。
git rebase --onto <commit-id>^ <commit-id>
答案 9 :(得分:-3)
首先在cmd以下运行
rm -rf .git
-从当前版本重新创建仓库
git init
git add .
git commit -m "first commit"
-推送到github远程仓库
git remote add origin git@github.com<your git mail>
git push -u --force origin master