git revert <commit_hash>
单独使用不起作用。显然,必须指定-m
。
git revert -m
中,-m
选项指定了父级编号。这是必需的,因为合并提交具有多个父级,并且 Git 不知道哪个父级是主干,哪个父级是您想要取消合并的分支。git log
的输出中查看合并提交时,您将在以 Merge
开头的行上列出其父级:commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <ben@example.com>
Date: Wed Aug 17 22:49:41 2011 +0100
Merge branch 'gh-pages'
Conflicts:
README
git diff 8989ee0 8f937c6
并且
git diff 7c6b236 8f937c6
8989ee0
和 7c6b236
中,应该选择哪一个?我应该如何理解这个问题? - Arup Rakshitgit log 8989ee0
和 git log 7c6b236
,你就应该知道答案了。 - BMW这是一个完整的示例:
git revert -m 1 <commit-hash>
git push -u origin master
git revert ...
撤销你的更改。
-m 1
表示您要撤消合并之前第一个父提交的树,如此答案所述。
<commit-hash>
是您想要撤销的合并的提交哈希。
git push ...
将您的更改推送到远程分支。
git revert
命令已经提交了所创建的提交对象。如果不想发生这种情况,你需要输入--no-commit
标志。 - Delficrevert
命令包括一个提交。 - Will Sheppardgit revert -m 1 <merge-commit>
1
以及何时不使用的答案。 - cellepogit checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>
'commit-hash-before-merge'来自合并之后的日志(git log)。
push -f
。 - Baptiste Mille-Mathiasgit log
来确定合并前的提交哈希不是一件简单的事情,因为提交会随着时间交织在一起 - 我想知道这是否总是 MERGECOMMIT^
(这似乎表明是 https://www.git-tower.com/learn/git/faq/undo-git-merge/#using-span-classmonospaced-boldgit-resetspan-to-undo-a-merge)? - John Bachir所有回答已经覆盖了大部分内容,但我会加上我的五分钱。简而言之,还原合并提交非常简单:
git revert -m 1 <commit-hash>
如果您有权限,可以直接推送到“master”分支;否则,请将其推送到您的“revert”分支并创建拉取请求。
您可能会在此主题上找到更有用的信息:https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html
git log
使用第二个提交哈希值(完整哈希值,在列出错误之前要还原回去的那个)然后从那里重新分支。
git checkout -b newbranch <HASH>
然后删除旧分支,在其位置上复制新分支并从那里重新开始。git branch -D oldbranch
git checkout -b oldbranch newbranch
如果已经广播过了,那么就从所有的存储库中删除旧分支,将重新做的分支推送到最核心的位置,再将其拉回所有存储库。merge
提交,请按以下步骤进行操作。
git log
以找到合并提交的 ID。您还会发现与合并相关的多个父 ID(见下面的图片)。记下显示为黄色的合并提交 ID。父 ID 是下一行中写成 Merge: parent1 parent2
的那些。现在...
简短地说:
git revert <merge commit id> -m 1
命令,这将打开一个 vi
控制台以输入提交消息。编写、保存、退出,完成!详细地说:
切换到进行合并的分支。在我的情况下,它是 test
分支,我正在尝试从中删除 feature/analytics-v3
分支。
git revert
是撤消任何提交的命令。但是,当撤消一个 merge
提交时有一个讨厌的技巧。您需要输入 -m
标志,否则它将失败。从这里开始,您需要决定是否要还原分支,并使其看起来像是在 parent1
或 parent2
上完全一样:
git revert <merge commit id> -m 1
(还原到parent2
)
git revert <merge commit id> -m 2
(还原到parent1
)
你可以用 git log 查看这些父提交,以确定想要回滚的方向,这是所有混淆的根源。
我从这个链接中找到了有关“如何撤消合并”的好解释,下面是我复制粘贴的解释。如果下面的链接无法使用,它可能会有所帮助。
如何撤销错误的合并 Alan(alan@clueserver.org) 说:
我有一个主分支,在此基础上我们建立了一个分支供一些开发人员进行工作。他们声称已经准备好。我们将其合并到主分支中,但它破坏了某些东西,因此我们撤消了合并。然后他们对代码进行了更改。他们将其调整到了一个可以接受的状态,我们再次合并。但检查后发现,在撤消之前所做的代码更改不在主分支中,而之后的更改却在主分支中,请求帮助从这种情况中恢复。
“合并撤消”后的历史记录如下:
---o---o---o---M---x---x---W
/
---A---B
其中 A 和 B 是在较差的侧面开发中,M 是将这些早期更改合并到主干的合并,x 是与侧面分支无关的更改,已经在主干上进行了,而 W 是“撤销合并 M”(W 是否倒置 M?)。 换句话说,“diff W^..W”类似于“diff -R M^..M”。
可以使用以下命令进行这样的合并“撤销”:
$ git revert -m 1 M 在侧面分支的开发人员修复错误后,历史记录可能如下所示:
---o---o---o---M---x---x---W---x
/
---A---B-------------------C---D
其中C和D是为了修复A和B中出现的问题,而在W之后,您可能已经对主线进行了其他更改。
如果您合并更新后的侧分支(其顶部为D),则A或B中所做的任何更改都不会出现在结果中,因为它们被W撤销了。这就是Alan看到的。
Linus解释了情况:
撤销一个常规提交只是有效地撤消该提交所做的事情,并且相当简单。但是,撤消合并提交还会撤消该提交更改的数据,但绝对不会影响合并对历史的影响。因此,合并仍将存在,并被视为连接两个分支的最后共享状态,未修复的合并也不会对此产生影响。因此,“撤消”取消数据更改,但在版本库历史记录上,它绝对不是“撤消”操作。因此,如果您认为“撤消”就是“撤销”,那么您总是会忽略掉撤消的这一部分。是的,它撤销了数据,但不,它没有撤销历史记录。在这种情况下,您希望首先撤消先前的撤消,这将使历史记录如下所示:
---o---o---o---M---x---x---W---x---Y
/
---A---B-------------------C---D
其中,Y是W的还原。可以通过以下方式进行“还原的还原”:
$ git revert W (假设W和W..Y更改之间不存在冲突)这个操作将使历史记录等同于在历史记录中根本没有W或Y:
---o---o---o---M---x---x-------x----
/
---A---B-------------------C---D
合并旁支后,不会出现早期还原和还原还原所引起的冲突。
---o---o---o---M---x---x-------x-------*
/ /
---A---B-------------------C---D
当然,对C和D所做的更改仍可能与任何x所做的更改冲突,但这只是普通的合并冲突。
git
的设计与每个人都使用的git-flow
工作流不匹配。如果你已经检出了develop
分支,那么你肯定想要还原引入错误的 2 次提交的特性分支,而不是多年共享的开发分支。感觉需要用-m 1
来选择它非常荒谬。 - pkamb