Все об Arch Linux

Arch Linux будет тем, что вы из него сделаете!

Конфликты файлов с официальным репо: что делать

Сразу к делу: конфликт файлов возникает, когда pacman хочет записать файл, а на диске уже лежит файл с тем же путём, принадлежащий другому пакету. Установка прерывается с ошибкой failed to commit transaction (conflicting files). Лечится это не слепым --overwrite, а разбором: кто владеет файлом, зачем он там и какой пакет должен его отдать.

Что такое конфликт файлов в pacman

Pacman ведёт базу установленных файлов: каждый пакет владеет своим списком путей. Когда ты ставишь новый пакет, pacman сверяет его файлы с базой. Если путь уже занят другим пакетом, возникает конфликт.

Ошибка выглядит так:

error: failed to commit transaction (conflicting files)
package: /usr/bin/foo exists in filesystem

Тут два разных случая. Первый: файл принадлежит другому пакету из базы. Второй: файл лежит на диске, но не принадлежит ни одному пакету, так называемый exists on filesystem. Это разные ситуации, и лечатся они по-разному. Про второй случай есть отдельная статья «Файл существует в файловой системе».

Раньше конфликты обходили флагом --force, но в pacman 6 его убрали. Остался только --overwrite, и он требует явного указания путей. Это сделано специально: случайная перезапись чужих файлов ломает систему, и pacman теперь заставляет тебя думать.

Почему пакет из AUR конфликтует с официальным

Самая частая причина: пакет из AUR собирает тот же бинарник или кладёт файл по тому же пути, что и пакет из официальных репозиториев. Например, AUR-версия программы с другими флагами сборки ставит /usr/bin/foo, а официальный пакет foo уже владеет этим путём.

Вторая причина: пакет из AUR тянет зависимости, которые конфликтуют с уже установленными. Скажем, AUR-пакет требует bar-git, а у тебя стоит официальный bar.

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

Как понять, кто владеет файлом

Первый шаг: узнать, кому принадлежит конфликтующий путь.

pacman -Qo /usr/bin/foo

Если пакет найден, вывод покажет имя и версию. Если файл не принадлежит никому, pacman ответит No package owns .... Тогда это случай exists on filesystem, и разбирать его нужно отдельно.

Дальше проверь, установлен ли пакет-владелец и не сирота ли он:

pacman -Q foo

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

pacman -Ql foo | grep /usr/bin/foo

Так ты увидишь, действительно ли пакет заявляет этот путь или файл попал на диск мимо базы.

Как работают conflicts, provides и replaces в PKGBUILD

В PKGBUILD есть три поля, которые управляют конфликтами.

conflicts=(...) перечисляет пакеты, с которыми этот пакет не может сосуществовать. При установке pacman предложит удалить конфликтующий пакет.

provides=(...) перечисляет виртуальные имена, которые пакет предоставляет. Например, provides=('foo') говорит pacman: этот пакет закрывает зависимость на foo.

replaces=(...) означает, что пакет заменяет другой, и pacman при установке заменит его файлы.

Разница между conflicts и replaces тонкая. conflicts запрещает сосуществование: pacman спросит, что удалить. replaces говорит «этот пакет теперь вместо того», и pacman заменит файлы без вопросов.

Посмотреть, что заявляет пакет, можно прямо из PKGBUILD:

grep -E '^(conflicts|provides|replaces)' PKGBUILD

Что делать при конфликте с официальным пакетом

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

Сначала пойми, нужен ли тебе этот пакет

Если AUR-пакет дублирует официальный, возможно, он тебе не нужен. Официальный пакет обновляется вместе с системой, а AUR-версию придётся пересобирать вручную. Проверь, чем они отличаются: может, разница только в свежести версии, и официальный вариант закрывает твою задачу.

Проверь, не заявляет ли пакет замену

Иногда конфликт ожидаемый: AUR-пакет специально заменяет официальный. В PKGBUILD тогда стоит replaces=('official-package'). В этом случае pacman сам предложит замену при установке, и конфликта не будет. Если replaces нет, а пакет по смыслу должен заменять официальный, это ошибка в PKGBUILD, и стоит написать о ней мейнтейнеру.

Собери с правильными conflicts

Если ты собираешь пакет сам и знаешь, что он несовместим с официальным, добавь в PKGBUILD:

conflicts=('official-package')

Тогда pacman при установке предложит удалить официальный пакет, и конфликт файлов не возникнет. Это правильный путь для своей сборки. Подробно про написание PKGBUILD читай в статье «Свой PKGBUILD: полный гайд».

Выбери альтернативный вариант пакета

