Как мне завершить слияние после разрешения конфликтов слияния?


282

Я прочитал раздел « Основные ветвления и слияния » в Git Community Book.

Поэтому я следую его и создать одну ветвь: experimental.

Затем я:

  1. переключиться на экспериментальную ветку (git checkout экспериментальный)
  2. внести кучу изменений
  3. совершить это (git commit -a)
  4. переключиться на главную ветку (git checkout master)
  5. внести некоторые изменения и зафиксировать там
  6. переключиться обратно на экспериментальный (git checkout экспериментальный)
  7. изменение мастера слияния на экспериментальное (мастер слияния git)
  8. Есть некоторые конфликты, но после их разрешения я добавил «git add myfile»

  9. И теперь я застрял, я не могу вернуться к мастеру

когда я делаю

 $ git checkout master
error: Entry 'res/layout/my_item.xml' would be overwritten by merge. Cannot merge.

и я сделал:

$ git rebase --abort

Нет ребаз в прогрессе?

и я сделал :

$  git add res/layout/socialhub_list_item.xml
$ git checkout master
error: Entry 'res/layout/my_item.xml' would be overwritten by merge. Cannot merge.

Что я могу сделать, чтобы вернуться в свою основную ветку?


После того, как исправить конфликт, выполнить надстройку, а затем попытаться выполнить коммит git commit gf2n.cpp -m "Hand merge gf2n.cpp due to conflicts", это приводит fatal: cannot do a partial commit during a merge.. И, конечно же, «Частичные коммиты» , по-видимому, не документированы и не обсуждаются нигде на страницах руководства пользователя git. Выполнение git mergeпосле исправления приводит к тому, Please, commit your changes before you can merge.что инструмент «
Сломанная

2
git commit с явными путями задокументирован в man-странице в ОПИСАНИИ "как" 3. перечисляя файлы в качестве аргументов команды commit, и в этом случае commit игнорирует изменения, внесенные в индекс, и вместо этого записывает текущее содержимое перечисленных файлов (которое должно быть уже известно Git); ", а также под '- опция -only. Я почти уверен, что сообщение о слиянии было написано кем-то, кто предположил, что вы прочтете, как работает команда commit, и может распознать значение слова «частичный» в этом описании, если не уже, то по крайней мере снова и более осторожно. @jww
jthill

1
Итак, почему этот пример заслуживает внимательного прочтения для понимания, тогда как справочные материалы - нет? @jww
jthill

1
Что ж, использование git явно требует лучшего понимания прочитанного, чем вы готовы приобрести. Возможно, я даже более уверен, что это ошибка в git, чем вы уверены, что это так.
до

1
С Git 2.12 (Q1 2017) вы скоро просто сделаете git merge --continue. Смотрите мой ответ ниже
VonC

Ответы:


267

Когда во время слияния возникает конфликт, вы должны завершить слияние вручную. Похоже, вы сделали первые два шага, чтобы отредактировать конфликтующие файлы, а затем запустить git addих, чтобы пометить их как разрешенные. Наконец, вам нужно совершить слияние с git commit. В этот момент вы сможете снова переключать филиалы.


Если вы используете «git gui &» для фиксации - вы можете не осознавать, что ваше состояние ветки больше не «сливается». Получение «статуса git» полезно для проверки правильности статуса вашего филиала.
Тони Эшворт

4
Попробуйте git commit -am "your commit message"выполнить добавление и фиксацию одновременно.
Вахидс

