Какой у тебя опыт работы с git и разрешением конфликтов
Что проверяют
Умеете ли вы спокойно довести слияние до рабочего состояния и понимаете ли, что конфликт бывает не только текстовым. Следом часто спрашивают, как вы разрешаете конфликт в IntelliJ IDEA и чем rebase отличается от merge для истории.
Как отвечать
Расскажите, как устроен процесс и какие конфликты в Java-проекте самые частые:
- обновление ветки:
git fetch, затемgit rebase origin/mainдля линейной истории илиgit merge origin/main, если команда не переписывает опубликованные ветки. Откатить начатое помогаютgit merge --abortиgit rebase --abort; - инструмент: трёхпанельный диалог слияния в IntelliJ IDEA, где слева ваша версия, справа чужая, посередине результат. Неконфликтующие изменения он применяет сам, спорные куски вы решаете вручную. В терминале помогает
merge.conflictStyle zdiff3, он показывает общую базу; - сборочные файлы: версии зависимостей в
pom.xml,build.gradle.ktsили каталогеlibs.versions.toml. Версию выбирают осознанно, а не ту, что оказалась сверху, и проверяют дерево зависимостей; - миграции базы: если в двух ветках появился
V12__...для Flyway, приложение не стартует с ошибкой о двух миграциях с одной версией. Одну переименовывают в следующий номер. С Liquibase смотрят порядокchangeSetв changelog; - повторяющиеся конфликты:
git rerereзапоминает, как вы решили конфликт, и применяет решение при следующем ребейзе.
После разрешения обязательно ./gradlew build или mvn verify. Компилятор ловит часть смысловых конфликтов, например вызов метода, который в другой ветке переименовали, а тесты ловят остальное.
Снизить число конфликтов помогают маленькие PR и единое форматирование: Spotless или google-java-format в CI, иначе импорты и отступы будут конфликтовать постоянно.
Где спотыкаются
Жмут «принять всё моё» в IDE и затирают чужие изменения, а замечают это только на ревью или в проде.
Правят конфликт в pom.xml наугад и оставляют две версии одной библиотеки в разных модулях.
Переписывают историю общей ветки через push --force. После ребейза своей ветки используют --force-with-lease, а общую ветку не перезаписывают вовсе.