Полагаю, что лучшим решением было бы исправление поддержки Git в Mercurial, чтобы всегда использовать рекурсивные опции Git (например, git clone --recursive
при клонировании под-репозитория на основе Git, git pull --recurse-submodules && git submodule update
после извлечения обновленного под-репозитория на основе Git и т. Д.),Я знаю, что разработчики Git специально решили не инициализировать субмодули автоматически, потому что один из рабочих процессов, которые они хотят поддерживать, это «Я никогда не хочу видеть ни один из субмодулей», но, возможно, «всегда инициализировать все субрепозитории» лучше подходит длярежим работы Mercurial по умолчанию (я не большой пользователь Mercurial, поэтому у меня нет четкого представления о том, каким будет стиль Mercurial по умолчанию).
Пока это не произойдет, вы можетечтобы обойти проблему, переведя записи subrepo/.gitmodules
в записи .hgsub
.Это легко сделать вручную, но, возможно, вы могли бы автоматизировать его, если это было важно (используйте git config
, чтобы извлечь пути и URL-адреса из .git/config
и / или .gitmodules
).Это может быть непривлекательно, если вы имеете дело с файлом .gitmodules
, который сильно меняется (вам нужно быть очень внимательным в отношении синхронизации .hgsub
каждый раз, когда меняется .gitmodules
).
Я проверил это с четырьмя репозиториями:
- gitsub - «листовое» хранилище (без подмодулей Git)
- gitsuper - «суперпроект» Git;
gitsub/
- это gitsub в качестве подмодуля - hgsuper2 - суперпроект Mercurial;
gitsuper/
- gitsuper asсуб-репозиторий,
gitsuper/gitsub
- это gitsub в качестве суб-репозитория. - hgsuper2-clone - клонированный «суперпроект» Mercurial;
gitsuper/
* gitsuper в качестве вложенного репозитория,
gitsuper/gitsub
is gitsub в качестве вложенного хранилища.
Я создал и протестировал их следующим образом:
- Создать gitsub .Добавьте и передайте некоторый контент.
- Создание gitsuper .
- Добавить содержимое.
git submodule add url-of-gitsub gitsub && git submodule init
git commit -m 'added gitsub'
- Создать hgsuper2 .
- Добавить некоторый контент.
git clone --recursive url-of-gitsuper gitsuper
echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub
Эти два последних шага могут быть автоматизированы из битовgitsuper/.git/config
и gitsuper/.gitmodules
. hg add .hgsub && hg commit -m 'added Git subrepositories'
- Клон hgsuper2-клон из hgsuper2 .
Получает соответствующее содержимое в gitsuper/
и gitsuper/gitsub/
. - Обновляет и фиксирует новое содержимое в gitsub .
- Обновляет gitsuper .
- Добавьте или измените некоторый контент и установите его.
(cd gitsub && git pull origin master)
git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
- In hgsuper2, извлеките изменения из суперпозиториев Git.
(cd gitsuper && git pull --recurse-submodules && git submodule update)
Содержимое в gitsuper/
и gitsuper/gitsub/
обновляется при извлечении. hg commit -m 'updated gitsuper (and its contents)'
- Pullв hgsuper2-клон .
hg pull -u
Обновлен контент из Git.
Мои тесты работали (с использованием Mercurial 1.8.1 и Git 1.7.4.1), но я заметил одну ошибку.Mercurial создает и проверяет ветку Git со странным именем (origin/master
(то есть refs/heads/origin/master
) вместо использования отдельного HEAD (как Git делает со своими подмодулями) или просто с использованием master
(то есть refs/heads/master
)).Иногда кажется, что он немного заклинивает, что приводит к таким ошибкам:
fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper
Я обошел проблему, зайдя в рассматриваемый репозиторий Git (подкаталог Mercurial на основе Git) и удаливветвь с git checkout HEAD~0 && git branch -D origin/master
(первая отсоединяет HEAD и (что более важно) удаляется от ветки, поэтому ее можно удалить следующей командой).Этот обходной путь полностью безопасен, если у вас нет изменений локальных изменений в репозитории Git.
Другая небольшая проблема заключается в том, чтовам нужно будет запустить git submodule init
, чтобы Git знал о своих подмодулях, прежде чем вводить команды подмодулей Git в супер-репозиторий Git, созданный Mercurial (подмодули были клонированы в нужных местах, но они были установлены Mercurial, поэтому есть нет записей для них в .git/config
).
Точно так же, если вы планируете создавать изменения для содержимого, которым управляет Git, из подкаталога Mercurial на основе Git, то вы должны быть осторожны, чтобы всегда добавлять любые подмодули Git, фиксировать и выдвигать из подкаталогов Git перед фиксацией в ртутном «суперпроекте». В противном случае вы можете столкнуться с ситуацией, когда Mercurial использует одну комбинацию gitsuper и gitsub , тогда как gitsuper сама по себе ссылается на другую версию gitsub . Другими словами, так как вы будете обходить код подмодуля Git (управляя подмодулями Git как подкаталогами Mercurial), вам нужно быть осторожным, чтобы синхронизировать взгляд подмодулей с Git и Mercurial.