Параметры слияния
Обычное слияние — это одна кнопка, и в большинстве случаев на этом история заканчивается. Эта страница — про остальные случаи: лок-файл, который конфликтует при каждом слиянии; файл, который кто-то переформатировал по отступам; вендоренный проект, у которого пути не совпадают. Ключи для всех трёх ситуаций есть в git уже много лет — просто они закопаны в man-странице, которую никто не открывает посреди конфликта.
Правый клик по ветке → Слияние с параметрами… — и в строках веток и удалённых
веток в боковой панели, и на цветных бейджах ссылок в графе, у которых общий
блок меню, — либо ⌘K → Слияние с параметрами.

Команда печатается по мере того, как вы её собираете. Она нужна, чтобы сверить её с документацией — и чтобы в следующий раз запустить из терминала, без этого диалога.
Когда ханк конфликтует
| Выбор | Флаг | Что означает |
|---|---|---|
| Остановиться и спросить меня | — | По умолчанию. Разрешаете вы |
| Оставить сторону этой ветки | -X ours |
Спорные ханки разрешаются в пользу того, что уже выгружено |
| Взять входящую сторону | -X theirs |
Спорные ханки разрешаются в пользу приходящей ветки |
-X ours — это не -s ours. Здешний ключ решает судьбу только тех ханков,
которые действительно конфликтуют; все прочие изменения из другой ветки
сливаются как обычно. Стратегия под названием ours — которую Gitcito не
предлагает — берёт ваше дерево целиком и выбрасывает другую сторону, порождая
коммит слияния, который заявляет, что содержит работу, которой в нём нет. Это
различие — самое непонятое место во всей теме слияний в git.
Он не может решить всё. Конфликт «изменено/удалено» — одна сторона
отредактировала файл, другая его удалила — это не конфликт содержимого, и -X
оставляет его вам. И правильно: не существует такой версии «предпочитать наше»,
которая ответила бы, должен ли удалённый файл вернуться.
Пробелы
| Выбор | Флаг |
|---|---|
| Игнорировать изменения в существующих пробелах | -X ignore-space-change |
| Игнорировать пробелы полностью | -X ignore-space-at-eol, -X ignore-all-space |
Случай, ради которого это существует: одна ветка переставила отступы в файле (или это сделал форматтер), другая отредактировала те же строки. Git видит две правки одной строки и останавливается. Если пробелы игнорируются, переформатирование перестаёт быть изменением, которое надо взвешивать, и настоящая правка проходит.
Результат сохраняет пробелы другой стороны на затронутых ею строках, так что прогнать после этого форматтер — неплохая мысль.
Что записать
| Выбор | Флаг | С чем вы останетесь |
|---|---|---|
| Fast-forward, когда возможно | — | Коммит слияния только там, где история разошлась |
| Всегда делать коммит слияния | --no-ff |
Коммит слияния даже при fast-forward, так что ветка навсегда останется видимой в графе |
| Только fast-forward, иначе отказ | --ff-only |
Ничем, если понадобилось бы настоящее слияние. Полезно как проверка |
| Squash | --squash |
Изменениями в индексе, слияние не записано, коммит пишете вы |
| Слить, но не коммитить | --no-commit |
Слиянием в индексе и в процессе — можно сначала осмотреть или поправить |
Squash и --no-commit — не одно и то же. Squash вообще забывает, что слияние
было: git не записывает второго родителя, и в следующий раз ветка будет выглядеть
несмёрженной. --no-commit — это слияние в процессе, которое просто ждёт вас:
MERGE_HEAD установлен, и коммит завершает его обычным образом.
--ff-only не падает молча. Если понадобился бы коммит слияния, git
отказывается и ничего не сдвигается — именно это и делает его хорошей проверкой
здравого смысла перед скриптованным слиянием.
Стратегия
| Стратегия | Для чего |
|---|---|
По умолчанию (ort) |
Для всего. Современное трёхстороннее слияние git |
subtree |
Две стороны живут по разным путям — проект, вендоренный в подкаталог этого |
resolve |
Старое трёхстороннее слияние. Иногда справляется там, где ort сдаётся на перекрёстной истории |
-s subtree — тот случай, который стоит запомнить. Слияние обновлений из
проекта, лежащего в vendor/parser/, иначе прочиталось бы как «все файлы
удалены, все файлы добавлены»; стратегия subtree сначала вычисляет сдвиг путей.
Весь процесс целиком — в сабтри.
Почему тут конфликт
Внутри резолвера конфликтов есть кнопка Почему тут конфликт.
Она запускает git log --merge для файла перед вами и перечисляет по каждой
стороне коммиты, которые его трогали с момента расхождения веток.

Маркеры конфликта говорят, что столкнулось. Это говорит, кто это изменил, когда и зачем — а именно этот вопрос обычно и решает исход, и именно он заставляет пойти и спросить человека, прежде чем выбирать сторону.
Если тут пусто — значит, ни одна сторона не коммитила изменение именно этого файла: столкновение пришло из переименования или переноса каталога уровнем выше.
Ограничения, о которых стоит знать
- Параметры действуют на одно слияние. Они не запоминаются и не влияют ни на обычный пункт Слить в текущую, ни на меню перетаскивания.
- Отмена по-прежнему работает: слияние с параметрами записывает ту же запись
отмены, которая сбрасывает на
ORIG_HEAD. - Осьминожьи слияния (больше двух веток разом) здесь не предлагаются.
- Пункты «Слить X в Y» в меню коммита остаются обычными слияниями. Используйте сам бейдж ссылки, когда нужны параметры.
-Xрешает молча. Ничто не помечает, какие ханки разрешились автоматически, так что на важном слиянии прочитайте дифф после, а не доверяйте отсутствию конфликтов.
См. также: Слияние и ребейз · Конфликты · Сабтри · Радар конфликтов