Я столкнулся с конфликтом слияния. Как я могу прервать слияние?

Я использовал git pull, и у меня возник конфликт слияния:

unmerged:   _widget.html.erb

You are in the middle of a conflicted merge.

Я знаю, что другая версия файла хороша, а моя плохая, поэтому от всех моих изменений следует отказаться. Как я могу это сделать?

Я понимаю, что это очень старый вопрос, но хотите ли вы прервать слияние весь и оставить ветвь, которую вы сливали, без объединения, или просто игнорируйте этот файл как часть более крупного слияния, позволяя всем другим файлам слиться как нормальный? Для меня ваш заголовок подразумевает первое, а тело вашего вопроса хочет второе. Ответы делают и то, и другое, не проясняя ситуацию.

rjmunro 07.10.2013 15:18

У меня был аналогичный случай при фиксации, говоря, что автоматическое слияние не удалось; исправить конфликты, а затем зафиксировать результат: [rejected] gh-pages -> gh-pages (non-fast-forward)

Chetabahana 30.04.2016 20:32

Гвин, было бы полезно выбрать здесь принятый ответ. Решение, получившее наибольшее количество голосов, немного менее безопасно, чем некоторые из более современных решений, поэтому я думаю, что это поможет выделить другие :)

Amicable 06.10.2016 16:11
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2 743
3
1 963 711
13

Ответы 13

Думаю именно git reset вам нужен.

Помните, что git revert означает нечто совсем иное, чем, скажем, svn revert - в Subversion откат отменяет ваши (незафиксированные) изменения, возвращая файл в текущую версию из репозитория, тогда как git revert «отменяет» фиксацию.

git reset должен выполнять аналог svn revert, то есть отбрасывать ваши нежелательные изменения.

Поскольку ваш pull был неудачным, HEAD (не HEAD^) является последним "действительным" коммитом в вашей ветке:

git reset --hard HEAD

Другая часть, которую вы хотите, - позволить их изменениям преобладать над вашими изменениями.

Более старые версии git позволяли использовать «их» стратегию слияния:

git pull --strategy=theirs remote_branch

Но с тех пор это было удалено, как объясняется в это сообщение Хунио Хамано (сопровождающий Git). Как отмечено в связь, вместо этого вы должны сделать это:

git fetch origin
git reset --hard origin

Вместо того, чтобы делать полный сброс, вы можете довести его до более детального уровня, выполнив: git fetch origin -> git reset origin (soft reset, your changes are still present) -> git checkout file_to_use_their_version_of another_file (steamroll your own changes back to match the origin) Я больше никогда не использую git pull. Поскольку в битве между моим последним кодом и источником всегда должно побеждать происхождение, я всегда использую git fetch и git rebase origin. Это фактически делает мои слияния и конфликты редкими и редкими.

Kzqai 13.05.2010 20:20

Я согласен. Я также предпочитаю сначала получить, а затем изучить восходящие изменения (git log ..@{upstream} или git diff ..@{upstream}). После этого я, как и вы, перебазирую свою работу.

Pat Notz 15.05.2010 03:26

В дополнение к этому я рекомендую запустить «git clean -f», если у вас еще остались неотслеживаемые файлы, которые вы хотите очистить.

lzap 11.03.2011 15:42

вместо git reset --hard origin у меня работал git branch -r (выберите название ветки), git reset --hard remote/branch.

EoghanM 10.05.2011 18:37

Как отмечалось в более позднем ответе, начиная с версии 1.6.1 можно использовать 'git reset --merge'

Matt Ball 23.01.2012 19:59

Я использовал git merge -X theirs remote_branch вместо git pull --strategy=theirs remote_branch, так как theirs выглядит как вариант recursive

mlt 02.07.2012 19:28

Стратегии theirs нет.

srcspider 04.04.2013 11:18

@mlt, theirs действительно является рекурсивным вариантом, он не существует как собственная стратегия (в текущем git), согласно документации.

Jon L. 23.02.2015 17:02

git merge --abort намного предпочтительнее.

Daniel Cassidy 24.02.2016 18:48

git fetch origin, а затем git reset --hard origin/master сделали свое дело. Кстати, я использую git версии 2.13.6 (Apple Git-96)

lnarasimhan 05.12.2017 02:43

@Kzqai Я использую git pull --rebase после того, как я локально зафиксировал (обычно исправляю, поэтому у меня есть 1 фиксация для каждой функции, по крайней мере, пока я не нажму) свои изменения.

juanmf 06.02.2020 10:50

Я хотел бы отметить для следующего бедняги, оказавшегося в моей ситуации, что, когда git merge --abort не работал, эти шаги работали.

sk8forether 24.10.2020 04:00

В этом конкретном случае вы действительно не хотите прерывать слияние, просто разрешите конфликт определенным образом.

Нет особой необходимости сбрасывать и выполнять слияние с другой стратегией. Конфликты были правильно выделены git, и требование принять изменения других сторон относится только к этому одному файлу.

