Как отменить фиксацию слияния, которая уже была перенесена в удаленную ветку?
git revert <commit_hash>
один не будет работать. -m
должен быть указан, и я довольно смущен этим.
Кто-нибудь испытывал это раньше?
Ответы
Ответ 1
Опция -m
указывает родительский номер. Это потому, что коммит слияния имеет более одного родителя, и Git не знает автоматически, какой родитель был основной линией, и какой родитель был ветвью, которую вы хотите удалить -m erge.
Когда вы увидите коммит слияния в выводе git log
, вы увидите его родителей в строке, начинающейся с Merge
:
commit 8f937c683929b08379097828c8a04350b9b8e183
Merge: 8989ee0 7c6b236
Author: Ben James <[email protected]>
Date: Wed Aug 17 22:49:41 2011 +0100
Merge branch 'gh-pages'
Conflicts:
README
В этой ситуации git revert 8f937c6 -m 1
вернет вам дерево, как это было в 8989ee0
, а git revert -m 2
восстановит дерево, как это было в 7c6b236
.
Чтобы лучше понять родительские идентификаторы, вы можете запустить:
git log 8989ee0
а также
git log 7c6b236
Ответ 2
Вот полный пример в надежде, что он кому-то поможет:
git revert -m 1 <commit-hash>
git commit -m "Reverting the last commit which messed the repo."
git push -u origin master
Где <commit-hash>
- хеш фиксации слияния, который вы хотели бы вернуть, и, как указано в объяснении этого ответа, -m 1
указывает, что вы должны вернуться к дереву первого родителя до слияния.
Строка git commit ...
по существу совершает ваши изменения, в то время как третья строка делает ваши изменения общедоступными, нажимая их на удаленную ветвь.
Ответ 3
Бен рассказал вам, как вернуть фиксацию слияния, но очень важно, что вы понимаете, что это делает "заявляет, что вы никогда не захотите, чтобы изменения дерева были внесены слиянием. В результате, более поздние слияния приведут только к изменениям дерева, введенным коммитами, которые не являются предками ранее восстановленного слияния. Это может быть или не быть тем, что вы хотите". (git -merge man page).
An сообщение о статье/списке рассылки, связанное с man-страницей, детализирует механизмы и соображения, которые задействованы. Просто убедитесь, что вы понимаете, что если вы вернете фиксацию слияния, вы не можете просто снова слить ветку и ожидать, что те же изменения вернутся.
Ответ 4
Вы можете выполнить следующие шаги, чтобы вернуть неверные фиксации или reset удаленной ветки назад, чтобы исправить состояние HEAD/.
- проверка удаленной ветки на локальное репо.
git checkout development
-
скопировать хеш фиксации (то есть идентификатор коммита непосредственно перед неправильной фиксацией) из журнала git
git log -n5
вывод:
commit 7cd42475d6f95f5896b6f02e902efab0b70e8038" Объединить ветвь "неправильно-совершить" в "развитие" "
commit f9a734f8f44b0b37ccea769b9a2fd774c0f0c012 "это неправильная фиксация "
commit 3779ab50e72908da92d2cfcd72256d7a09f446ba "это правильная фиксация"
-
reset ветвь на хеш фиксации, скопированная на предыдущем шаге
git reset <commit-hash> (i.e. 3779ab50e72908da92d2cfcd72256d7a09f446ba)
- запустите
git status
, чтобы показать все изменения, которые были частью неправильной фиксации.
- просто запустите
git reset --hard
, чтобы вернуть все эти изменения.
- принудительно удалите локальную ветку на удаленную станцию и обратите внимание, что ваша история фиксации чиста, поскольку она была до того, как она загрязнилась.
git push -f origin development
Ответ 5
git revert -m 1 <merge-commit>
Ответ 6
Чтобы сохранить журнал в чистоте, так как ничего не произошло (с некоторыми недостатками при таком подходе (из-за push -f)):
git checkout <branch>
git reset --hard <commit-hash-before-merge>
git push -f origin HEAD:<remote-branch>
'commit-hash-before-merge' приходит из журнала (git log) после слияния.
Ответ 7
Иногда наиболее эффективным способом отката является откат и замена.
git log
Использовать 2-х хеш-хеш (полный хеш, тот, который вы хотите вернуть назад, до того, как произошла ошибка), а затем снова отбросить его.
git checkout -b newbranch <HASH>
Затем удалите старую ветку, скопируйте новую ветку на место и перезапустите оттуда.
git branch -D oldbranch
git checkout -b oldbranch newbranch
Если он был передан, а затем удалите старую ветку из всех репозиториев, перетащите ветвь redone на самую центральную и верните ее ко всем.
Ответ 8
Я нашел создание обратного патча между двумя знающими конечными точками и применение этого патча. Это предполагает, что вы создали моментальные снимки (теги) у своей основной ветки или даже резервные копии вашей основной ветки say master_bk_01012017.
Скажите, что ветвь кода, которую вы объединили в master, была mycodebranch.
- Мастер проверки.
- Создайте полный двоичный обратный патч между мастером и вашей резервной копией.
git diff --binary master..master_bk_01012017 > ~/myrevert.patch
- Проверьте свой патч
git apply --check myrevert.patch
- Применить патч с выпиской
git am --signoff < myrevert.patch
- Если вам понадобится снова ввести этот код после его исправления, вам нужно будет отделить возвращенный мастер и проверить его ветвь
git branch mycodebranch_fix
git checkout mycodebranch_fix
- Здесь вам нужно найти SHA-ключ для возврата и вернуть обратно
git revert [SHA]
- Теперь вы можете использовать mycodebranch_fix для исправления проблем, фиксации и повторного слияния с мастером после выполнения.
Ответ 9
Правильно отмеченный ответ сработал для меня, но мне пришлось потратить некоторое время, чтобы определить, что происходит.. Поэтому я решил добавить ответ с простыми простыми шагами для случаев, подобных моему..
Допустим, у нас есть ветки A и B.. Вы слили ветвь A в ветвь B и подтолкнули ветвь B к себе, так что теперь слияние является частью этого... Но вы хотите вернуться к последнему коммиту перед слиянием.. Что делать ты сделаешь?
- Перейдите в корневую папку git (обычно это папка проекта) и используйте
git log
-
Вы увидите историю последних коммитов - коммиты имеют свойства commit/author/date, а слияния также имеют свойство merge - так что вы видите их так:
commit: <commitHash> Merge: <parentHashA> <parentHashB> Author: <author> Date: <date>
-
Используйте git log <parentHashA>
и git log <parentHashB>
- вы увидите истории коммитов этих родительских веток - первые коммиты в списке самые последние
- Возьмите
<commitHash>
коммита, который вы хотите, перейдите в корневую папку git и используйте git checkout -b <newBranchName> <commitHash>
- это создаст новую ветку, начиная с последнего коммита, который вы выбрали перед слиянием. Вуаля, готово!
Ответ 10
git doc о git revert -m предоставьте ссылку, чтобы объяснить это: https://github.com/git/git/blob/master/Documentation/howto/revert-a-faulty-merge.txt
Ответ 11
Все ответы уже охватывали большинство вещей, но я добавлю свои 5 центов. Короче говоря, отменить коммит слияния довольно просто:
git revert -m 1 <commit-hash>
Если у вас есть разрешение, вы можете отправить его прямо в "главную" ветку, в противном случае просто переместите его в свою "возвратную" ветку и создайте запрос на извлечение.
Вы можете найти более полезную информацию по этому вопросу здесь: https://itcodehub.blogspot.com/2019/06/how-to-revert-merge-in-git.html
Ответ 12
Если вы хотите отменить коммит merge
, вот что вам нужно сделать.
- Сначала проверьте
git log
чтобы найти идентификатор фиксации слияния. Вы также найдете несколько родительских идентификаторов, связанных с объединением (см. Изображение ниже).
Запишите идентификатор фиксации слияния, показанный желтым цветом. Родительские идентификаторы - это те, которые записаны в следующей строке как Merge: parent1 parent2
. Сейчас...
Короткий рассказ:
- Переключитесь на ветку, на которой было произведено слияние. Затем просто выполните команду
git revert <merge commit id> -m 1
которая откроет консоль vi
для ввода сообщения фиксации. Написать, сохранить, выйти, готово!
Длинная история:
-
Переключитесь на ветку, на которой было произведено слияние. В моем случае это test
ветка, и я пытаюсь удалить из нее ветку feature/analytics-v3
.
-
git revert
- это команда, которая отменяет любой коммит. Но при отмене коммита merge
есть неприятный трюк. Вам необходимо ввести флаг -m
иначе он потерпит неудачу. С этого parent1
вам нужно решить, хотите ли вы вернуть свою ветку и сделать так, чтобы она выглядела точно так, как это было на parent1
или parent2
помощью:
git revert <merge commit id> -m 1
(возвращается к parent2
)
git revert <merge commit id> -m 2
(возвращается к parent1
)
Вы можете git войти эти родители, чтобы выяснить, какой путь вы хотите пойти и что корень всей путаницы.
Ответ 13
Как отметил Райан, git revert
может затруднить слияние в будущем, поэтому git revert
может быть не таким, каким вы хотите. Я обнаружил, что использование команды git reset --hard <commit-hash-prior-to-merge>
более полезно здесь.
Как только вы выполните жесткую часть reset, вы можете принудительно нажать на удаленную ветвь, т.е. git push -f <remote-name> <remote-branch-name>
, где <remote-name>
часто называют origin
. С этого момента вы можете повторно объединить, если хотите.