git 我需要弹出并删除我的主分支中的“中间”提交。我该怎么做?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5757187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
I need to pop up and trash away a "middle" commit in my master branch. How can I do it?
提问by Luca G. Soave
For example, in the following master branch, I need to trash just the commit af5c7bf16e6f04321f966b4231371b21475bc4da, which is the second due to previous rebase:
例如,在下面的主分支中,我只需要删除提交 af5c7bf16e6f04321f966b4231371b21475bc4da 的垃圾,这是由于之前的 rebase 导致的第二次提交:
commit 60b413512e616997c8b929012cf9ca56bf5c9113
Author: Luca G. Soave <[email protected]>
Date: Tue Apr 12 23:50:15 2011 +0200
add generic config/initializers/omniauth.example.rb
commit af5c7bf16e6f04321f966b4231371b21475bc4da
Author: Luca G. Soave <[email protected]>
Date: Fri Apr 22 00:15:50 2011 +0200
show github user info if logged
commit e6523efada4d75084e81971c4dc2aec621d45530
Author: Luca G. Soave <[email protected]>
Date: Fri Apr 22 17:20:48 2011 +0200
add multiple .container at blueprint layout
commit 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22
Author: Luca G. Soave <[email protected]>
Date: Thu Apr 21 19:55:57 2011 +0200
add %h1 Fantastic Logo + .right for 'Sign in with Github'
I need to mantain
我需要维护
- the First commit 60b413512e616997c8b929012cf9ca56bf5c9113,
- the Third commit e6523efada4d75084e81971c4dc2aec621d45530 and
- the Last commit 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22
- 第一次提交 60b413512e616997c8b929012cf9ca56bf5c9113,
- 第三次提交 e6523efada4d75084e81971c4dc2aec621d45530 和
- 最后一次提交 414ceffc40ea4ac36ca68e6dd0a9ee97e73dee22
"throwing away" just the Second commit af5c7bf16e6f04321f966b4231371b21475bc4da
“扔掉”只是第二次提交af5c7bf16e6f04321f966b4231371b21475bc4da
How can I do that? Thanks in advance Luca
我怎样才能做到这一点?提前致谢 卢卡
回答by JCotton
Rebaseor revertare the options. Rebase will actually remove the commit from the history so it will look like that second commit never existed. This will be a problem if you've pushed the master branch out to any other repos. If you try to push after a rebase in this case, git will give you a reject non fast-forward mergeserror.
变基或还原是选项。Rebase 实际上会从历史记录中删除提交,因此看起来第二次提交从未存在过。如果您将主分支推送到任何其他存储库,这将是一个问题。如果您在这种情况下尝试在 rebase 之后推送,git 会给您一个拒绝非快进合并错误。
Revert is the correct solution when the branch has been shared with other repos. git revert af5c7bf16
will make a new commit that simply reverses the changes that af5c7bf16 introduced. This way the history is not rewritten, you maintain a clear record of the mistake, and other repos will accept the push.
当分支已与其他存储库共享时,Revert 是正确的解决方案。git revert af5c7bf16
将进行新的提交,简单地逆转 af5c7bf16 引入的更改。这样历史就不会被重写,你保持一个清晰的错误记录,其他 repos 会接受推送。
Here's a good way to erase: git rebase -i <commit>^
That takes you to the commit just before the one you want to remove. The interactive editor will show you a list of all the commits back to that point. You can pick, squash, etc. In this case removethe line for the commit you want to erase and save the file. Rebase will finish its work.
这是一种擦除的好方法:git rebase -i <commit>^
这会将您带到要删除的提交之前的提交。交互式编辑器将向您显示返回到该点的所有提交的列表。您可以选择、压缩等。在这种情况下,删除您要擦除并保存文件的提交的行。Rebase 将完成其工作。
回答by mipadi
If rebase is an option, you can rebase and just drop it:
如果 rebase 是一个选项,您可以 rebase 并删除它:
$ git rebase -i 414ceffc^
If rebase is not an option, you can just revert it:
如果 rebase 不是一个选项,您可以将其还原:
$ git revert af5c7bf16
回答by BuvinJ
Despite all the credit the original answers received here, I didn't quite find them to satisfactorily answer the question. If you find yourself in a situation where you need to remove a commit, or a collection of commits from the middle of the history, this is what I suggest:
尽管原始答案在这里得到了所有赞誉,但我并没有发现它们能令人满意地回答这个问题。如果您发现自己处于需要从历史记录中间删除提交或提交集合的情况,这就是我的建议:
- Create a new branch off the head of the one containing all the commits and switch to it.
- Revert the new branch back to the point you want to start a new base from.
- Then, (here's the key point) cherry pickthe subsequent commits you actually want to be applied after that from the original branch to the new one, and skip the commits you don't want anymore (i.e. the ones you are deleting).
- If desired, rename the original branch to something indicating it's old code, and then rename your new branch what the original one was called.
- Finally, push your changes to your remote repo (if using one). You'll probably need to use a "forced push". If your collaborators have issues pulling the revisions, it might be easiest for them to just clone the repo again from the remote source. One way or another, you'll likely want to talk to them if you are ripping commits out of the middle of your history anyway!
- 在包含所有提交的分支的头部创建一个新分支并切换到它。
- 将新分支恢复到您想要开始新基地的点。
- 然后,(这里是关键点)从原始分支到新分支挑选您实际想要应用的后续提交,并跳过您不再需要的提交(即您要删除的提交)。
- 如果需要,将原始分支重命名为表明它是旧代码的内容,然后将新分支重命名为原始分支的名称。
- 最后,将您的更改推送到您的远程存储库(如果使用一个)。您可能需要使用“强制推送”。如果您的合作者在拉动修订时遇到问题,他们可能最容易从远程源再次克隆存储库。无论如何,如果您正在从历史记录中删除提交,您可能会想与他们交谈!
Here's info on Cherry Picking: What does cherry-picking a commit with git mean?
以下是关于 Cherry Picking 的信息: 用 git 挑选提交意味着什么?
Here's some on doing it with Tortoise Git (as I just did). It's definitely easier to use a gui utility for these sorts of operations! Cherry pick using TortoiseGit
这里有一些关于用 Tortoise Git 做的事情(就像我刚刚做的那样)。使用 gui 实用程序进行此类操作绝对更容易! 使用 TortoiseGit 挑选樱桃