Подтвердить что ты не робот

Зависимости субрепозитария Hg

В прошлом было несколько вопросов о зависимостях подпотоков Hg (здесь и здесь), но принятые ответы, похоже, не рассматривают проблему для меня.

Мой проект имеет 4 зависимости: A, B, C, D. D зависит от A, B и C; и B и C зависят от A:

dependency graph of A,B,C,D

Я хочу использовать субрепозитории Hg для их хранения, чтобы я мог отслеживать, на какую версию каждого они полагаются. Это связано с тем, что, хотя я использую A, B, C и D в этом проекте, другим проектам потребуются только A и B. Поэтому B и C должны отслеживать, какая версия A им нужна независимо от D. В то же время в моем приложении версии B и C, на которые ссылается данная версия D, должны всегда использовать ту же версию A, что и ссылка на данная версия D (иначе она просто упадет во время выполнения). Я действительно хочу, чтобы они могли ссылаться друг на друга как братья и сестры в том же каталоге, то есть D.hgsub выглядел бы следующим образом, а B и C выглядели бы как первая строка.

..\A = https:(central kiln repo)\A
..\B = https:(central kiln repo)\B
..\C = https:(central kiln repo)\C

Однако это, похоже, не работает: я могу понять, почему (было бы легко дать людям достаточно веревки, чтобы повесить себя), но это позор, как я считаю, самым опрятным решением для моих зависимостей. Я прочитал несколько предлагаемых решений, которые я быстро очерчу и почему они не работают для меня:

  • Включить копии как вложенные подкаталоги, ссылайтесь на них как на субрепозиторы Hg. Это приводит к следующей структуре каталогов (я удалил первичные копии A, B, C, B\A, C\A, поскольку я могу принять ссылку на копии внутри \D вместо):

    • project\(все основные файлы проекта)
    • Проект \D
    • Проект \D\A
    • Проект \D\B
    • Проект \D\B\A
    • Проект \D\C
    • Проект \D\C\A

    Проблемы с этим подходом:

    • Теперь у меня есть 3 копии A на диске, все из которых могут иметь независимые модификации, которые должны быть синхронизированы и объединены до нажатия на центральное репо.
    • Я должен использовать другие механизмы, чтобы гарантировать, что B, C и D ссылаются на одну и ту же версию A (например, D может использовать v1, в то время как D\B может использовать v2)
  • Вариант: используйте выше, но укажите RHS для .hgsub, чтобы указать на копию в родительской копии (то есть B и C должны содержать .hgsub ниже):

    A = ..\A
    

    Проблемы с этим подходом:

    • У меня все еще есть три копии на диске
    • В первый раз, когда я клонировал B или C, он попытается рекурсивно вытащить ссылочную версию A из "..\A", которая может не существовать, предположительно вызывая ошибку. Если он не существует, он не дает никакого представления о том, где следует найти репо.
    • Когда я делаю рекурсивный толчок изменений, изменения в D\B\A не входят в общее центральное репо; вместо этого они просто попадают в D\A. Поэтому, если я дважды нажимаю строку, я могу гарантировать, что все изменения будут правильно распространены, но это довольно выдумка.
    • Точно так же, если я делаю (ручное) рекурсивное притяжение, я должен получить право ордера, чтобы получить последние изменения (т.е. потянуть D\A до того, как я вытащу D\B\A)
  • Используйте символические ссылки, чтобы указать папку \D\B\A на D\A и т.д.

    Проблемы с этим подходом:

    • Символы
    • не могут быть закодированы в репозитории Hg, поэтому каждый раз, когда член команды клонирует репо, им приходится вручную/с помощью script повторно создавать символические ссылки. Это может быть приемлемым, но я предпочел бы лучшее решение. Также (личное предпочтение) я нахожу символические ссылки очень неинтуитивными.

Являются ли эти наилучшие доступные решения? Есть ли веская причина, почему мой начальный .hgsub(см. Сверху) - это сон трубы, или есть способ, которым я могу запросить/реализовать это изменение?

ОБНОВЛЕНО, чтобы лучше объяснить более широкое использование A, B, C, D

4b9b3361

Ответ 1

Вместо того, чтобы пытаться управлять вашими зависимостями через Mercurial (или с любым SCM, если на то пошло), попробуйте вместо этого использовать инструмент управления зависимостями, например Apache Ivy.

Используя подход на основе Ivy, у вас нет суб-репозиций, у вас будут только проекты A, B, C и D. A создает артефакт (например,.jar,.so или .dll и т.д.), который публикуется в хранилище артефактов (в основном место, где вы храните артефакты сборки) с версией. Проекты B и C могут затем зависеть от конкретной версии A (контролируемой через файл ivy.xml в каждом проекте), который Ivy будет извлекать из репозитория артефактов. Проекты B и C также создают артефакты, которые публикуются в вашем репозитории. Проект D зависит от B и C, и Айви можно сказать, чтобы получить зависимости транзитивно, что означает, что он получит артефакты для B, C и A (поскольку они зависят от A).

Аналогичный подход можно использовать с Apache Maven и Gradle (позднее использует Ivy)

Основные преимущества заключаются в следующем:

  • он очень четко показывает, какие версии каждого компонента использует проект (иногда люди забывают проверить .hgsub, поэтому они не знают, что они работают с subrepos),
  • это делает невозможным изменение зависимого проекта (поскольку вы работаете с артефактами, а не с кодом)
  • и это избавит вас от необходимости перестраивать зависимые проекты и не знать, какую версию вы используете.
  • избавляет вас от наличия нескольких избыточных копий проектов, которые используются другими проектами.

EDIT: аналогичный ответ со слегка отличающимся отклонением в Рекомендации по субмодулям Project Project с Mercurial и Eclipse?

Ответ 2

Вы говорите, что хотите отследить, на какую версию они полагаются, но вы также будете довольны одной копией A, разделяемой между B, C и D. Они являются взаимоисключающими - с одной копией A, с любым изменением для A приведет к изменению в .hgsub каждого из B, C и D, поэтому нет никакой независимости в версии (так как все B, C и D будут зафиксированы после изменения A).

Отдельные копии будут неудобными. Если вы внесете изменения, которые влияют как на копию B копии A, так и на C, тогда попытайтесь вытолкнуть всю структуру, изменения в (скажем) B будут успешными, но изменения в C не будут выполнены, потому что они требуют слияния с изменениями, которые вы только что нажали B, чтобы избежать создания новых головок. И это будет боль.

То, как я это сделаю (и, может быть, есть лучшие способы), было бы создать D-репо с подполями A, B и C. Каждый из B и C имел бы некоторый необработанный файл A-location (который вы "re предложили ввести через пост-клон hook), сообщив вашей системе сборки, где искать ее репозиторий. Это имеет то преимущество, что вы работаете, но теряете удобство системы, которая отслеживает параллельные версии {B, C} и A. Снова вы можете сделать это вручную с помощью файла версии A в каждом из B или C, обновленного с помощью крючка, читайте с помощью крючка, и вы можете сделать эту работу, но я не думаю, что это возможно, используя реализацию subrepos в hg. Мои предложения действительно сводятся к внедрению упрощенной собственной подрепосистемы.