所以我正在和其他人一起做一个项目,有多个github分叉正在进行中。有人刚刚修复了一个问题,我就和他的叉子合并了,但后来我意识到我可以找到更好的解决方案。我想要恢复我刚刚做的提交。我尝试用git revert HEAD这样做,但它给了我这个错误:
fatal: Commit <SHA1> is a merge but no -m option was given.
这是什么意思?当我合并和提交,我确实使用-m选项说“合并与<用户名>”。
我哪里做错了?
所以我正在和其他人一起做一个项目,有多个github分叉正在进行中。有人刚刚修复了一个问题,我就和他的叉子合并了,但后来我意识到我可以找到更好的解决方案。我想要恢复我刚刚做的提交。我尝试用git revert HEAD这样做,但它给了我这个错误:
fatal: Commit <SHA1> is a merge but no -m option was given.
这是什么意思?当我合并和提交,我确实使用-m选项说“合并与<用户名>”。
我哪里做错了?
当前回答
假设另一个人在foo上面创建了bar,但你同时创建了baz,然后合并,给出了历史
$ git lola * 2582152 (HEAD, master) Merge branch 'otherguy' |\ | * c7256de (otherguy) bar * | b7e7176 baz |/ * 9968f79 foo
注意:git lola是一个非标准但有用的别名。
没有骰子与git恢复:
$ git revert HEAD fatal: Commit 2582152... is a merge but no -m option was given.
查尔斯·贝利像往常一样作了精彩的回答。使用git还原
$ git revert --no-edit -m 1 HEAD [master e900aad] Revert "Merge branch 'otherguy'" 0 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 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手册中所记录的那样
<rev>^,例如HEAD^, v1.5.1^0 对修订形参加上后缀^表示该提交对象的第一个父对象。^<n>表示第n个父结点(即<rev>^等同于<rev>^1)。作为一个特殊规则,<rev>^0表示提交本身,当<rev>是引用提交对象的标记对象的对象名时使用。
所以在调用git重置之前,HEAD^(或HEAD^1)是b7e7176, HEAD^2是c7256de,即分别是合并提交的第一个和第二个父节点。
小心git重置——很难,因为它会破坏工作。
其他回答
在最初的问题中,git错误的“-m选项”可能错误地表示提交消息。正如在其他答案中解释的那样,使用'-m n'指定merge的第n个父节点,以选择您认为是主干线的父节点。
默认情况下,git revert拒绝恢复合并提交,因为这实际上意味着模棱两可。我假设你的HEAD实际上是一个合并提交。
如果你想要恢复合并提交,你必须指定哪个合并的父节点你想要考虑作为主干线,也就是说你想要恢复到哪个节点。
通常情况下,这将是第一个父节点,例如,如果你在master上,git合并了不想要的,然后决定恢复不想要的合并。第一个父分支将是合并前的主分支,第二个父分支将是不需要的尖端。
在这种情况下,你可以这样做:
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 lola是一个非标准但有用的别名。
没有骰子与git恢复:
$ git revert HEAD fatal: Commit 2582152... is a merge but no -m option was given.
查尔斯·贝利像往常一样作了精彩的回答。使用git还原
$ git revert --no-edit -m 1 HEAD [master e900aad] Revert "Merge branch 'otherguy'" 0 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 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手册中所记录的那样
<rev>^,例如HEAD^, v1.5.1^0 对修订形参加上后缀^表示该提交对象的第一个父对象。^<n>表示第n个父结点(即<rev>^等同于<rev>^1)。作为一个特殊规则,<rev>^0表示提交本身,当<rev>是引用提交对象的标记对象的对象名时使用。
所以在调用git重置之前,HEAD^(或HEAD^1)是b7e7176, HEAD^2是c7256de,即分别是合并提交的第一个和第二个父节点。
小心git重置——很难,因为它会破坏工作。
我有这个问题,解决方案是查看提交图(使用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
这是因为- m1会基于公共父结点进行合并而- m2则基于分支y进行合并,这就是我要选择的。