3
git commitработает. И лучше всего использовать его, чтобы получить заполненное сообщение о коммитах по умолчанию. Я избегаю `git commit -am", так как он переопределит сообщение
Arijoon

1
Попробуй git push.
Alper

Я получил эту ситуацию в следующем сценарии -> Я слил X ветви с Y ветви. Затем я понял, что сделал что-то не так в ветви Y, поэтому я исправил это и затем «исправил» свои изменения в ветви Y. Из-за изменений git не создал новый коммит. Поэтому, когда я слил ветку X с обновленной веткой Y, это дало конфликт. Кстати, спасибо за этот ответ.
Дога

157

Как мне завершить слияние после разрешения конфликтов слияния?

С Git 2.12 (1 квартал 2017 года) у вас будет более естественная команда:

git merge --continue

Смотрите коммит c7d227d (15 декабря 2016 г.) Джеффа Кинга ( peff) .
См. Коммит 042e290 , коммит c261a87 , коммит 367ff69 (14 декабря 2016 г.) Крисом Пакхэмом ( cpackham) .
(Слиты Junio C Hamano - gitster- в фиксации 05f6e1b , 27 декабря 2016)

См. 2.12 примечания к выпуску .

merge: добавить --continueопцию ' ' как синоним для ' git commit'

Teach « git merge» --continueвариант , который позволяет «продолжающуюся» слияние, заполнив его.
Традиционный способ завершения слияния после разрешения конфликтов - использовать « git commit».
Теперь с такими командами, как ' git rebase' и ' git cherry-pick', имеющими --continueопцию ' ', добавление такой опции к ' git merge' представляет согласованный пользовательский интерфейс.


Я готовился опубликовать комментарий о том, как это было недавно добавлено в 2.12 в 1 квартале 2017 года, но затем я перечитал первую строку вашего ответа. Неудивительно, что вариант не был найден для меня в версии 2.10!
cjsimon

1
Я попробовал git merge --continue, и Git Bash не смог распознать это как команду. Но то, что сработало, было git commit -m "Записать сообщение"
Mimi

2
@Mimi ОК, но вы используете Git 2.12 или более?
VonC

@ VonC вы правы, я использую старую версию Git!
Мими

23

Если вы застряли во время слияния / перебазировки, вы всегда можете

git reset --hard

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


16
обязательное предупреждение: git reset --hardвыбрасывает незафиксированные изменения
Джеффри Хейл

2
Почему бы не просто git merge --abort, который не рискует что-либо потерять?
Александр Джордж

11

Просто git commit это.

Опционально git abortэто:
я столкнулся с конфликтом слияний. Как я могу прервать слияние?

Чтобы упростить жизнь с помощью слияний, установите kdiff3 и настройте его как mergetool. Инструкции: http://doodkin.com/2016/05/29/git-merge-easy-github-this-branch-has-conflicts-that-must-be-resolved-use-the-command-line/

Эта страница содержит это видео: https://www.youtube.com/watch?v=Cc4xPp7Iuzo


11

Всякий раз, когда вы объединяете две ветви с помощью команды git merge brancha branchb, есть две возможности:

  1. Одна ветвь (скажем, ветвь) может быть достигнута другой ветвью (скажем, ветвь b), следуя ее истории коммитов. В этом случае git просто перемотает вперед голову, чтобы указать на недавнюю ветвь (в этом случае ветвь b).

    2.Но если две ветви разошлись в какой-то более старой точке, то git создает новый снимок и добавляет новый коммит, который указывает на него. Таким образом, в случае отсутствия конфликта между ветвями, которые вы объединяете, git плавно создает новый коммит.

Запустите, git logчтобы увидеть фиксацию после объединения двух не конфликтующих веток.

Теперь вернемся к интересному случаю, когда между объединяющимися ветвями возникают конфликты слияния. Я цитирую это со страницы https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

Git не создал автоматически новый коммит слияния. Это приостановило процесс, пока вы разрешаете конфликт. Если вы хотите увидеть, какие файлы были объединены в любой момент после конфликта слияния, вы можете запуститьgit status


Таким образом, в случае возникновения конфликтов слияния, вам нужно разрешить конфликт, затем добавить изменения, которые вы внесли в промежуточную область, git add filenameи затем зафиксировать изменения с помощью команды, git commit которая была приостановлена ​​git из-за конфликта. Я надеюсь, что это объясняет вашу запрос. Также посетите ссылку выше для подробного понимания. В случае любого запроса, пожалуйста, прокомментируйте ниже, я буду рад помочь.


7

Следующие шаги после разрешения конфликтов вручную:

  1. мерзавец добавить.
  2. git status (это покажет вам, какие команды необходимы для продолжения процедуры автоматического слияния)
  3. [команда мерзавец предлагает, например git merge --continue, git cherry-pick --continue, git rebase --continue]

16
Там нет мерзкого слияния
Хола Сой Эду Фелиз Навидад

@HolaSoyEduFelizNavidad Это неверно. Выходные данные Zie git ниже после конфликта: - error: Failed to merge in the changes. Patch failed at 0001 ADD: _type to styleguide The copy of the patch that failed is found in: .git/rebase-apply/patch When you have resolved this problem, run "git rebase --continue". If you prefer to skip this patch, run "git rebase --skip" instead. To check out the original branch and stop rebasing, run "git rebase --abort".
Дружелюбный

5
Есть перебазировка - продолжить, не объединить
Hola Soy Edu Feliz Navidad

git merge --continue, что я пытаюсь сделать, приводит к error: unknown option 'continue'. Я уверен, что ваш ответ неверен, поскольку в git-mergeсправочной странице его нет. Какую версию Git вы используете? Я использую git version 1.8.5.2 (Apple Git-48). Я тоже пробовал с MacPorts git version 2.9.3.
jww

1
С git 2.10 для простого слияния команда просто стараяgit commit
Крис Чарабарук

2

Конфликт слияния возникает, когда две ветви, которые вы пытаетесь объединить, изменили одну и ту же часть одного и того же файла. Вы можете создать список конфликтов с git status.

При обнаружении конфликтующей строки Git будет редактировать содержимое затронутых файлов с помощью визуальных индикаторов, которые отмечают обе стороны конфликтующего содержимого.

<<<<<<< HEAD
conflicted text from HEAD
=======
conflicted text from merging_branch
>>>>>>> merging_branch

Когда вы исправите конфликтующие файлы и будете готовы к слиянию, все, что вам нужно сделать, это запустить git addи git commitсгенерировать коммит слияния. Как только коммит был сделан, git pushизменения в ветке.

Справочная статья: Git Merge .


2

После добавления всех файлов следующим шагом будет « git commit» ».

«git status» подскажет, что делать: файлы, которые еще нужно добавить, перечислены внизу, а после того, как они все закончат, он предложит коммит вверху, где он пояснит статус слияния текущей ветви.


1

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

Когда вы выполняете $ git merge, то на самом деле происходит то, что git пытается переслать вашу текущую ветку к коммиту, на который включена ветвь, на которую ссылаются (другими словами, оба имени ветки указывают на один и тот же коммит.) Этот сценарий самый простой для git иметь дело, так как нет нового коммита. Подумайте о том, как хозяин прыгает на лилипад, на котором сидит ваша ветвь. Можно установить флаг --no-ff, и в этом случае git создаст новый коммит независимо от того, были ли какие-либо конфликты кода.

В ситуации, когда существуют конфликты кода между двумя ветвями, которые вы пытаетесь объединить (обычно это две ветки, в которых история коммитов имеет общий коммит в прошлом), ускоренная перемотка вперед не будет работать. git все еще может автоматически объединять файлы, если одна и та же строка не была изменена обеими ветками в конфликтующем файле. в этом случае git объединит конфликтующие файлы для вас и автоматически зафиксирует их. Вы можете просмотреть, как это сделал git, выполнив $ git diff --cached. Или вы можете передать флаг --no-commit в команду merge, которая оставит измененные файлы в вашем индексе, которые вам нужно будет добавить и зафиксировать. Но вы можете $ git diff этих файлов, чтобы посмотреть, что изменится слияние.

Третий сценарий - это конфликты, которые git не может разрешить автоматически. В этом случае вам нужно будет объединить их вручную. На мой взгляд, это проще всего сделать с помощью слияния, например, слияния с араксисом или p4merge (бесплатно). В любом случае, вы должны сделать каждый файл по одному. Если слияние кажется застрявшим, используйте $ git merge --continue, чтобы подтолкнуть его вперед. Git должен сказать вам, если это не может продолжаться, и если так, то почему бы и нет. Если вы чувствуете, что в какой-то момент приостановили слияние, вы можете выполнить $ git merge --abort, и любое слияние будет отменено, и вы сможете начать все сначала. Когда вы закончите, каждый объединенный файл будет измененным файлом, который необходимо добавить и зафиксировать. Вы можете проверить, где находятся файлы со статусом $ git. Если вы еще не зафиксировали объединенные файлы. Вы должны сделать это, чтобы завершить слияние.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.