Mercurial репозиторий для нескольких веток - PullRequest
16 голосов
/ 27 октября 2009

У меня есть несколько квази-связанных проектов, которые я хочу контролировать версиями. В SVN я бы настроил их как несколько каталогов в рамках одного проекта

/scripts  #updates in sync with project1 & project2
/project1 #requires database
/project2 #requires database
/database

Естественно, для этого примера игрушки возможны другие макеты SVN, но у этого макета есть свои преимущества:

  • Я могу копировать файлы между ветвями, сохраняя историю
  • Я могу проверить только подмножество проектов, например svn co repo/project2; svn co repo/database. Это значительно экономит память и время, если проект1 большой.
  • Простое управление репозиторием, поскольку доступ пользователя определяется один раз для всех проектов

Эта парадигма плохо сопоставляется с Mercurial, поскольку вы не можете клонировать один каталог Mercurial Repo . Итак, мой вопрос: каков наиболее распространенный способ хранения больших тесно связанных проектов в Mercurial?

Мои идеи:

  • Несколько репозиториев - теряет историю файлов, которые перемещаются между проектами
  • Леса - похоже, остановились, и я не уверен, насколько стабильно это расширение
  • Именованные ветки с преимущественно несвязанным контентом
  • SubRepos - К сожалению, я использую Ubuntu 9.04, которая поставляется только с hg 1.1.2. В противном случае это выглядело бы как хороший вариант

1 Ответ

10 голосов
/ 27 октября 2009

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

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

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

  1. Обновление до заголовка ветки, в которую вы хотите скопировать файл: hg update -C project1
  2. Объединить ветку, из которой вы хотите скопировать файл: HGMERGE=/bin/false hg merge -r project2
  3. Вернитесь к началу ветви, в которую вы хотите скопировать файл: hg revert -a --no-backup -r project1
  4. Вернуть конкретный файл, который вы хотите скопировать из головной версии слитой ветки: hg revert --no-backup -r project2 path/to/file/in/project2.txt
  5. Переместите файл на место в ветке, в которую вы хотите скопировать: hg mv path/to/file/in/project2.txt project1/file/path/project2.txt
  6. Отметить слияние как разрешенное: hg resolve -am
  7. И, наконец, зафиксировать результат: hg commit -m "A merge to copy project2.txt to project1."

Как я уже сказал, очень некрасиво. И это вполне может сработать только в hg 1.3, так как я знаю, что некоторые важные ошибки во взаимодействии revert, merge и resolution были исправлены сравнительно недавно. (IMHO, я подозреваю, что Ubuntu намеренно отстает от версий систем управления версиями не-bzr.)

Как часто вы действительно ожидаете копирования файлов между проектами? Почему это случилось? Вы уверены, что потерять историю было бы так плохо?

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

...