commit 14f41939956d80b9e17bb8721354c33f8d5b5a79
Merge: f1270f7 e3eb223
Author: Scott Chacon
Date: Fri Sep 19 18:14:49 2014 +0200
Merge branch 'mundo'
Conflicts:
hello.rb
diff --cc hello.rb
index 0399cd5,59727f0..e1d0799
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
#! /usr/bin/env ruby
def hello
- puts 'hola world'
- puts 'hello mundo'
++ puts 'hola mundo'
end
hello()
Теперь когда вы знаете как создать коммит слияния, вы можете сделать ее по ошибке. Одна из замечательных вещей в работе с Git – это то, что ошибки совершать не страшно, так как есть возможность исправить их (и в большинстве случаев сделать это просто).
Коммит слияния не исключение. Допустим, вы начали работать в тематической ветке, случайно слили ее в master, и теперь ваша история коммитов выглядит следующим образом:

Рисунок 2. Случайный коммит слияния
Есть два подхода к решению этой проблемы, в зависимости от того, какой результат вы хотите получить.
Если нежелаемый коммит слияния существует только в вашем локальном репозитории, то простейшее и лучшее решение состоит в перемещении веток так, чтобы они указывали туда куда вам нужно. В большинстве случаев, если вы после случайного git merge выполните команду git reset --hard HEAD~, то указатели веток восстановятся так, что будут выглядеть следующим образом:

Рисунок 3. История после git reset --hard HEAD~
Мы рассматривали команду reset ранее в Раскрытие тайн reset, поэтому вам должно быть не сложно разобраться с тем, что здесь происходит. Здесь небольшое напоминание: reset --hard обычно выполняет три шага:
1. Перемещает ветку, на которую указывает HEAD. В данном случае мы хотим переместить master туда, где она была до коммита слияния (C6).
2. Приводит индекс к такому же виду что и HEAD.
3. Приводит рабочую директорию к такому же виду, что и индекс.
Недостаток этого подхода состоит в изменении истории, что может привести к проблемам в случае совместно используемого репозитория. Загляните в Опасности перемещения, чтобы узнать что именно может произойти; кратко говоря, если у других людей уже есть какие-то из изменяемых вами коммитов, вы должны отказаться от использования reset. Этот подход также не будет работать, если после слияния уже был сделан хотя бы один коммит; перемещение ссылки фактически приведет к потере этих изменений.
Если перемещение указателей ветки вам не подходит, Git предоставляет возможность сделать новый коммит, которая откатывает все изменения, сделанные в другой. Git называет эту операцию “восстановлением” (“revert”), в данном примере вы можете вызвать ее следующим образом:
$git revert -m 1 HEAD
[master b1d8379] Revert "Merge branch 'topic'"
Опция -m 1 указывает какой родитель является “основной веткой” и должен быть сохранен. Когда вы выполняете слияние в HEAD (git merge topic), новый коммит будет иметь двух родителей: первый из них HEAD (C6), а второй – вершина ветки, которую сливают с текущей (C4). В данном случае, мы хотим отменить все изменения, внесенные слиянием родителя #2 (C4), и сохранить при этом всё содержимое из родителя #1 (C6).
История с коммитом восстановления (отменой коммита слияния) выглядит следующим образом:

Рисунок 4. Итория после git revert -m 1
Новый коммит ^M имеет точно такое же содержимое как C6, таким образом, начиная с нее всё выглядит так, как будто слияние никогда не выполнялось, за тем лишь исключением, что “теперь уже не слитые” коммиты всё также присутствуют в истории HEAD. Git придет в замешательство, если вы вновь попытаетесь слить topic в ветку master:
$git merge topic
Already up-to-date.
В ветке topic нет ничего, что еще недоступно из ветки master. Плохо, что в случае добавления новых наработок в topic, при повторении слияния Git добавит только те изменения, которые были сделаны после отмены слияния:

Рисунок 5. История с плохим слиянием
Лучшим решением данной проблемы является откат коммита отмены слияния, так как теперь вы хотите внести изменения, которые были отменены, а затемсоздание нового коммита слияния:
Читать дальше