Для несвязанного файла в конфликте git делает доступными общую базовую, локальную и удаленную версии файла в индексе. (Здесь они считываются для использования в инструменте 3-стороннего сравнения 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?

Peter 12.01.2010 11:30

@ Питер: Я не уверен. Желаемый результат достигается с помощью нескольких основных команд с простыми параметрами. Какие улучшения вы бы посоветовали?

CB Bailey 25.03.2010 14:58

Я думаю, что команда git 1.6.1 имеет большой смысл и хороша. Это именно то, чего я хотел. Я думаю, что решение до 1.6.1 неэлегантно и требует знаний о других частях git, которые следует отделить от процесса разрешения слияния. Но новая версия отличная!

Peter 27.03.2010 23:51

Если ваша версия 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 после завершения слияния или отмены его.

Интересно - но инструкция меня пугает. Когда именно целесообразно использовать? Когда нужно указывать дополнительный <commit>? #GitMoment: -o

conny 15.11.2011 08:36

Обычно вы используете это, когда хотите повторить слияние с самого начала. Мне никогда не приходилось указывать необязательную фиксацию самостоятельно, поэтому значение по умолчанию (без необязательного <commit>) вполне подойдет.

Carl 15.11.2011 23:53

Я бы хотел, чтобы за этот ответ было больше голосов! На данный момент это кажется наиболее подходящим решением во многих случаях.

Jay Taylor 08.12.2011 02:56

Даже с незафиксированными изменениями git смог восстановить состояние до слияния. Отлично!

T3rm1 12.06.2014 15:45

git merge --abort - это просто синоним git reset --merge? В названии, конечно, больше смысла, но есть ли у него те же функции?

Tikhon Jelvis 22.07.2014 22:37

git reset --merge спас мой бекон. Удивительный!

Ben Liyanage 27.01.2016 21:48

эй @ Карл, не могли бы вы удалить этот ответ? Это сбивает с толку многих, включая меня. git merge --abort - правильный ответ, и он должен быть вверху.

Riz 06.09.2016 20:43

git merge --abort не работает с конфликтом слияния осьминога, работает только git reset --merge.

ks1322 06.02.2017 18:22

@Riz: Какие доказательства вы предлагаете в поддержку своего утверждения?

Carl 14.08.2017 02:03

Альтернативой, которая сохраняет состояние рабочей копии, является:

git stash
git merge --abort
git stash pop

Я обычно не рекомендую этого делать, потому что это фактически похоже на слияние в Subversion, поскольку оно отбрасывает отношения веток в следующем коммите.

Я нашел этот подход полезным, когда случайно слился с веткой git-svn, которая с этим не справляется. При работе с ветвями отслеживания git-svn лучше использовать сквош-слияния или выбор вишни. Фактически мое решение превращает слияние в слияние в сквош постфактум.

Alain O'Dea 13.07.2010 22:58

Лучший ответ на вопрос

Fouad Boukredine 29.02.2020 04:36

Чем это будет отличаться от мягкого сброса? Мягкий сброс также сбрасывает репозиторий в исходное состояние, но не затрагивает рабочую копию.

Mecki 04.09.2020 17:53

Да, но приходит ли на ум «git reset --soft someref», когда ваша цель - «Как мне прервать слияние?». Как узнать, что использовать для someref? Следовательно, "git merge --abort", который делает правильные вещи и, очевидно, называется освежающим для Git.

Alain O'Dea 04.09.2020 17:56

Начиная с Git 1.6.1.3, git checkout может оформлять заказ с любой стороны слияния:

git checkout --theirs _widget.html.erb

git merge --abort

Abort the current conflict resolution process, and try to reconstruct the pre-merge state.

If there were uncommitted worktree changes present when the merge started, git merge --abort will in some cases be unable to reconstruct these changes. It is therefore recommended to always commit or stash your changes before running git merge.

git merge --abort is equivalent to git reset --merge when MERGE_HEAD is present.

http://www.git-scm.com/docs/git-merge

Это доступно с git v1.7.4. Это псевдоним для git reset --merge.

Michael Johnson 24.04.2013 19:41

Комментарии предполагают, что 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 намного эффективнее для сценариев, подобных описанному, и в целом неудачных слияний.

что здесь на самом деле подразумевается под «неудачным слиянием»? Слияние с конфликтами или еще что? Или перефразируя это: когда нет MERGE_HEAD? У меня следующий вопрос, чтобы лучше понять использование «git reset --merge».

Ewoks 28.09.2015 11:14

@Ewoks git stash apply вызвал у меня конфликт слияния, но git merge --abort не помог, а git reset --merge помог.

nitzel 06.12.2018 17:34

Я обнаружил, что у меня сработало следующее (вернуть один файл в состояние до слияния):

git reset *currentBranchIntoWhichYouMerged* -- *fileToBeReset*

Если вы столкнулись с конфликтом слияния и вам нечего зафиксировать, но по-прежнему отображается ошибка слияния. После применения всех нижеперечисленных команд,

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

Надеюсь, это поможет!!!

Sourcetree

Поскольку вы не фиксируете свое слияние, просто дважды щелкните другую ветку (что означает ее проверку), и когда sourcetree спросит вас об отмене всех изменений, тогда соглашайтесь :)

Обновлять

Я вижу много голосов против, но любое сообщение ... Я оставлю этот ответ, который адресован тем, кто использует SourceTree в качестве клиента git (как и я - когда я ищу решение для вопроса, заданного OP)

OP, очевидно, использует командную строку. Ваш пост не имеет ценности.

Adrian Bartholomew 15.12.2020 22:52

Я согласен с тем, что очевидно, что OP использует командную строку, но люди, которые не используют командную строку, а исходное дерево и имеют аналогичную проблему, находят этот вопрос вверху в Google (например, я) - поэтому для таких людей этот ответ имеет значение - вот почему Я оставил это здесь :)

Kamil Kiełczewski 16.12.2020 01:33

Для 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 ...

Другие вопросы по теме