Репозиторий Git в репозитории Git

У меня есть репозиторий git, содержащий репозиторий git.

repo1/
     .git/
     files
     repo2/
          .git/
          files
     files

Возможно ли работать с этой архитектурой?

Ответ 1

Вы можете иметь вложенные git repos:
Родительское репо просто игнорирует вложенное репо.

jleedev и иллюстрирует этот gist script, который родительский репо будет отслеживать вложенное состояние репо через a gitlink.
(gitlink = SHA-1 объекта, ссылающегося на фиксацию в другом репозитории. git ссылки могут быть указаны только SHA или через знак фиксации.
Gitlink имеет специальный режим '160000', используемый для подмодулей, но также присутствует для простых вложенных репозиций).

Однако обычные команды не признают вложенное репо: add или commit будут применяться только в одном репо, а не в другом.

git subodule позволит ссылаться на вложенное репо из родительского репо и сохранять точную ссылку на дочернее репо.

Другая альтернатива может включать:

  • два отдельных git repos (не вложенные)
  • символическая ссылка от одной к определенной части другой (как Unix, так и Windows Vista + имеют символические ссылки)

Ответ 2

То, что вы пытаетесь выполнить, называется "подмодулем", пожалуйста, ознакомьтесь с этой ссылкой: http://git-scm.com/book/en/v2/Git-Tools-Submodules, чтобы узнать, как он работает.

Ответ 3

Я использовал эту структуру довольно долго, с каталогами под-репо, указанными в .gitignore во внешнем репо.

Он смущает инструмент git в моем редакторе (PhpStorm), который всегда хочет совершить внешнее репо, но в остальном работает нормально. Я загружаю все внешнее репо (которое включает все внутренние репозитории) как один проект в редакторе. Это позволяет мне легко искать и проверять код во внешнем репо во время работы над внутренним.

Я выполняю все операции git из git bash в любом репо, над которым я работаю.

Подмодули могут быть лучшим подходом. У меня не было времени исследовать, будут ли они работать лучше с PhpStorm.

Ответ 4

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

Вы хотите добавить следующее в repo1/.git/info/exclude, чтобы изменения в repo2 не смешивались с repo1:

repo2

Ответ 5

Я удивлен, что никто в этой теме не упомянул решения для управления пакетами.

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

По моему мнению, программное обеспечение для управления пакетами является неотъемлемой частью любого сложного проекта. Мне нравится композитор из-за интуитивно понятных рабочих процессов, которые он поддерживает: https://getcomposer.org/

К сожалению, подмодули git не поддерживаются PHPstorm: http://youtrack.jetbrains.com/issue/IDEA-64024

Ответ 6

Я также согласен с Рональдом Уильямсом выше. Основной целью git -подмодулей является обновление кода, взятого из внешнего мира, без необходимости внесения изменений, если этот код был изменен обновлением. То же самое и система управления пакетами композиторов. Фактически они не рекомендуют также совершать эти изменения и игнорировать папку vendor в .gitignore в корне проекта, Это кошмар, если вы попытаетесь зафиксировать эту папку, потому что некоторые из vendor/some_repo могут быть из dev-версии, поэтому у них есть .git-папка, из-за которой все эти пакеты становятся подмодулями, даже если вы не добавляйте их с помощью git submodule add. Вы можете увидеть что-то вроде этого, если вы изменяете some_file во вложенном репозитории .git:

~/project_root $ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#   (commit or discard the untracked or modified content in submodules)
#
#   modified:   vendor/nested_repo (modified content)

Обратите внимание на запись измененного содержимого в подмодулях и вы не видите имя some_file в выводе. Вместо этого вы видите уведомление (измененное содержимое), потому что root_project.git видит поставщик /nested _repo в качестве подмодуля и не отслеживает отдельные файлы в этой папке.

Если вы запустите git add -all, вы не получите никакого результата до тех пор, пока вы не введете изменения в vendor/nested_repo и только после этого сможете внести изменения в корневой репозиторий.

Не делай этого. Вместо этого, если вы хотите сохранить свой проект в целом. Репозиторий .git(любой, не только созданный композитором репозиторий), что очень удобно иногда, добавьте эту запись в корневой каталог .gitignore ПЕРЕД

.git
!/.git

К сожалению, для всего рецепта для работы вам нужно запустить команду git add для каждого из вложенных репозиториев, которые вы хотите изменить позже. Обратите внимание, что конечная косая черта в путях репозиториев ДОЛЖНА.

~/project_root $ git add vendor/some_repo/ vendor/another_repo/

Затем измените some_file в поставщике /some _repo и увидите разницу:

~/project_root $ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   vendor/some_repo/some_file

Таким образом, вы можете запустить git add --all, а затем git commit "Changes ..." в project_root, как обычно.