Многие программы в AUR живут в нескольких вариантах: -git (сборка из исходников), -bin (готовый бинарник), обычный (сборка из релизного архива). Если один вариант конфликтует с официальным пакетом, попробуй другой. Например, вместо сборки из исходников поставь -bin, если он есть. Бинарный вариант часто кладёт файлы по другим путям или не тянет лишние зависимости, и конфликт уходит.

Когда –overwrite оправдан

--overwrite разрешает pacman перезаписать файлы, принадлежащие другим пакетам:

pacman -S --overwrite '/usr/lib/*' пакет

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

Но использовать --overwrite бездумно нельзя. Он перезаписывает файлы чужого пакета, не трогая его базу. В результате пакет-владелец остаётся в базе, а его файлы уже не его. При следующем обновлении pacman снова попытается поставить эти файлы, и конфликт вернётся. Хуже того, перезаписанный пакет может сломаться: конфиги, библиотеки, скрипты, всё, что лежало по этим путям.

Правило простое: --overwrite только когда ты осознанно заменяешь один пакет другим и уверен, что файлы совместимы. Например, при переходе с одного пакета на его форк с теми же путями. И после такой замены удали старый пакет, чтобы база не врала:

pacman -R old-package

Как безопасно провести замену официального пакета

Если ты решил заменить официальный пакет на AUR-версию осознанно, делай это по шагам.

Сначала посмотри, что заявляет новый пакет:

grep -E '^(conflicts|provides|replaces)' PKGBUILD

Потом проверь, кто зависит от старого пакета:

pacman -Qi old-package

Вывод покажет, какие пакеты требуют его. Если зависимые пакеты есть, убедись, что новый пакет закрывает их через provides. Иначе после замены получишь сломанные зависимости. Про это читай статью «Зависимости AUR ломаются после обновления».

Затем установи новый пакет с --overwrite только на те пути, которые реально заменяешь:

pacman -S --overwrite '/usr/bin/foo' aur-package

И сразу удали старый:

pacman -R old-package

После этого проверь целостность системы:

pacman -Qk

Если pacman ругается на пропавшие файлы, верни старый пакет и подумай ещё раз.

Частые вопросы

Что значит «file exists in filesystem»?

Это значит, что файл лежит на диске, но не принадлежит ни одному пакету. Обычно он остаётся после ручного удаления пакета, распаковки архивов или старых версий. Разберись, нужен ли файл, и удали его или перенеси.

Можно ли просто добавить –overwrite и забыть?

Можно, но это отложенная мина. Файлы чужого пакета будут перезаписаны, а база pacman об этом не узнает. При следующем обновлении конфликт вернётся, а пакет-владелец может сломаться. --overwrite инструмент для осознанной замены, а не для обхода ошибок.

Чем conflicts отличается от replaces?

conflicts запрещает сосуществование: pacman предложит удалить один из пакетов. replaces говорит, что новый пакет заменяет старый, и pacman заменит его файлы сам. Если пакет по смыслу заменяет официальный, в PKGBUILD должен стоять replaces, а не только conflicts.

Конфликт двух AUR-пакетов: что делать?

Посмотри, кто владеет файлом (pacman -Qo), и реши, какой пакет тебе нужен. Если нужны оба, проверь, не заявляют ли они conflicts друг на друга, и выбери один. Держать два пакета, которые кладут файлы в одно место, нельзя: они будут ломать друг друга при каждом обновлении.

Конфликт возвращается после каждого обновления: почему?

Потому что причина не устранена. Ты перезаписал файлы через --overwrite, но пакет-владелец так и живёт в базе со своим списком путей. При обновлении pacman снова пытается поставить его файлы, и конфликт возвращается. Лечится это удалением старого пакета после замены и чисткой базы, а не повторным --overwrite.

Полезные ресурсы

Заключение

Конфликт файлов при установке из AUR решается не флагом --overwrite, а пониманием ситуации. Сначала узнай, кто владеет файлом (pacman -Qo), потом посмотри, что заявляет пакет в PKGBUILD (conflicts, provides, replaces). Если конфликт ожидаемый, добавь conflicts в свою сборку или выбери другой вариант пакета. --overwrite оставь для осознанной замены, когда ты точно знаешь, что файлы совместимы. Так база pacman останется честной, а система целой.



Не получилось? Поможем настроить

Задай вопрос в чате — отвечаем быстро, по делу и без воды.

Читайте также

Комментарии

Загрузка…

Откроется GitHub: создайте новый issue с вашим комментарием (кнопка «Submit new issue»). После отправки обновите эту страницу — комментарий появится ниже.

Telegram Max