git 如何恢复已经推送到远程分支的合并提交?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7099833/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 11:36:37  来源:igfitidea点击:

How to revert a merge commit that's already pushed to remote branch?

git

提问by Yaz

git revert <commit_hash>alone won't work. -mmust be specified, and I'm pretty confused about it.

git revert <commit_hash>单独是行不通的。-m必须指定,我对此很困惑。

Anyone experienced this before?

有没有人经历过这种情况?

回答by Ben James

The -moption specifies the parent number. This is because a merge commit has more than one parent, and Git does not know automatically which parent was the mainline, and which parent was the branch you want to un-merge.

-m选项指定父编号。这是因为合并提交有多个父级,Git 不会自动知道哪个父级是主线,哪个父级是您要取消合并的分支。

When you view a merge commit in the output of git log, you will see its parents listed on the line that begins with Merge:

当您在 的输出中查看合并提交时git log,您将看到其父项列在以 开头的行中Merge

commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <[email protected]>
Date:   Wed Aug 17 22:49:41 2011 +0100

Merge branch 'gh-pages'

Conflicts:
    README

In this situation, git revert 8f937c6 -m 1will get you the tree as it was in 8989ee0, and git revert -m 2will reinstate the tree as it was in 7c6b236.

在这种情况下,git revert 8f937c6 -m 1将使您获得原来的树8989ee0,并git revert -m 2恢复原来的树7c6b236

To better understand the parent IDs, you can run:

为了更好地了解父 ID,您可以运行:

git log 8989ee0 

and

git log 7c6b236

回答by Saheed

Here's a complete example in the hope that it helps someone:

这是一个完整的示例,希望对某人有所帮助:

git revert -m 1 <commit-hash> 
git push -u origin master

Where <commit-hash>is the commit hash of the merge that you would like to revert, and as stated in the explanation of this answer, -m 1indicates that you'd like to revert to the tree of the first parent prior to the merge.

<commit-hash>您想恢复的合并的提交哈希在哪里,如本答案的解释中所述,-m 1表示您希望在合并之前恢复到第一个父级的树。

The git revert ...line essentially commits your changes while the second line makes your changes public by pushing them to the remote branch.

git revert ...行本质上是提交您的更改,而第二行通过将更改推送到远程分支来公开您的更改。

回答by Ryan Stewart

Ben has told you how to revert a merge commit, but it's very importantyou realize that in doing so

Ben 已经告诉过您如何恢复合并提交,但是您意识到这样做非常重要

"...declares that you will never want the tree changes brought in by the merge. As a result, later merges will only bring in tree changes introduced by commits that are not ancestors of the previously reverted merge. This may or may not be what you want." (git-merge man page).

“...声明您永远不会希望合并带来的树更改。因此,以后的合并只会带来由不是先前还原合并的祖先的提交引入的树更改。这可能会也可能不会你想要什么。(git-merge 手册页)

An article/mailing list messagelinked from the man page details the mechanisms and considerations that are involved. Just make sure you understand that if you revert the merge commit, you can't just merge the branch again later and expect the same changes to come back.

从手册页链接的文章/邮件列表消息详细介绍了所涉及的机制和注意事项。只要确保你明白,如果你恢复合并提交,你不能在稍后再次合并分支并期望相同的更改回来。

回答by ssasi

You could follow these steps to revert the incorrect commit(s) or to reset your remote branch back to correct HEAD/state.

您可以按照以下步骤还原不正确的提交或将远程分支重置回正确的 HEAD/状态。

  1. checkout the remote branch to local repo.
    git checkout development
  2. copy the commit hash (i.e. id of the commit immediately before the wrong commit) from git log git log -n5

    output:

    commit 7cd42475d6f95f5896b6f02e902efab0b70e8038 "Merge branch 'wrong-commit' into 'development'"
    commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 "this is a wrong commit"
    commit 3779ab50e72908da92d2cfcd72256d7a09f446ba "this is the correct commit"

  3. reset the branch to the commit hash copied in the previous step
    git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)

  4. run the git statusto show all the changes that were part of the wrong commit.
  5. simply run git reset --hardto revert all those changes.
  6. force-push your local branch to remote and notice that your commit history is clean as it was before it got polluted.
    git push -f origin development
  1. 将远程分支签出到本地仓库。
    git checkout development
  2. 从 git log 复制提交哈希(即在错误提交之前立即提交的 id) git log -n5

    输出:

    提交7cd42475d6f95f5896b6f02e902efab0b70e8038“合并分支‘错误提交’到‘发展’,”
    承诺f9a734f8f44b0b37ccea769b9a2fd774c0f0c012“这是一个错误的承诺”
    提交3779ab50e72908da92d2cfcd72256d7a09f446ba“这是正确的提交”

  3. 将分支重置为上一步中复制的提交哈希
    git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)

  4. 运行git status以显示属于错误提交的所有更改。
  5. 只需运行git reset --hard即可恢复所有这些更改。
  6. 强制将您的本地分支推送到远程并注意您的提交历史记录是干净的,就像它被污染之前一样。
    git push -f origin development

回答by Neeraj Kumar

git revert -m 1 <merge-commit>

回答by nvd

To keep the log clean as nothing happened (with some downsides with this approach (due to push -f)):

为了在没有发生任何事情时保持日志干净(这种方法有一些缺点(由于 push -f)):

git checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>

'commit-hash-before-merge' comes from the log (git log) after merge.

'commit-hash-before-merge' 来自合并后的日志(git log)。

