Я использовал git pull, и у меня возник конфликт слияния:
unmerged: _widget.html.erb
You are in the middle of a conflicted merge.
Я знаю, что другая версия файла хороша, а моя плохая, поэтому от всех моих изменений следует отказаться. Как я могу это сделать?
У меня был аналогичный случай при фиксации, говоря, что автоматическое слияние не удалось; исправить конфликты, а затем зафиксировать результат: [rejected] gh-pages -> gh-pages (non-fast-forward)
Гвин, было бы полезно выбрать здесь принятый ответ. Решение, получившее наибольшее количество голосов, немного менее безопасно, чем некоторые из более современных решений, поэтому я думаю, что это поможет выделить другие :)





Думаю именно 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. Это фактически делает мои слияния и конфликты редкими и редкими.
Я согласен. Я также предпочитаю сначала получить, а затем изучить восходящие изменения (git log ..@{upstream} или git diff ..@{upstream}). После этого я, как и вы, перебазирую свою работу.
В дополнение к этому я рекомендую запустить «git clean -f», если у вас еще остались неотслеживаемые файлы, которые вы хотите очистить.
вместо git reset --hard origin у меня работал git branch -r (выберите название ветки), git reset --hard remote/branch.
Как отмечалось в более позднем ответе, начиная с версии 1.6.1 можно использовать 'git reset --merge'
Я использовал git merge -X theirs remote_branch вместо git pull --strategy=theirs remote_branch, так как theirs выглядит как вариант recursive
Стратегии theirs нет.
@mlt, theirs действительно является рекурсивным вариантом, он не существует как собственная стратегия (в текущем git), согласно документации.
git merge --abort намного предпочтительнее.
git fetch origin, а затем git reset --hard origin/master сделали свое дело. Кстати, я использую git версии 2.13.6 (Apple Git-96)
@Kzqai Я использую git pull --rebase после того, как я локально зафиксировал (обычно исправляю, поэтому у меня есть 1 фиксация для каждой функции, по крайней мере, пока я не нажму) свои изменения.
Я хотел бы отметить для следующего бедняги, оказавшегося в моей ситуации, что, когда git merge --abort не работал, эти шаги работали.
В этом конкретном случае вы действительно не хотите прерывать слияние, просто разрешите конфликт определенным образом.
Нет особой необходимости сбрасывать и выполнять слияние с другой стратегией. Конфликты были правильно выделены 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?
@ Питер: Я не уверен. Желаемый результат достигается с помощью нескольких основных команд с простыми параметрами. Какие улучшения вы бы посоветовали?
Я думаю, что команда git 1.6.1 имеет большой смысл и хороша. Это именно то, чего я хотел. Я думаю, что решение до 1.6.1 неэлегантно и требует знаний о других частях git, которые следует отделить от процесса разрешения слияния. Но новая версия отличная!
Если ваша версия 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
Обычно вы используете это, когда хотите повторить слияние с самого начала. Мне никогда не приходилось указывать необязательную фиксацию самостоятельно, поэтому значение по умолчанию (без необязательного <commit>) вполне подойдет.
Я бы хотел, чтобы за этот ответ было больше голосов! На данный момент это кажется наиболее подходящим решением во многих случаях.
Даже с незафиксированными изменениями git смог восстановить состояние до слияния. Отлично!
git merge --abort - это просто синоним git reset --merge? В названии, конечно, больше смысла, но есть ли у него те же функции?
git reset --merge спас мой бекон. Удивительный!
эй @ Карл, не могли бы вы удалить этот ответ? Это сбивает с толку многих, включая меня. git merge --abort - правильный ответ, и он должен быть вверху.
git merge --abort не работает с конфликтом слияния осьминога, работает только git reset --merge.
@Riz: Какие доказательства вы предлагаете в поддержку своего утверждения?
Альтернативой, которая сохраняет состояние рабочей копии, является:
git stash
git merge --abort
git stash pop
Я обычно не рекомендую этого делать, потому что это фактически похоже на слияние в Subversion, поскольку оно отбрасывает отношения веток в следующем коммите.
Я нашел этот подход полезным, когда случайно слился с веткой git-svn, которая с этим не справляется. При работе с ветвями отслеживания git-svn лучше использовать сквош-слияния или выбор вишни. Фактически мое решение превращает слияние в слияние в сквош постфактум.
Лучший ответ на вопрос
Чем это будет отличаться от мягкого сброса? Мягкий сброс также сбрасывает репозиторий в исходное состояние, но не затрагивает рабочую копию.
Да, но приходит ли на ум «git reset --soft someref», когда ваша цель - «Как мне прервать слияние?». Как узнать, что использовать для someref? Следовательно, "git merge --abort", который делает правильные вещи и, очевидно, называется освежающим для Git.
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 --abortwill 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 --abortis equivalent togit reset --mergewhenMERGE_HEADis present.
http://www.git-scm.com/docs/git-merge
Это доступно с git v1.7.4. Это псевдоним для 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 намного эффективнее для сценариев, подобных описанному, и в целом неудачных слияний.
что здесь на самом деле подразумевается под «неудачным слиянием»? Слияние с конфликтами или еще что? Или перефразируя это: когда нет MERGE_HEAD? У меня следующий вопрос, чтобы лучше понять использование «git reset --merge».
@Ewoks git stash apply вызвал у меня конфликт слияния, но git merge --abort не помог, а git reset --merge помог.
Я обнаружил, что у меня сработало следующее (вернуть один файл в состояние до слияния):
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, очевидно, использует командную строку. Ваш пост не имеет ценности.
Я согласен с тем, что очевидно, что OP использует командную строку, но люди, которые не используют командную строку, а исходное дерево и имеют аналогичную проблему, находят этот вопрос вверху в Google (например, я) - поэтому для таких людей этот ответ имеет значение - вот почему Я оставил это здесь :)
Для 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 ...
Я понимаю, что это очень старый вопрос, но хотите ли вы прервать слияние весь и оставить ветвь, которую вы сливали, без объединения, или просто игнорируйте этот файл как часть более крупного слияния, позволяя всем другим файлам слиться как нормальный? Для меня ваш заголовок подразумевает первое, а тело вашего вопроса хочет второе. Ответы делают и то, и другое, не проясняя ситуацию.