Почему git revert жалуется на отсутствующую опцию -m? - PullRequest
138 голосов
/ 12 мая 2011

Итак, я работаю над проектом с другими людьми, над которым работают несколько форков github. Кто-то просто исправил проблему, и я слился с его форком, но потом понял, что могу найти лучшее решение. Я хочу отменить коммит, который я только что сделал. Я попытался сделать это с git revert HEAD, но он выдал мне эту ошибку:

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

Что это значит? Когда я слил и зафиксировал, я использовал опцию -m, чтобы сказать «Объединено с ».

Что я здесь не так делаю?

Ответы [ 3 ]

156 голосов
/ 12 мая 2011

По умолчанию git revert отказывается отменить коммит слияния, так как это на самом деле означает неоднозначность.Я предполагаю, что ваш HEAD на самом деле является коммитом слияния.

Если вы хотите отменить коммит слияния, вы должны указать, какой родитель слияния вы хотите считать основным стволом, т.е.вы хотите вернуться к.

Часто это будет родительский номер один, например, если вы были на master и сделали git merge unwanted, а затем решили отменить слияние unwanted.Первым родителем будет ваша ветвь перед слиянием master, а вторым родителем будет кончик unwanted.

В этом случае вы можете сделать:

git revert -m 1 HEAD
40 голосов
/ 12 мая 2011

Скажем, другой парень создал панель поверх foo, но вы тем временем создали baz, а затем объединились, получив историю

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

Примечание: git lola - этонестандартный, но полезный псевдоним.

Никаких кубиков с git revert:

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

Чарльз Бейли, как обычно, дал отличный ответ .Использование 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

Но я подозреваю, что вы хотите выбросить слияниеcommit:

$ 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 reset,HEAD^ (или HEAD^1) - b7e7176, а HEAD^2 - c7256de, , т. Е. , соответственно, первый и второй родители коммита слияния.

Будьте осторожны с git reset --hard, потому чтоэто может разрушить работу.

6 голосов
/ 24 октября 2014

У меня была эта проблема, решение было посмотреть на график коммитов (используя 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, то есть того, к которому я хочу черри.

...