2010-11-06 2 views
20

У меня есть проект в Git, который имеет несколько подмодулей, и мне нужны эти подмодули, которые нужно загрузить, и файлы, доступные для использования основного проекта, и для того, чтобы подмодули работали, мне нужно их собственное подмодули должны быть доступны и т. д. Поэтому, чтобы установить это, я рекурсивно инициализирую подмодули, используя git submodule update --init --recursive.Дублирующие подмодули с Git

Однако, я заметил, что многие из моих подмодулей имеют общую зависимость, смотря что-то подобное в псевдокоде (alpha -> beta представляет, что alpha имеет подмодуль beta)

my project -> submodule a -> submodule m 
      -> submodule b -> submodule m 
          -> submodule n -> submodule x 
      -> submodule c -> submodule x 

Мой вопрос: есть ли способ избежать этого дублирования, используя только git, сохраняя при этом (по крайней мере, одну копию) файлы для каждого подмодуля?

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

В идеале я хотел бы, чтобы упростить его вниз:

my project -> submodule a -> symlink(submodule m) 
      -> submodule b -> symlink(submodule m) 
          -> symlink(submodule n) 
      -> submodule c -> symlink(submodule x) 
      -> submodule m 
      -> submodule n -> symlink(submodule x) 
      -> submodule x 

Заранее спасибо за любые предложения!

+0

Не точно такой же вопрос, но очень похожи: http://stackoverflow.com/questions/1419498/git-nested-submodules-and- зависимости – MarcH

ответ

7

Это не встроено в git, но вы можете определенно сделать это с символическими ссылками, как вы говорите. Возможно, вам стоит взглянуть на git new-workdir (из каталога git's contrib), что и делает это. Он не знает ничего общего с подмодулями, но подмодуль не знает, что это подмодуль - это родительское репо, которое знает об этом. Я не пробовал это, но я довольно уверен, что вы могли бы использовать это что-то вроде этого:

# remove the target first (new-workdir will refuse to overwrite) 
rm -rf submodule_b/submodule_m 

#    (original repo)   (symlinked repo) 
git new-workdir submodule_a/submodule_m submodule_b/submodule_m 

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

Оттуда вы должны быть хорошими. Когда вы запускаете команду git submodule в супермодуле, она просто переходит в подмодули и запускает там соответствующие команды, которые будут работать как ожидалось.

Единственное, что вам обычно нужно знать с символическими репозиториями, как это, состоит в том, что они имеют один и тот же набор ветвей, поэтому, если они оба имеют одну ветвь, и вы передаете ее в одну, другую будет не синхронизироваться. С подмодулями это, как правило, не будет проблемой, хотя, поскольку они по существу всегда находятся в отключенном состоянии HEAD, если вы не вмешиваетесь.

3

git-new-workdir не может быть хорошим решением, как описано здесь: http://comments.gmane.org/gmane.comp.version-control.git/196019

Это не работает для меня под мерзавца 1.7.10.

Я решил использовать его для использования с жесткими ссылками. Я запускаю OS X, и файловая система позволяет создавать жесткие ссылки на каталоги: https://github.com/darwin/hlink

Теперь я могу жестко связать каталоги подмодулей, а git - прозрачно. Жесткая привязка также имеет приятное свойство, что все подмодули полностью зеркалируются, включая HEAD, который я предпочитаю в своем случае.

Хорошо, идея состоит в том, чтобы иметь один «главный» субмодульный репо и жестко связать все «подчиненные» копии обратно к нему. Это сделает их неотличимыми друг от друга и полностью синхронизированными.

ПРЕДОСТЕРЕЖЕНИЯ:

1) Это отлично работает до тех пор, как относительные пути в .git работе. Другими словами, вы можете жестко связать только подмодули, сидящие на одном уровне каталогов в дереве каталогов. Это был мой случай. Я предполагаю, что вы можете легко исправить это, изменив .gitfiles своей сложной задачей. Примечание. Это не должно быть проблемой перед git 1.7.10, потому что ранее субмодул .git был автономным каталогом, а не только текстовым файлом .git, указывающим куда-то еще.

2) Жесткие ссылки могут вносить некоторые несовместимости. Например, TimeMachine запутывается, потому что он использует жесткие ссылки внутри для управления версиями. Удостоверьтесь, что вы исключили свою форму в каталог проекта TimeMachine.

Вот пример моей передней задачи делает работу: https://github.com/binaryage/site/blob/3ef664693cafc972d05c57a64c41e89b1c947bfc/rakefile#L94-115

Смежные вопросы