Mercurial обновление не работает для subrepo, если subrepo принадлежит двум основным репо?

Возьмите эту структуру репо:

Server (main repo)
    ProjectA (subrepo)
    SharedLibrary (subrepo)

Client (main repo)
    ProjectB (subrepo)
    SharedLibrary (subrepo)

SharedLibrary указывает на одну и ту же папку (это Windows), это не отдельная копия / клон под каждым основным репо.

Предположим, что у каждого основного репо есть две ревизии, 0 и 1(совет). Мы начинаем с обоих основных репо с ревизии 1(отзыв).

Сделайте следующие шаги:

  1. В клиентском репо обновите набор изменений 0. Это обновит ProjectB и SharedLibrary до более ранних, но соответствующих ревизий.

  2. ProjectA теперь не синхронизирован с SharedLibrary. Шаг 1 обновил SharedLibrary до более старой версии, чем требуется для ProjectA, которая по-прежнему на 1(совет).

  3. В репозитории сервера мы хотим обновить SharedLibrary до правильной версии для ProjectA, поэтому мы запускаем подсказку hg update в главном репо сервера. Это НЕ обновляет SharedLibrary до правильной ревизии. Он оставляет SharedLibrary в той же ревизии, что и первый шаг.

  4. Вернитесь в репозиторий клиента и запустите hg update tip. SharedLibrary теперь в правильной редакции для ProjectA и ProjectB.

Похоже, что обновление в репозитории сервера не проверяет правильность ревизии SharedLibrary. Это поведение ожидается, или есть лучший способ сделать это?

1 ответ

Решение

То, что вы видите, это то, что hg update будет сливаться, когда рабочая копия загрязнена. Позвольте мне сначала объяснить это нормальным файлом. Представьте, что у вас есть хранилище с двумя ревизиями. Я на ревизии 0 и foo модифицируется:

$ hg diff
diff --git a/foo b/foo
--- a/foo
+++ b/foo
@@ -1,3 +1,3 @@
 first
 second
-third
+third line

Вы видите, я изменил третью строку. Теперь, если я бегу hg update 1 модификация будет объединена с тем, как foo выглядит как в ревизии 1:

$ hg update 1
merging foo
0 files updated, 1 files merged, 0 files removed, 0 files unresolved

Модификация все еще там и foo все еще грязно

$ hg diff
diff --git a/foo b/foo
--- a/foo
+++ b/foo
@@ -1,3 +1,3 @@
 first line
 second
-third
+third line

Когда ты сделал

$ cd client
$ hg update 0

Вы убедились, что SharedLibrary был обновлен до версии, описанной в .hgsubstate для ревизии 0 в client,

Когда вы тогда пошли в server, SharedLibrary subrepo больше не было в пересмотре, упомянутом в .hgsubstate на пересмотре 1 в server, Другими словами, рабочая копия в server был грязный hg commit приведет к новому .hgsubstate файл передается.

Mercurial сохраняет эту модификацию, когда вы hg update в server и вот почему вы видите, что SharedLibrary не обновлялся при обновлении. использование hg update -C если вы хотите сделать подпункт текущим.

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

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

Я описал это более подробно, но вкратце вы должны следовать рекомендациям и поддерживать одинаковую структуру как на сервере, так и на клиентах. использование SharedLibrary = SharedLibrary пути в вашем .hgsub файл для поддержания этой структуры. Свяжите репозитории вместе на стороне сервера (см. Мой другой ответ), чтобы один репозиторий появился под несколькими разными URL / каталогами.

Начиная с подпунктов, остерегайтесь жесткой связи. Если вы можете, то попробуйте использовать подходящую систему управления зависимостями, такую ​​как Maven+Nexus для проектов на основе Java.

Другие вопросы по тегам