Как объединить конфликты Git в Emacs


84

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

Вопрос : есть ли способ, которым Emacs может поддерживать слияние, используя информацию, доступную в Git, о моей версии, их версии и базовой версии файла?


Изменить: этот вопрос имеет другую область, чем этот связанный вопрос , так как он не ограничивается вызовом ediff.


7
Если бы вы использовали Magit, вы могли бы загрузить буфер состояния и затем нажать eна файлы, показанные как конфликтующие. Magit запустит ediffпроцесс слияния и предложит вам подтвердить изменения, после чего вы сможете создать объединенный файл.
wvxvw

@ Начинающий: 3 других человека думали, что это дубликат, и я был последним голосом. Почему: другая упомянутая ветка дает такие же ответы ( smergeи vc-resolve-conflict, как и один на ediff) и была дольше. Я согласен с тем, что первая тема может использовать лучший заголовок.
Дан

@ Дан, я не согласен: это другой вопрос, и то, что ответ похож, ничего не меняет.
начинающих

1
@IqbalAnsari: я думаю, что другой теме нужен более качественный заголовок, чтобы людям было легче его найти. На самом деле, я думаю, что название темы для начинающих было бы хорошо для этого. Тем не менее, давайте немного подождем, чтобы узнать, захотят ли люди снова открыть эту ветку. Если нет, я бы высказался за переименование первой темы с названием «Начинающий».
Дан

1
И для чего это стоит, я думаю, что это хороший вопрос с хорошими ответами. Просто я также считаю, что это дубликат, но другие могут не разделить это мнение (то есть о дублировании).
Дан

Ответы:


86

Вы можете попробовать smerge-modeпросто открыть конфликтующий файл и сделать M-xsmerge-modeRET. Здесь будут освещены все конфликтующие регионы. Он также добавляет сочетания клавиш, чтобы легко разрешать конфликты, ознакомьтесь с документацией, C-hfsmerge-modeRETчтобы узнать их.

Префикс по умолчанию

Я нахожу префикс по умолчанию для smerge-mode C-c^громоздких, поэтому я изменил его на C-cv

(setq smerge-command-prefix "\C-cv")

Важные сочетания клавиш

Для меня самые важные привязки:

smerge-nextобязан smerge-command-prefixnперейти к следующему конфликту.

smerge-previousобязан smerge-command-prefixpперейти к предыдущему конфликту.

smerge-keep-currentобязан smerge-command-prefixRETсохранить версию, в которой находится курсор.

smerge-keep-mineобязан smerge-command-prefixmсохранить ваши изменения.

smerge-keep-otherобязан smerge-command-prefixoсохранить другие изменения.

smerge-ediffобязан smerge-command-prefixEначать сеанс ediff, чтобы объединить конфликты. Это так же, как vc-resolve-conflicts(спасибо @phils и @Malabarba за то, что указал на это).

Включение режима smerge автоматически

ОБНОВЛЕНИЕ: Следующее относится только к предыдущим версиям Emacs 25.1, следующее может вызвать проблемы в более поздних версиях, см. Https://github.com/magit/magit/issues/3897

Кроме того, вам может быть интересно автоматическое включение smerge-modeпри посещении файла / буфера с маркерами конфликта, вы можете использовать что-то вроде следующего для достижения этой цели

(defun my-enable-smerge-maybe ()
  (when (and buffer-file-name (vc-backend buffer-file-name))
    (save-excursion
      (goto-char (point-min))
      (when (re-search-forward "^<<<<<<< " nil t)
        (smerge-mode +1)))))

(add-hook 'buffer-list-update-hook #'my-enable-smerge-maybe)

Обратите внимание, что я использую, buffer-list-update-hookи нет, find-file-hookтак как в большинстве случаев я получаю конфликты в буфере, который уже открыт в Emacs, и в этом случае find-file-hookэто не поможет.

Также проверьте другие методы, упомянутые в этом ответе


1
(1) Не забывай smerge-ediff. (2) На какой версии Emacs вы работаете? В текущей основной ветке emacs smerge включается автоматически. (3) Почему вы используете buffer-list-update-hookвместо find-file-hook?
Малабарба

