为什么git会抱怨缺少-m选项?

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

fatal: Commit <SHA1> is a merge but no -m option was given.

What does that mean? When I merged and committed, I did use the -m option to say "Merged with <username>".

What am I doing wrong here?

178507 次浏览

默认情况下,git revert拒绝恢复合并提交,因为它的实际含义是不明确的。我假设你的HEAD实际上是一个合并提交。

如果你想要恢复合并提交,你必须指定哪个合并的父节点你想要考虑作为主干线,也就是说你想要恢复到哪个节点。

通常这将是第一个父项,例如,如果你在master上执行了git merge unwanted,然后决定恢复unwanted的合并。第一个父结点将是你的预合并master分支,第二个父结点将是unwanted的尖端。

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

git revert -m 1 HEAD

git cat-file -p [MERGE_COMMIT_ID]将按顺序显示父分支。第一个是- m1,第二个是- m2。

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

$ git lola
*   2582152 (HEAD, master) Merge branch 'otherguy'
|\
| * c7256de (otherguy) bar
* | b7e7176 baz
|/
* 9968f79 foo

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

git revert不行:

$ git revert HEAD
fatal: Commit 2582152... is a merge but no -m option was given.

Charles Bailey像往常一样给出了优秀的答案。使用git revert作为

$ git revert --no-edit -m 1 HEAD
[master e900aad] Revert "Merge branch 'otherguy'"
0 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 bar

有效地删除bar并生成

$ git lola
* e900aad (HEAD, master) Revert "Merge branch 'otherguy'"
*   2582152 Merge branch 'otherguy'
|\
| * c7256de (otherguy) bar
* | b7e7176 baz
|/
* 9968f79 foo

但我怀疑你想扔掉合并提交:

$ git reset --hard HEAD^
HEAD is now at b7e7176 baz


$ git lola
* b7e7176 (HEAD, master) baz
| * c7256de (otherguy) bar
|/
* 9968f79 foo

git rev-parse手册

< p > __ABC0,例如HEAD^, v1.5.1^0 < br > 修订形参的后缀^表示该提交对象的第一个父对象。^<n>表示第__abc6个父类(即。 <rev>^相当于<rev>^1)。作为一个特殊规则,<rev>^0表示提交本身,当<rev>是引用提交对象的标记对象的对象名时使用

因此在调用git reset之前,HEAD^(或HEAD^1)是b7e7176, HEAD^2是c7256de, 即。,分别是合并提交的第一个和第二个父节点。

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

我有这个问题,解决方案是查看提交图(使用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进行合并,这就是我想要选择的对象。

在最初的问题中,git错误的“-m选项”可能错误地表示提交消息。正如在其他答案中解释的那样,使用'-m n'指定merge的第n个父节点,以选择您认为是主干线的父节点。