Как разрешить конфликты слияния в Composer
Конфликты слияния в Composer и их разрешение

Старт! Честный VDS/VPS, на котором «Лунная База» живет уже 20+ лет

Задумываетесь о том, чтобы поднять свой pet-проект, сайт клиента или настроить окружение для разработки? Уже пора подумать, где арендовать железо.

Лунная База хостится на FirstVDS более 20 лет. Мыслей о том, чтобы перебраться на другой хостинг, не было ни разу (хотя опыт работы с другими вариантами, конечно, есть).

Бывали разные ситуации, но они бывают на любом железе. Главное, что нужно понять: здесь нет маркетинговой шелухи и сказок про «мы всё сделаем за вас». Если вы берете VDS — вам дают полный root, возможность накатить любую ОС и не лезут в ваши конфиги.

Если в саппорт написать с вопросом по вашему коду и получить ответ: «Читайте документацию и разбирайтесь сами» или «Обратитесь к профильному специалисту» — это не повод обижаться. Это повод углубить свои знания в DevOps и сайтостроении! Бегите от тех, кто пообещает: «Мы всё чиним и настраиваем абсолютно бесплатно!». Никто никогда не работает «по доброте душевной» в ущерб себе, а бесплатный сыр в администрировании обычно заканчивается сломанной базой данных.

Что по факту: Гибкое масштабирование ядер и RAM, экономия по сравнению с физическими серверами и адекватная панель ispmanager, если она вам нужна.



Конфликты слияния в Composer

Работая в команде над одним и тем же проектом в Composer, можно столкнуться с ситуацией, когда несколько человек добавляют, обновляют или удаляют что-то в файлах composer.json и composer.lock в разных ветках. Когда эти ветки в конечном итоге будут сливаться, возникнут конфликты слияния. Разрешить эти конфликты слияния не так просто, как в случае с другими файлами, особенно в случае с файлом composer.lock.

Примечание: Возможно не сразу становится очевидным, почему объединение на основе текстовых данных невозможно для файлов блокировок, поэтому давайте представим следующий пример, в котором мы хотим объединить две ветви;

  • Ветвь 1 добавила пакет A, который требует пакет B. Пакет B заблокирован на версии 1.0.0.
  • Ветвь 2 добавила пакет C, который конфликтует со всеми версиями пакета B ниже 1.2.0.

В результате слияния, основанного на тексте, будет получен пакет A версии 1.0.0, пакет B версии 1.0.0 и пакет C версии 1.0.0. Это некорректный результат, поскольку конфликт пакета C не был учтен и потребует обновления пакета B.

Повторное внедрение изменений в Composer

Наиболее безопасным методом объединения файлов в Composer является принятие версии из одной ветки и применение изменений из другой ветки.

Пример, когда у нас есть две ветки:

  1. Добавлен пакет 'A'
  2. Пакет 'B' был удален и добавлен пакет 'C'.

Чтобы разрешить конфликт при слиянии этих двух ветвей:

  • Мы выбираем ветку, в которой произошло больше всего изменений, и принимаем файлы composer.json и composer.lock из этой ветки. В данном случае мы выбираем файлы Composer из ветки 2.
  • Мы повторно применяем изменения из другой ветки (ветки 1). В этом случае необходимо снова запустить composer require package/A.

Проверка правильности объединенных файлов в Composer

Перед коммитом убедитесь, что полученные файлы composer.json и composer.lock являются корректными. Для этого выполните следующие команды:

php composer.phar validate
php composer.phar install [--dry-run]

Автоматизация разрешения конфликтов слияния с помощью git

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

Пример такого драйвера можно найти в balbuf composer git merge driver.

Важные моменты

Следует помнить, что при конфликтах слияния в файле блокировок теряется информация о том, на какую именно версию были замкнуты новые пакеты для одной из ветвей. Если пакет A в ветке 1 ограничен как ^1.2.0 и заблокирован как 1.2.0, то при использовании ветки 2 в качестве базовой и выполнении новой команды composer require package/A:^1.2.0 он может быть обновлен, так как в этом случае будет использоваться самая последняя версия, которую позволяет ограничение, если это возможно. Возможно, к этому моменту уже доступна версия 1.3.0 для этого пакета, которая и будет использована.

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

Восстановление после некорректно разрешенных конфликтов слияния в Composer

