Mercurial обновление не работает для subrepo, если subrepo принадлежит двум основным репо? - PullRequest
3 голосов
/ 12 марта 2012

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

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.SharedLibrary теперь имеет правильную ревизию для ProjectA и ProjectB.

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

1 Ответ

2 голосов
/ 12 марта 2012

То, что вы видите, это то, что 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 больше не находился в версии, упомянутой в .hgsubstate, в версии 1 в server. Другими словами, рабочая копия в server была грязной - hg commit приведет к фиксации нового файла .hgsubstate.

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

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

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

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

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

...