仅使用git-restore<commit_hash>是行不通的。显然,必须指定-m。


当前回答

接受的答案和其他一些答案演示了如何使用git-restore命令还原合并提交。然而,对于父提交存在一些混淆。这篇文章旨在通过一个图形表示和一个真实的例子来阐明这一点。

还原合并提交不像git revert<commit hash>那样简单,因为git在从合并提交返回时会因为两个父提交而感到困惑。要指定所需的父级,请使用-m标志。由于git无法确定哪个父级是主线,哪个分支是要自动取消合并的分支,因此必须指定此项。

iss53分支被合并到master中,创建了一个合并提交C6。C6有两个父母C5和C4。

需要恢复C6并将存储库恢复到C4的状态。因此,它必须指定要用于revert命令的父级。

为此,请检查git日志(此处表示实际的提交哈希值和图中的代码名称)>git日志提交C6合并:C4 C5作者:Mozz<mozz@example.com>日期:2月29日星期三23:59:59 2020+0100将分支“iss53”合并到主分支...从git日志输出中,记下Merge:--附带的父ID。它的格式为Merge:parent1 parent2,此处为Merge:C4 C5。C4提交在主分支中,我们需要恢复到它,即父1,这里需要-m1(使用gitlogC4验证先前的提交以确认父分支)。切换到进行合并的分支(这里是主分支,我们的目标是从中删除iss53分支)使用-m 1标志执行git还原。#在主分支中恢复到C4数字还原C6-m 1#C6-是合并提交哈希

对于一些其他情况,

# revert to C5 in iss53 branch
git revert C6 -m 2

# General
git revert <merge commit id> -m 1 (reverts to parent1)
git revert <merge commit id> -m 2 (reverts to parent2)
# remember to check and verify the parent1 and parent2 with git log command.

实际示例

在只有主分支的现有项目上创建了一个新的分支还原测试,提交图现在看起来像这样。

(对于提交的图形化视图,请使用带有git-log[SO ans-ref]的-graph或这个更具交互性的VS代码扩展-git-grraph)

现在,我已经添加了一些新文件,修改了现有文件,并在每个分支上创建了单独的提交,然后将它们推送到源。图形现在看起来如下:

然后,从GitHub创建一个拉取请求,并将恢复测试分支合并到main。

我想撤消合并提交并返回到主分支中的最后一次提交,即12a7327

注意,合并提交-2ec06d9现在有两个父级-12a7327(在主级)和15bde47(在还原测试中),现在检查gitlog,

> git log

commit 2ec06d9d315a3f7919ffe4ad2c2d7cec8c8f9aa3 (HEAD -> main, origin/main, origin/HEAD)
Merge: 12a7327 15bde47
Author: Akshay <63786863+akshay@users.noreply.github.com>
Date:   Sun Feb 5 00:41:13 2023 +0530

    Merge pull request #1 from Akshay/revert-test
    
    Revert test

要恢复合并提交并返回到12a7327需要执行的操作,

# To the First parent
git revert 2ec06d9 -m 1

现在,编辑器中将显示一条提交消息,指定详细信息、检查和验证。

因此,这将创建一个Revert提交,该提交执行合并提交的反向更改。

最后推送更改,现在合并提交更改消失,日志将如下所示:,

其他回答

为了保持日志的整洁(这种方法有一些缺点(由于push-f)):

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

“合并前提交哈希”来自合并后的日志(gitlog)。

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

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

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

下面是一个完整的示例:

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

git还原。。。提交您的更改。

-m1表示您希望在合并之前恢复到第一个父级的树,如下面的答案所述。<commit hash>是要还原的合并的提交哈希。

git推。。。将更改推送到远程分支。

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

注意:此解决方案仅适用于您自己的分支,而不适用于共享的树枝

签出远程分支到本地回购。git签出您的branch_name从git日志中复制提交哈希(即错误提交前的提交id)git日志-n5

应该显示如下内容:

提交7cd42475d6f95f5896b6f02e902efab0b70e8038“合并分支“错误提交”到“your_branch_name”“提交”f9a734f8f44b0b37ccea769a2fd774c0f0c012“这是错误的提交”提交3779ab50e72908da92d2cfcd72256d7a09f444ba“这是正确的提交“

将分支重置为上一步中复制的提交哈希git reset<commit hash>(即3779ab50e72908da92d2cfcd72256d7a09f444ba)运行gitstatus以显示错误提交中的所有更改。只需运行gitreset——很难还原所有这些更改。强制将您的本地分支推到远程,并注意到您的提交历史记录与被污染之前一样干净。git push-f origin your_branch_name

-m1是被修复的当前分支的最后一个父级,-m2是合并到其中的分支的原始父级。

如果命令行令人困惑,Tortoise Git也可以在这里提供帮助。