Как добавить подмодуль в подкаталог?

У меня есть git repo в ~/.janus/ с кучей подмодулей в нем. Я хочу добавить подмодуль в ~/.janus/snipmate-snippets/snippets/, но когда я запускаю git submodule add <[email protected]:...> в каталоге snipmate-snippets, появляется следующее сообщение об ошибке:

You need to run this command from the toplevel of the working tree.

Итак, вопрос: Как добавить подмодуль в каталог snipmate-snippets?

Ответ 1

Перейдите в ~/.janus и запустите:

git submodule add <[email protected] ...> snipmate-snippets/snippets/

Если вам нужна дополнительная информация о подмодулях (или git вообще) ProGit, это очень полезно.

Ответ 2

Обратите внимание, что начиная с git1.8.4 (июль 2013 г.) вам больше не придется возвращаться в корневой каталог.

 cd ~/.janus/snipmate-snippets
 git submodule add <[email protected] ...> snippets

(Bouke Versteegh комментарии, что вам не нужно использовать /., как в snippets/.: snippets достаточно)

См. commit 091a6eb0feed820a43663ca63dc2bc0bb247bbae:

subodule: отказаться от требования верхнего уровня

Используйте новую опцию rev-parse --prefix для обработки всех путей, переданных команде subodule, отбросив требование о ее запуске с верхнего уровня репозитория.

Поскольку интерпретация URL-адреса относительного субмодуля зависит от того, настроена ли настройка "remote.origin.url", явно блокировать относительные URL-адреса в "git submodule add", если не на верхнем уровне рабочего дерева.

Подписано: John Keeping

Зависит от commit 12b9d32790b40bf3ea49134095619700191abf1f

Это означает, что "git rev-parse" ведет себя так, как если бы он был вызван из указанного подкаталога репозитория, с той разницей, что любые пути к файлам, которые он печатает, имеет префикс полного пути от вершины рабочего дерева.

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

Ответ 3

У меня была аналогичная проблема, но я нарисовал себя в углу с инструментами графического интерфейса.

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

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

proj> git rm -r --cached ./ui/jslib

Тогда я должен был сказать, что там был подмодуль (который вы не можете сделать, если что-то в настоящее время отслеживается git):

proj> git submodule add ./ui/jslib

Update

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

proj> git submodule add [email protected]:user/jslib.git ui/jslib

Это будет клонировать репозиторий git в качестве подмодуля, который включает стандартные шаги клонирования, а также несколько других более неясных шагов конфигурации, которые git берет на себя от вас, чтобы заставить этот подмодуль работать. Самое главное отличие состоит в том, что он размещает там простой файл .git, а не каталог .git, который содержит ссылку на путь, где живет реальный ресурс git - обычно в корневом корневом проекте .git/modules/jslib.

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

Итак, move, push, git добавить подмодуль, является самым чистым вариантом.

Ответ 4

Для тех из вас, кто разделяет мою странную привязанность к редактированию файлов конфигурации вручную, добавление (или изменение) следующего также может сделать трюк.

.git/config (личная конфигурация)

[submodule "cookbooks/apt"]
    url = https://github.com/opscode-cookbooks/apt

.gitmodules (исправлена ​​совместная конфигурация)

[submodule "cookbooks/apt"]
    path = cookbooks/apt
    url = https://github.com/opscode-cookbooks/apt

См. это также - разница между .gitmodules и указанием подмодулей в .git/config?

Ответ 5

однострочный bash script, чтобы помочь объекту Криса ответить выше, так как я нарисовал себя в углу, используя обновления Vundle для моих .vim-скриптов. DEST - это путь к каталогу, содержащему ваши подмодули. Сделайте это после выполнения git rm -r $DEST

DEST='path'; for file in `ls ${DEST}`; do git submodule add `grep url ${DEST}/${file}/.git/config|awk -F= '{print $2}'` ${DEST}/${file}; done

веселит