Я столкнулся с конфликтом слияний. Как я могу прервать слияние?
Я использовал git pull
и был конфликт слияния:
unmerged: _widget.html.erb
You are in the middle of a conflicted merge.
Я знаю, что другая версия файла хороша, а моя - плоха, поэтому все мои изменения должны быть отменены. Как я могу это сделать?
17 ответов
Так как ваш pull
был неудачным тогда HEAD
(не HEAD^
) последний "действительный" коммит в вашей ветке:
git reset --hard HEAD
Другая часть, которую вы хотите, это позволить их изменениям перевесить ваши изменения.
Более старые версии git позволяли вам использовать "их" стратегию слияния:
git pull --strategy=theirs remote_branch
Но с тех пор это было удалено, как объяснено в этом сообщении Джунио Хамано (сопровождающий Git). Как отмечено в ссылке, вместо этого вы должны сделать это:
git fetch origin
git reset --hard origin
Если ваша версия git>= 1.6.1, вы можете использовать git reset --merge
,
Также, как упоминает @Michael Johnson, если ваша версия git>= 1.7.4, вы также можете использовать git merge --abort
,
Как всегда, убедитесь, что у вас нет незафиксированных изменений, прежде чем начинать слияние.
Со страницы руководства git merge
git merge --abort
эквивалентно git reset --merge
когда MERGE_HEAD
настоящее.
MERGE_HEAD
присутствует, когда выполняется слияние.
Также относительно непринятых изменений при запуске слияния:
Если у вас есть изменения, которые вы не хотите фиксировать перед началом слияния, просто git stash
их до слияния и git stash pop
после завершения слияния или отмены.
git merge --abort
Прервите текущий процесс разрешения конфликтов и попытайтесь восстановить состояние перед объединением.
Если в начале объединения произошли незафиксированные изменения рабочего дерева,
git merge --abort
в некоторых случаях не сможет восстановить эти изменения. Поэтому рекомендуется всегда фиксировать или хранить ваши изменения перед запуском git merge.
git merge --abort
эквивалентноgit reset --merge
когдаMERGE_HEAD
настоящее.
Это так просто.
git merge --abort
Сам Git показывает вам решение, когда вы находитесь в такой ситуации и запускаете команду git status.
git status
Надеюсь, это поможет людям.
Я думаю, что это git reset
тебе нужно.
Остерегайтесь этого git revert
означает что-то совсем другое, скажем, svn revert
- в Subversion возврат отменяет ваши (незафиксированные) изменения, возвращая файл в текущую версию из репозитория, тогда как git revert
"отменяет" коммит
git reset
должен сделать эквивалент svn revert
откажитесь от нежелательных изменений.
Для git >= 1.6.1:
git merge --abort
Для более старых версий git это будет работать:
git reset --merge
или
git reset --hard
Вы можете прервать этап слияния:
git merge --abort
иначе вы можете сохранить свои изменения (на какой ветке вы находитесь)
git checkout --ours file1 file2 ...
в противном случае вы можете сохранить другие изменения ветки
git checkout --theirs file1 file2 ...
В этом конкретном случае вы не хотите прерывать слияние, просто разрешите конфликт определенным образом.
Также нет особой необходимости сбрасывать и выполнять слияние с другой стратегией. Git правильно выделил конфликты, и требование принять изменения других сторон относится только к этому файлу.
Для необработанного файла в конфликте git делает доступной общую базовую, локальную и удаленную версии файла в индексе. (Здесь они читаются для использования в инструменте 3-way diff git mergetool
.) Ты можешь использовать git show
просматривать их.
# common base:
git show :1:_widget.html.erb
# 'ours'
git show :2:_widget.html.erb
# 'theirs'
git show :3:_widget.html.erb
Самый простой способ разрешить конфликт - использовать дословно удаленную версию:
git show :3:_widget.html.erb >_widget.html.erb
git add _widget.html.erb
Или с git >= 1.6.1:
git checkout --theirs _widget.html.erb
Для такого сценария я сделал git fetch
а также git pull
, затем понял, что восходящая ветвь не является главной, что привело к нежелательным конфликтам.
git reset --merge
Это вернулось обратно без сброса моих локальных изменений.
Поскольку комментарии предполагают, что git reset --merge
это псевдоним для git merge --abort
Стоит отметить, что git merge --abort
только эквивалентно git reset --merge
учитывая, что MERGE_HEAD
настоящее. Это можно прочитать в справке git для команды слияния.
git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.
После неудачного слияния, когда нет MERGE_HEAD
неудачное слияние может быть отменено git reset --merge
но не обязательно с git merge --abort
Таким образом, они не только старый и новый синтаксис для одного и того же.
Лично я нахожу git reset --merge
гораздо более мощный для сценариев, подобных описанному, и неудачных слияний в целом.
И если вы в конечном итоге столкнулись с конфликтом слияния и не имеете каких-либо обязательств, но ошибка слияния отображается после применения всех перечисленных ниже команд,
git reset --hard HEAD
git pull --strategy=theirs remote_branch
git fetch origin
git reset --hard origin
пожалуйста, удалите
.git\index.lock
файл [вырезать вставить в другое место в случае восстановления], а затем введите любую из следующих команд в зависимости от того, какую версию вы хотите.
git reset --hard HEAD
git reset --hard origin
Надеюсь, это поможет!!!
Альтернатива, которая сохраняет состояние рабочей копии:
git stash
git merge --abort
git stash pop
Я вообще советую против этого, потому что это фактически похоже на слияние в Subversion, поскольку оно отбрасывает отношения ветвления в следующем коммите.
Возможно, это не то, что хотел OP, но я попытался объединить стабильную ветку с функциональной веткой, и было слишком много конфликтов. Мне не удалось сбросить изменения, так как HEAD был изменен многими коммитами, поэтому простым решением было принудительное оформление заказа в стабильную ветку. затем вы можете оформить заказ в другую ветку, и все будет так, как было до слияния.
git checkout -f master
git checkout side-branch
Начиная с Git 1.6.1.3 git checkout
удалось оформить заказ с любой стороны слияния:
git checkout --theirs _widget.html.erb
Чтобы избежать подобных неприятностей, можно подробнее рассказать о
git merge --abort
подойти и создать отдельную тестовую ветку перед слиянием .
Дело : У вас есть тема ветвь, она не слилась , потому что вы отвлеклись / кое - что придумал / вы знаете , но есть (или был) готов.
Теперь можно объединить это в мастер?
Поработайте в тестовой ветке, чтобы оценить / найти решение, затем откажитесь от тестовой ветки и примените решение в тематической ветке.
# Checkout the topic branch
git checkout topic-branch-1
# Create a _test_ branch on top of this
git checkout -b test
# Attempt to merge master
git merge master
# If it fails you can abandon the merge
git merge --abort
git checkout -
git branch -D test # we don't care about this branch really...
Работайте над разрешением конфликта.
# Checkout the topic branch
git checkout topic-branch-1
# Create a _test_ branch on top of this
git checkout -b test
# Attempt to merge master
git merge master
# resolve conflicts, run it through tests, etc
# then
git commit <conflict-resolving>
# You *could* now even create a separate test branch on top of master
# and see if you are able to merge
git checkout master
git checkout -b master-test
git merge test
Наконец, снова проверьте ветку темы, примените исправление из тестовой ветки и продолжите PR. Наконец, удалите тест и мастер-тест.
Вовлеченный? Да, но это не повлияет на мою тему или основную ветку, пока я не буду готов.
Я обнаружил, что следующее работает для меня (вернуть один файл в состояние перед объединением):
git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*
Sourcetree
Поскольку вы не фиксируете свое слияние, просто дважды щелкните другую ветку (что означает ее проверку), и когда sourcetree спросит вас об отмене всех изменений, соглашайтесь:)