Предотвратить мерзкие конфликтные маркеры
Я посмотрел довольно тщательно, найти ответ на этот вопрос и тоже не смог. Есть ли простой способ предотвратить добавление маркерами конфликтов в конфликтующие файлы при слиянии git? Я бы хотел, чтобы git не добавлял "<<<< ==== -----" при конфликте в файле.
Я попытался использовать двоичные файлы gitattributes, поскольку думал, что это не изменит содержимое файла, но безуспешно. Есть идеи?
Ура!
2 ответа
Учитывая ваши комментарии, вы должны настроить Beyond Compare как mergetool
вместо того, чтобы вручную открывать файлы с конфликтами. Убедитесь, что вы можете запустить bc3
в терминале первым. Затем вы можете настроить его так (в Linux):
git config --global merge.tool bc3
git config --global mergetool.bc3.trustExitCode true
Теперь, когда вы столкнетесь с конфликтом, просто запустите
git mergetool
открыть конфликтующие файлы в Beyond Compare.
Более подробную информацию и инструкции для других операционных систем можно найти на их сайте поддержки: https://www.scootersoftware.com/support.php?zz=kb_vcs.
Цель, если файл находится в конфликте,
1) сделать так, чтобы git пометил файл как "находящийся в конфликте", и
2) уметь использовать Beyond Compare между неотправленными версиями файла ("наша" версия и "их" версия).
Я предупреждаю, что, хотя это будет хорошо работать в простых случаях, это несколько отрицательно сказывается на подходе трехстороннего слияния, который обычно используется (т. Е. Вы не смотрите на изменения в контексте базы слияния), поэтому в некоторых случаях в более сложных случаях это будет не так просто. (По этой причине я бы рекомендовал ознакомиться с более "стандартным" подходом к разрешению конфликтов, чтобы вы могли, по крайней мере, воспользоваться им при необходимости.)
Но, безусловно, есть несколько способов сделать это. Самое простое - начать слияние нормально
git checkout our_branch
git merge their_branch
а затем, когда он конфликтует, верните дерево работы в "нашу" версию
git checkout --ours path/to/conflicted/file
Если вы настроили Beyond Compare для работы в качестве инструмента сравнения, вы можете пропустить оформление заказа и просто
git diff our_branch their_branch -- path/to/conflicted/file
но недостатком здесь является то, что у BC не будет открытой рабочей версии файла, поэтому у вас может не быть поддержки, которую вы хотите для непосредственного редактирования.
Таким образом, другой вариант, более сложный в настройке, но более автоматический в использовании, заключается в настройке собственного драйвера слияния. Пользовательский драйвер слияния включается всякий раз, когда изменяются и "наша" версия, и "их" версия данного файла (относительно "базовой" версии). Это скрипт, который получает в качестве параметров имена временных файлов, представляющих различные версии файла. Он создает (предварительный) результат слияния по пути для "нашей" версии и возвращает состояние, указывающее, возникли ли конфликты.
Драйверы слияния описаны в документации merge
атрибут (по адресу https://git-scm.com/docs/gitattributes). Это также показывает, что, учитывая настроенный драйвер слияния, вы бы связали его с файлом (-ами) по заданному пути (-ям) с .gitattributes
файл. (Вы можете связать его со всеми путями в вашем репо с записью для *
, но если в вашем репозитории могут содержаться двоичные файлы, вы можете либо избежать этого, либо позаботиться о том, чтобы сценарий драйвера вел себя разумно и для двоичных файлов.)
Сам скрипт попытался бы выполнить нормальное слияние
git merge-file -p <ours> <base> <theirs> > <temp-path>
(где <ours>
, <base>
, а также <theirs>
из параметров сценариев, и <temp-path>
это новый временный файл). Если эта команда возвращает 0 (без конфликтов), сценарий переместит вывод (<temp-path>
) поверх "нашей" версии и вернет 0. В противном случае он удалит временный файл, оставит "наши" без изменений и вернет ненулевое значение.
Это сделало бы ваши слияния такими же, как при первом подходе, за исключением того, что вы можете пропустить git checkout --ours
, Это может не стоить того. Но преимущество этого решения в том, что вы можете использовать его, чтобы сделать немного больше.
Проблема со всеми вышеупомянутыми решениями состоит в том, что если файл содержит какие-либо конфликты, то ни одно из изменений (включая не конфликтующие изменения) для этого файла не будет автоматически объединено. Вы должны обработать весь файл вручную (с Beyond Compare или любым другим).
Вы можете уточнить скрипт драйвера слияния так, чтобы в случае конфликта он повторно запускал слияние с --ours
вариант стратегии
git merge-file --ours <ours> <base> <theirs>
(Вы бы все равно хотели бежать без --ours
вариант, чтобы вы знали, если какие-либо конфликты произошли. Если есть конфликты, то вы удалите временный файл, запустите снова --ours
вариант - но без -p
или перенаправление вывода - и снова вернуть ненулевое значение, чтобы git знал, что произошел конфликт.)
Наконец, обратите внимание, что это не следует путать с тем, что происходит, если вы просто запустите команду слияния либо с -s ours
(который полностью игнорирует содержимое другой ветки) или -X ours
(который разрешает конфликты в пользу "нашей" версии и не сообщает о конфликтах).