Для дополнительного уточнения обратите внимание, что smerge-ediffи vc-resolve-conflictsэто одно и то же.
Филс

@Malabarba 1) Я упоминал, что smerge-modeсочетания клавиш документированы в документации. Возможно я могу процитировать руководство здесь для полноты. Спасибо за ответ. 2) Я нахожусь на v24.5, хотя иногда я пробую основную ветку, я не помню, чтобы smerge поворачивался автоматически (это недавнее изменение?). 3) Это потому, что в большинстве случаев я получаю конфликты в уже открытых буферах, и в этом случае мне нужно явно включитьsmerge-mode
Iqbal Ansari

@IqbalAnsari есть ли причина, по которой вы не включали smerge-modeвсе время? Возможно, это не так много, пока не будет вызвано.
PythonNut

@PythonNut Хороший вопрос, к сожалению, у меня нет ответа, так как я никогда не пытался держать его включенным постоянно, хотя стоит попробовать
Икбал Ансари

33

Изменить: так как этот ответ получил больше голосов, чем я ожидал, я немного расширил его.

Чтобы дополнить ответ @IqbalAnsari, вы также можете использовать vc-resolve-conflicts(как уже упоминалось, это псевдоним smerge-ediff). Это запустит ediffинтерфейс. Слева будет первый родитель слияния, а второй родитель слияния справа. Они помечены на моделине с MINEи OTHERсоответственно. Объединенный буфер показан ниже (см. Скриншот).

Снимок экрана интерфейса <code> ediff </ code>

Сочетания клавиш

  • Перейдите через конфликты с nи p.
  • Принять версии с aили b.
  • Посмотри на предка с /!
  • Выйти из сеанса Ediff с q.

Вы также можете перейти к объединенному буферу other-windowи отредактировать вручную в случае, если разрешение конфликта более сложно, чем принятие версии. Когда вы закончите, вы можете сохранить буфер и выйти из Emacs как обычно. Для получения дополнительной помощи, просто используйте ?во время ediffсеанса, там есть целый ряд очень полезных команд. Я до сих пор не знаю, что половина из них делает!


2
Это самый хороший метод ИМО. Я связан с этим C-x v <, хотя на практике я с большей вероятностью буду вызывать его с помощью Magit (согласно комментарию wvxvw).
Филс

1
Поскольку 2000 год vc-resolve-conflictявляется псевдонимом для smerge-ediff, который, как следует из названия, начинает сеанс Ediff, а не сеанс Emerge. Кстати, заголовок библиотеки ediff.elподтверждает emerge.elвлияние s, а затем продолжает: «Текущая версия Ediff заменяет Emerge. Он предоставляет превосходный пользовательский интерфейс и имеет множество основных функций, которых нет в Emerge. В частности, он может выполнять исправления и Двухстороннее и трехстороннее сравнение файлов, слияние и операции с каталогами. "
Tarsius

6
Также обратите внимание, что magit-ediff-resolve( Emили eдля файла с конфликтами) используется smerge-ediffвнутренне. Это, однако, переопределяет, ediff-quit-hookчтобы обеспечить немного лучший опыт завершения сеанса. Вместо того, чтобы сказать вам, что вы можете сохранить «буфер» (есть несколько буферов), он спрашивает вас, хотите ли вы сохранить буфер (показывая вам его имя).
Tarsius

Есть ли способ показать 4 окна (наше, родительское, их рабочее пространство), например vimdiff?
user1133275

9

Если вы используете Spacemacs, я бы порекомендовал активировать «smerge-transient-mode», который вызывает меню гидры со всеми возможными командами smerge.

Для этого просто вызовите Mx spacemacs/smerge-transient-state/body, который по умолчанию назначен для SPC-g-r.

Вот скриншот:

введите описание изображения здесь

Редактирование вашего файла должно быть интуитивно понятным:

  1. Нажмите, nчтобы перейти к следующему фрагменту.
  2. Выберите действие слияния .
  3. Повторите, пока не сделано.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.