Hg зависимости от хранилища - PullRequest
18 голосов
/ 11 апреля 2011

В прошлом было несколько вопросов о зависимостях 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 (иначе она просто упадет во время выполнения). То, что я действительно хочу, - это позволить им ссылаться друг на друга как братья и сестры в одном и том же каталоге - то есть .hgsub D будет выглядеть следующим образом, а B и C будут выглядеть как первая строка.

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

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

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

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

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

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

    A = ..\A
    

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

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

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

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

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

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

Ответы [ 2 ]

4 голосов
/ 26 сентября 2011

Вместо того, чтобы пытаться управлять своими зависимостями через Mercurial (или с любым SCM в этом отношении), попробуйте вместо этого использовать инструмент управления зависимостями, такой как Apache 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, поэтому они не знают, что работают с подпунктами),
  • делает невозможным изменение зависимого проекта (поскольку вы работаете с артефактами, а не с кодом)
  • и это избавляет вас от необходимости перестраивать зависимые проекты и быть неуверенным в том, какую версию вы используете.
  • избавляет вас от нескольких избыточных копий проектов, которые используются другими проектами.

РЕДАКТИРОВАТЬ: Аналогичный ответ с несколько иным вращением на Наилучшие практики для подмодулей функций проекта с Mercurial и Eclipse?

1 голос
/ 13 апреля 2011

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

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

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

...