Следующим элементом вывода git status является сама директория проекта. Если вы выполните git diff для нее, то увидите кое-что интересное:
$git diff --cached DbConnector
diff --git a/DbConnector b/DbConnector
new file mode 160000
index 0000000..c3f01dc
--- /dev/null
+++ b/DbConnector
@@ -0,0 +1 @@
+Subproject commit c3f01dc8862123d317dd46284b05b6892c7b29bc
Хотя DbConnector является поддиректорией вашей рабочей директории, Git распознает ее как подмодуль и не отслеживает ее содержимое, когда вы не находитесь в этой директории. Вместо этого, Git видит ее как некоторый отдельный коммит из этого репозитория.
Если вам нужен немного более понятный вывод, то можете передать команде git diff опцию --submodule.
$git diff --cached --submodule
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..71fc376
--- /dev/null
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "DbConnector"]
+ path = DbConnector
+ url = https://github.com/chaconinc/DbConnector
Submodule DbConnector 0000000...c3f01dc (new submodule)
Когда вы выполните коммит, то увидите следующее:
$git commit -am 'added DbConnector module'
[master fb9093c] added DbConnector module
2 files changed, 4 insertions(+)
create mode 100644 .gitmodules
create mode 160000 DbConnector
Обратите внимание на права доступа 160000 у DbConnector. Это специальные права доступа в Git, которые, по сути, означают, что вы сохраняете коммит как элемент каталога, а не как поддиректорию или файл.
Клонирование проекта с подмодулями
Далее мы рассмотрим клонирование проекта, содержащего подмодули. Когда вы клонируете такой проект, по умолчанию вы получите директории, содержащие подмодули, но ни одного файла в них не будет:
$git clone https://github.com/chaconinc/MainProject
Cloning into 'MainProject'...
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 14 (delta 1), reused 13 (delta 0)
Unpacking objects: 100% (14/14), done.
Checking connectivity... done.
$cd MainProject
$ls -la
total 16
drwxr-xr-x 9 schacon staff 306 Sep 17 15:21 .
drwxr-xr-x 7 schacon staff 238 Sep 17 15:21 ..
drwxr-xr-x 13 schacon staff 442 Sep 17 15:21 .git
-rw-r--r-- 1 schacon staff 92 Sep 17 15:21 .gitmodules
drwxr-xr-x 2 schacon staff 68 Sep 17 15:21 DbConnector
-rw-r--r-- 1 schacon staff 756 Sep 17 15:21 Makefile
drwxr-xr-x 3 schacon staff 102 Sep 17 15:21 includes
drwxr-xr-x 4 schacon staff 136 Sep 17 15:21 scripts
drwxr-xr-x 4 schacon staff 136 Sep 17 15:21 src
$cd DbConnector/
$ls
$
Директория DbConnector присутствует, но она пустая. Вы должны выполнить две команды: git submodule init – для инициализации локального конфигурационного файла, и git submodule update – для извлечения всех данных этого проекта и переключения на соответствующий коммит, указанный в вашем основном проекте.
$git submodule init
Submodule 'DbConnector' (https://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
$git submodule update
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
Теперь ваша директория DbConnector находятся в точно таком же состоянии, как и ранее при выполнении коммита.
Однако, существует другой немного более простой вариант сделать тоже самое. Если вы передадите опцию --recursive команде git clone, то она автоматически инициализирует и обновит каждый подмодуль в этом репозитории.
$git clone --recursive https://github.com/chaconinc/MainProject
Cloning into 'MainProject'...
remote: Counting objects: 14, done.
remote: Compressing objects: 100% (13/13), done.
remote: Total 14 (delta 1), reused 13 (delta 0)
Unpacking objects: 100% (14/14), done.
Checking connectivity... done.
Submodule 'DbConnector' (https://github.com/chaconinc/DbConnector) registered for path 'DbConnector'
Cloning into 'DbConnector'...
remote: Counting objects: 11, done.
remote: Compressing objects: 100% (10/10), done.
remote: Total 11 (delta 0), reused 11 (delta 0)
Unpacking objects: 100% (11/11), done.
Checking connectivity... done.
Submodule path 'DbConnector': checked out 'c3f01dc8862123d317dd46284b05b6892c7b29bc'
Работа над проектом с подмодулями
Теперь у нас есть копия проекта с подмодулями. Давайте рассмотрим, как мы будет работать совместно с нашими коллегами над основным проектом и над подпроектом.
Получение изменений из вышестоящего репозитория
Простейший вариант использования подмодулей в проекте состоит в том, что вы просто получаете сам подпроект и хотите периодически получать обновления, но в своей копии проекта ничего не изменяете. Давайте рассмотрим этот простой пример.
Если вы хотите проверить наличие изменений в подмодуле, вы можете перейти в его директорию, выполнить git fetch и затем git merge для обновления локальной версии из вышестоящего репозитория.
$git fetch
From https://github.com/chaconinc/DbConnector
c3f01dc..d0354fc master -> origin/master
$git merge origin/master
Updating c3f01dc..d0354fc
Fast-forward
scripts/connect.sh | 1 +
src/db.c | 1 +
2 files changed, 2 insertions(+)
Теперь если вы вернетесь в основной проект и выполните git diff --submodule, то сможете увидеть, что подмодуль обновился, и получить список новых коммитов. Если вы не хотите каждый раз при вызове git diff указывать опцию --submodule, то можете установить такой формат вывода по умолчанию, задав параметру diff.submodule значение “log”.
Читать дальше