Обновление Mercurial не работает для субрепозитория, если субрепозиторий принадлежит двум основным репозиториям?
-
12-12-2019 - |
Вопрос
Возьмите эту структуру репо:
Server (main repo)
ProjectA (subrepo)
SharedLibrary (subrepo)
Client (main repo)
ProjectB (subrepo)
SharedLibrary (subrepo)
SharedLibrary указывает на одну и ту же папку (это Windows), это не отдельная копия/клон в каждом основном репозитории.
Предположим, что в каждом основном репозитории есть два набора изменений: 0 и 1 (подсказка).Мы начинаем с обоих основных репозиториев с версии 1 (совет).
Выполните следующие шаги:
В репозитории клиента обновите набор изменений до версии 0.При этом ProjectB и SharedLibrary обновляются до более ранних, но соответствующих версий.
ProjectA теперь не синхронизирован с SharedLibrary.На шаге 1 была обновлена версия SharedLibrary до более старой версии, чем требуется для ProjectA, которая все еще имеет номер 1 (подсказка).
В репозитории сервера мы хотим обновить SharedLibrary до правильной версии для ProjectA, поэтому мы запускаем подсказку по обновлению hg в основном репозитории сервера.Это НЕ обновляет SharedLibrary до правильной версии.В результате SharedLibrary останется в той же версии, что и первый шаг.
Вернитесь в репозиторий клиента и запустите подсказку по обновлению hg.SharedLibrary теперь имеет правильную версию как для ProjectA, так и для ProjectB.
Похоже, что обновление в репозитории сервера не проверяет, имеет ли SharedLibrary правильную версию.Ожидается ли такое поведение или есть лучший способ сделать это?
Решение
То, что ты видишь, это 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
фиксируемый файл.
Меркуриальный сохраняет эту модификацию когда ты hg update
в server
и вот почему ты это видишь SharedLibrary
не был актуален при обновлении.Использовать hg update -C
если вы хотите сделать субрепозиторий текущим.
Идея этой функции заключается в том, что вы можете тестировать разные версии своих подрепозиториев.При поиске ошибки часто необходимо обновить основной репозиторий до более старых версий, поэтому удобно, чтобы изменения в версиях подрепозитория оставались на месте.
Обратите внимание: запутанная ситуация, которую вы видите, не вызвана тем, что вы дважды повторно использовали один и тот же субрепозиторий.Однако, как отмечает Лассе, реальный способ использовать один субрепозиторий в нескольких проектах — это поместить его один раз на своем сервере, а затем клонируйте его в свои локальные клоны — один раз за клон.
у меня есть описал это более подробно, но вкратце вам следует следовать рекомендации и поддерживать идентичную структуру как на сервере, так и на клиентах.Использовать SharedLibrary = SharedLibrary
пути в твоем .hgsub
файл для поддержания этой структуры.Свяжите репозитории вместе на стороне сервера (см. другой ответ), чтобы один репозиторий отображался в нескольких разных URL-адресах/каталогах.
Когда вы начинаете с подрепозиториев, тогда остерегайтесь жесткой связи.Если можете, попробуйте использовать подходящую систему управления зависимостями, например Maven+Nexus, для проектов на основе Java.