我需要在我的主分支中弹出并删除"中间"提交.我该怎么做?

BBJ*_*BJ3 87 git github git-rebase git-revert git-reset

例如,在下面的主分支中,我需要删除提交af5c7bf16e6f04321f966b4231371b21475bc4da,这是由于之前的rebase导致的第二个:

commit 60b413512e616997c8b929012cf9ca56bf5c9113
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Tue Apr 12 23:50:15 2011 +0200

    add generic config/initializers/omniauth.example.rb

commit af5c7bf16e6f04321f966b4231371b21475bc4da
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Fri Apr 22 00:15:50 2011 +0200

    show github user info if logged

commit e6523efada4d75084e81971c4dc2aec621d45530
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Fri Apr 22 17:20:48 2011 +0200

    add multiple .container at blueprint layout

commit 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22
Author: Luca G. Soave <luca.soave@gmail.com>
Date:   Thu Apr 21 19:55:57 2011 +0200

    add %h1 Fantastic Logo + .right for 'Sign in with Github'
Run Code Online (Sandbox Code Playgroud)

我需要保持健康

  • 第一次提交60b413512e616997c8b929012cf9ca56bf5c9113,
  • 第三次提交e6523efada4d75084e81971c4dc2aec621d45530
  • 最后一次提交414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22

"扔掉"只是第二次提交af5c7bf16e6f04321f966b4231371b21475bc4da

我怎样才能做到这一点?在此先感谢Luca

JCo*_*ton 94

Rebaserevert是选项.Rebase实际上会从历史记录中删除提交,因此看起来第二次提交从未存在过.如果您将主分支推送到任何其他存储库,这将是一个问题.如果在这种情况下尝试推送一个rebase,git会给你一个拒绝非快进合并错误.

当分支与其他repos共享时,Revert是正确的解决方案.git revert af5c7bf16将进行一个新的提交,简单地反转af5c7bf16引入的更改.这种方式历史不会被重写,你保持清楚的错误记录,其他的回购将接受推动.

这是一个很好的擦除方法:git rebase -i <commit>^ 它将您带到要删除的提交之前的提交.交互式编辑器将显示返回该点的所有提交的列表.您可以选择,压缩等.在这种情况下,删除要删除的提交行并保存文件.Rebase将完成其工作.

  • 万一我选择“变基”,什么是变基的正确提交?我只需要删除第二个... (2认同)

mip*_*adi 31

如果rebase是一个选项,你可以改变并删除它:

$ git rebase -i 414ceffc^
Run Code Online (Sandbox Code Playgroud)

如果不能选择rebase,您可以将其还原:

$ git revert af5c7bf16
Run Code Online (Sandbox Code Playgroud)

  • @Luca G. Soave:仅当您明确告诉`git rebase`将其删除(通过以交互方式运行`rebase`并删除其条目)时,您才“丢失”提交。 (2认同)

Buv*_*inJ 30

尽管这里收到了原始答案的所有功劳,但我并没有发现它们能够令人满意地回答这个问题.如果您发现自己处于需要从历史中间删除提交或提交集合的情况,我建议这样做:

  • 在包含所有提交的分支的头部创建一个新分支并切换到它.
  • 将新分支恢复到您想要从中开始新基础的点.
  • 然后,(这里是关键点)樱桃选择你之后实际想要从原始分支到新分支的后续提交,并跳过你不再需要的提交(即你要删除的提交).
  • 如果需要,将原始分支重命名为指示其旧代码的内容,然后将新分支重命名为原始分支的名称.
  • 最后,将您的更改推送到远程仓库(如果使用的话).您可能需要使用"强制推送".如果您的协作者在修改版本时遇到问题,那么他们可能最容易从远程源再次克隆回购.无论如何,如果您正在从历史中间删除提交,您可能会想要与他们交谈!

这里有关于Cherry Picking的信息: 使用git意味着采摘樱桃是什么意思?

这里有一些用Tortoise Git做的(正如我刚才所做的那样).在这些操作中使用gui实用程序肯定更容易! Cherry挑选使用TortoiseGit

  • 这应该是最好的答案! (6认同)