Если вышеописанные действия не были выполнены, а текстовые слияния все равно были произведены, то проект Composer может оказаться в состоянии, когда наблюдается неожиданное поведение, поскольку файл composer.lock не полностью синхронизирован с файлом composer.json.

Здесь могут произойти две вещи:

  1. В секции require или require-dev файла composer.json находятся пакеты, которые отсутствуют в файле блокировки и, как следствие, никогда не устанавливаются.
    • Примечание: Начиная с версии Composer 2.5, наличие пакетов, которые требуются, но отсутствуют в composer.lock, приводит к ошибке при выполнении install.
  2. В файле composer.lock присутствуют пакеты, которые не являются прямой или косвенной зависимостью ни одного из требуемых пакетов. В результате пакет устанавливается, несмотря на то, что при запуске composer why vendor/package указано, что он не требуется.

Существует несколько способов решения этих проблем.

Начать с начала

Самым простым, но наиболее затратным вариантом является запуск composer update для восстановления корректного состояния с нуля.

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

Восстановление из истории git

Вариант, который, вероятно, не очень реален во многих ситуациях, но заслуживает отдельного упоминания.

Можно восстановить правильное состояние пакета, вернувшись в историю git и найдя последний корректный файл composer.lock, и перепрошить новые зависимости оттуда.

Устранение проблем вручную

Существует возможность восстановить несоответствие между файлами composer.json и composer.lock, не копаясь в истории git и не начиная работу с нуля. Для этого необходимо решить проблему 1 и 2 по отдельности.

Обнаружение и исправление отсутствующих необходимых пакетов

Для обнаружения необходимого, но не установленного пакета можно просто выполнить команду:

php composer.phar validate

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

./composer.json is valid but your composer.lock has some errors
# Lock file errors
- Required package "vendor/package-name" is not present in the lock file.
This usually happens when composer files are incorrectly merged or the composer.json file is manually edited.
Read more about correctly resolving merge conflicts https://getcomposer.org/doc/articles/resolving-merge-conflicts.md
and prefer using the "require" command over editing the composer.json file directly https://getcomposer.org/doc/03-cli.md#require

Чтобы исправить ошибку, просто запустите composer update vendor/package-name для каждого из перечисленных выше пакетов. После этого для каждого пакета, указанного в данном списке, повторный запуск composer validate должен привести к отсутствию ошибок файла блокировки:

./composer.json is valid

Обнаружение и устранение лишних пакетов

Для обнаружения и исправления пакетов, которые заблокированы, но не являются прямой/непрямой зависимостью, можно выполнить следующую команду:

php composer.phar remove --unused

Если заблокированных пакетов, не являющихся зависимостью, нет, то команда выдаст следующий результат:

No unused packages to remove

Если есть пакеты, которые необходимо почистить, то вывод будет следующим:

vendor/package-name is not required in your composer.json and has not been removed
./composer.json has been updated
Running composer update vendor/package-name
Loading composer repositories with package information
Updating dependencies
Lock file operations: 0 installs, 0 updates, 1 removal
  - Removing vendor/package-name (1.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Nothing to install, update or remove

Перевод с английского официальной документации Composer:
https://getcomposer.org/doc/articles/resolving-merge-conflicts.md

Самый честный хостинг за 20+ лет существования Лунной Базы

Задумываешься о том, чтобы поднять свой сайт в Интернете? Уже пора подумать о том, какой хостинг выбрать?

Лунная База хостится 20+ лет на firstDVS. При этом, мыслей о том, чтобы перебраться на другой хостинг не было. (Но, при этом есть опыт работы с другими вариантами.)

Бывали с firstDVS разные ситуации, но, они бывают на всех хостингах. Единственное, что тут важно понять, - это то, что никто ничего тебе не будет впаривать... Но, и работать за тебя тоже никто не станет. Если в саппорт ответили: «Читайте по ссылке и разбирайтесь сами...» или вообще «Обратитесь за помощью к специалисту», - это повод углубить свои знания в области сайтостроения, а не бежать к тем, что пообещают: «Мы всё чиним и всё делаем за своих клиентов абсолютно бесплатно!» Никто никогда ничего ни за кого "по доброте душевной" не делал, не делает и не будет делать!

Старт! Горячий старт на просторы интернета
Старт! Горячий старт на просторы интернета
Старт! Меню