246

所以我正在和其他人一起做一个项目,并且有多个 github 分支正在开发中。有人刚刚解决了一个问题,我与他的 fork 合并,但后来我意识到我可以找到更好的解决方案。我想恢复我刚刚所做的提交。我尝试这样做,git revert HEAD但它给了我这个错误:

致命:提交 <SHA1> 是一个合并,但没有给出 -m 选项。

这意味着什么?当我合并并提交时,我确实使用了 -m 选项来表示“与 <用户名> 合并”。

我在这里做错了什么?

4

4 回答 4

298

默认情况下git revert拒绝恢复合并提交,因为这实际上意味着不明确。我认为您HEAD实际上是合并提交。

如果你想恢复合并提交,你必须指定你想考虑的合并的哪个父主干,即你想恢复到什么。

通常这将是第一个父级,例如,如果您在master并且做了git merge unwanted然后决定恢复unwanted. 第一个父级将是您的合并前master分支,第二个父级将是unwanted.

在这种情况下,您可以这样做:

git revert -m 1 HEAD

git cat-file -p [MERGE_COMMIT_ID]将按顺序显示父分支。列出的第一个是 -m 1,第二个是 -m 2。

于 2011-05-11T21:48:44.530 回答
56

假设另一个人在 foo 之上创建了 bar,但你同时创建了 baz 然后合并,给出了历史

$ 混帐萝拉
* 2582152 (HEAD, master) 合并分支 'otherguy'
|\  
| * c7256de (otherguy) 酒吧
* | b7e7176 巴兹
|/  
* 9968f79 富

注意:git lola是一个非标准但有用的别名。

没有骰子git revert

$ git 还原头
致命:提交 2582152... 是一个合并,但没有给出 -m 选项。

查尔斯·贝利像往常一样给出了出色的答案。使用git revert

$ git revert --no-edit -m 1 HEAD
[master e900aad] 恢复“合并分支 'otherguy'”
 0 个文件更改,0 个插入 (+),0 个删除 (-)
 删除模式100644吧

有效地删除bar并产生历史

$ 混帐萝拉
* e900aad (HEAD, master) 恢复“合并分支 'otherguy'”
* 2582152 合并分支'otherguy'
|\  
| * c7256de (otherguy) 酒吧
* | b7e7176 巴兹
|/  
* 9968f79 富

但我怀疑您想丢弃合并提交:

$ git reset --hard HEAD^
HEAD 现在位于 b7e7176 baz

$ 混帐萝拉
* b7e7176(头,主)baz
| * c7256de (otherguy) 酒吧
|/  
* 9968f79 富

git rev-parse手册中所述

<rev>^,例如 HEAD^,v1.5.1^0
修订参数 的后缀^表示该提交对象的第一个父级。^<n>表示第n个父级( <rev>^等效于<rev>^1)。作为特殊规则,<rev>^0表示提交本身,并且在<rev>引用提交对象的标记对象的对象名称时使用。

所以在调用之前git resetHEAD^(或HEAD^1)是 b7e7176 和HEAD^2c7256de,分别是合并提交的第一个和第二个父级。

小心,git reset --hard因为它会破坏工作。

于 2011-05-11T22:20:08.293 回答
9

我遇到了这个问题,解决方案是查看提交图(使用 gitk),看看我有以下内容:

*   commit I want to cherry-pick (x)
|\  
| * branch I want to cherry-pick to (y)
* | 
|/  
* common parent (x)

我现在明白我想做

git cherry-pick -m 2 mycommitsha

这是因为-m 1将基于公共父-m 2级合并,而基于分支 y 的合并,那是我想要挑选的那个。

于 2014-10-24T12:56:49.493 回答
2

在最初的问题中,git 错误的“-m 选项”可能被误认为是提交消息。如其他答案中所述,使用“-m n”指定合并的第 n 个父级以选择您认为是主干的父级。

于 2021-05-19T11:20:58.027 回答