回答by ppostma1

Sometimes the most effective way to rollback is to step back and replace.

有时,最有效的回滚方法是退一步并替换。

git log

git log

Use the 2nd commit hash (full hash, the one you want to revert back to, before the mistake listed) and then rebranch from there.

使用第二次提交哈希(完整哈希,在列出错误之前要恢复到的哈希),然后从那里重新分支。

git checkout -b newbranch <HASH>

git checkout -b newbranch <HASH>

Then delete the old branch, copy the newbranch over in its place and restart from there.

然后删除旧分支,将新分支复制到它的位置并从那里重新启动。

git branch -D oldbranch
git checkout -b oldbranch newbranch

If its been broadcast, then delete the old branch from all repositories, push the redone branch to the most central, and pull it back down to all.

如果已广播,则从所有存储库中删除旧分支,将重做的分支推送到最中央,然后将其拉回全部。

回答by xproph

All the answers already covered most of the things but I will add my 5 cents. In short reverting a merge commit is quite simple:

所有的答案已经涵盖了大部分内容,但我会加上我的 5 美分。简而言之,恢复合并提交非常简单:

git revert -m 1 <commit-hash>

If you have permission you can push it directly to the "master" branch otherwise simply push it to your "revert" branch and create pull request.

如果您有权限,您可以将其直接推送到“master”分支,否则只需将其推送到您的“revert”分支并创建拉取请求。

You might find more useful info on this subject here: https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html

您可能会在此处找到有关此主题的更多有用信息:https: //itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html

回答by saran3h

If you want to revert a mergecommit, here is what you have to do.

如果你想恢复merge提交,这是你必须做的。

  1. First, check the git logto find your merge commit's id. You'll also find multiple parent ids associated with the merge (see image below).
  1. 首先,检查git log以找到您的合并提交的 ID。您还会发现与合并关联的多个父 ID(见下图)。

enter image description here

在此处输入图片说明

Note down the merge commit id shown in yellow. The parent IDs are the ones written in the next line as Merge: parent1 parent2. Now...

记下黄色显示的合并提交 ID。父 ID 是写在下一行中的那些Merge: parent1 parent2。现在...

Short Story:

短篇故事:

  1. Switch to branch on which the merge was made. Then Just do the git revert <merge commit id> -m 1which will open a viconsole for entering commit message. Write, save, exit, done!
  1. 切换到进行合并的分支。然后只需执行git revert <merge commit id> -m 1这将打开一个vi控制台以输入提交消息。写入,保存,退出,完成!

Long story:

很长的故事:

  1. Switch to branch on which the merge was made. In my case, it is the testbranch and I'm trying to remove the feature/analytics-v3branch from it.

  2. git revertis the command which reverts any commit. But there is a nasty trick when reverting a mergecommit. You need to enter the -mflag otherwise it will fail. From here on, you need to decide whether you want to revert your branch and make it look like exactly it was on parent1or parent2via:

  1. 切换到进行合并的分支。就我而言,它是test分支,我试图从中删除feature/analytics-v3分支。

  2. git revert是恢复任何提交的命令。但是在恢复merge提交时有一个讨厌的技巧。您需要输入-m标志,否则它将失败。从这里开始,您需要决定是否要恢复您的分支并使其看起来完全像它在parent1parent2通过:

git revert <merge commit id> -m 1(reverts to parent2)

git revert <merge commit id> -m 1(恢复为parent2

git revert <merge commit id> -m 2(reverts to parent1)

git revert <merge commit id> -m 2(恢复为parent1

You can git log these parents to figure out which way you want to go and that's the root of all the confusion.

你可以 git log 这些父母来找出你想要走的路,这就是所有混乱的根源。

回答by alexplain

I found creating a reverse patch between two know end-points and applying that patch would work. This presumes that you have created snapshots (tags) off of your master branch or even a back up of your master branch say master_bk_01012017.

我发现在两个已知端点之间创建一个反向补丁并应用该补丁会起作用。这假设您已经从 master 分支或什至 master 分支的备份创建了快照(标签),比如 master_bk_01012017。

Say the code branch you merged into master was mycodebranch.

假设您合并到 master 的代码分支是 mycodebranch。

  1. Checkout master.
  2. Create a full binary reverse patch between master and your backup. git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. Check your patch git apply --check myrevert.patch
  4. Apply patch with sign-off git am --signoff < myrevert.patch
  5. If you will need to bring in this code again once it is fixed, you will need to branch off the reverted master and checkout the fix branch git branch mycodebranch_fixgit checkout mycodebranch_fix
  6. Here you need to find the SHA key for the revert and revert the revert git revert [SHA]
  7. Now you can use your mycodebranch_fix to fix the issues, commit and re-merge into master once done.
  1. 结账师傅。
  2. 在主服务器和备份服务器之间创建一个完整的二进制反向补丁。 git diff --binary master..master_bk_01012017 > ~/myrevert.patch
  3. 检查你的补丁 git apply --check myrevert.patch
  4. 应用带有签名的补丁 git am --signoff < myrevert.patch
  5. 如果您在修复后需要再次引入此代码,则需要从恢复的 master 分支并签出 fix 分支 git branch mycodebranch_fixgit checkout mycodebranch_fix
  6. 在这里,您需要找到用于还原的 SHA 密钥并还原还原 git revert [SHA]
  7. 现在您可以使用 mycodebranch_fix 来修复问题,提交并在完成后重新合并到 master 中。