Я использовал 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 --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 togit reset --merge
whenMERGE_HEAD
is 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 ...
Я понимаю, что это очень старый вопрос, но хотите ли вы прервать слияние весь и оставить ветвь, которую вы сливали, без объединения, или просто игнорируйте этот файл как часть более крупного слияния, позволяя всем другим файлам слиться как нормальный? Для меня ваш заголовок подразумевает первое, а тело вашего вопроса хочет второе. Ответы делают и то, и другое, не проясняя ситуацию.