Проект git-subrepo существует достаточно давно, однако упоминаний о нем незаслуженно мало. Автором git-subrepo является Ingy dot Net.


Если посмотреть на историю комитов master-ветки проекта, то может показаться, что проект остановился в развитии 2 года назад. Однако работы над проектом ведутся и хочется надеяться, что скоро будет выпущена версия 0.4.0.


Важным свойством данного средства является то, что на стороне пользователя нет необходимости устанавливать git-subrepo до тех пор, пока пользователь не решит делать комиты в upstream-репозитории подпроектов. Кроме того, пользователь получает полностью готовое и настроенное дерево исходного кода в момент копирования основного репозитория посредством стандартной команды git-clone(1).


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


  • необходимо ли хранить полную историю подпроекта в основном репозитории или достаточно squashed коммитов;
  • нужна ли возможность поставки изменений из подпроекта в upstream-репозиторий поддерева;
  • существует ли необходимость подключать фиксированные теги upstream-репозитория подпроекта или достаточно возможности подключения веток;
  • будет ли необходимо вдальнейшем удалять как сами подпроекты так и, ставшую не нужной, часть истории этих подпроектов;
  • должен ли будет пользователь предпринимать какие-либо действия для ручной настройки подпроектов после клонирования репозитория основного проекта;
  • насколько трудоемким окажется вопрос анализа истории подключения подпроектов и конкретных ревизий, от которых берет начало подпроект;
  • как повлияет то или иное средство на политику управления конфигурациями (Source Configuration Management) и, на сколько данное средство усложнит каждодневный труд инженеров.

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


Инсталляция git-subrepo


Пакет git-subrepo, на стороне разработчика, может быть установлен как локально, в своем домашнем каталоге, так и на системном уровне.


В первом случае, достаточно клонировать репозиторий git-subrepo в нужный каталог, например, ~/bin:


bash-4.4$ cd ~/bin
bash-4.4$ git clone https://github.com/ingydotnet/git-subrepo.git

и настроить переменные окружения


bash-4.4$ vim subrepo-env.sh
#!/bin/sh

export GIT_SUBREPO_ROOT="/home/username/bin/git-subrepo"
export PATH="/home/username/bin/git-subrepo/lib:$PATH"
export MANPATH="/home/username/bin/git-subrepo/man:$MANPATH"

:wq

bash-4.4$ source ./subrepo-env.sh

Если посмотреть переменные, определенные в Make-файле git-subrepo:


# Install variables:
PREFIX ?= /usr/local
INSTALL_LIB  ?= $(DESTDIR)$(shell git --exec-path)
INSTALL_EXT  ?= $(INSTALL_LIB)/$(NAME).d
INSTALL_MAN1 ?= $(DESTDIR)$(PREFIX)/share/man/man1

то легко выяснить, что на системном уровне git-subrepo устанавливается в каталог, где располагается Git:


bash-4.4$
bash-4.4$ git --exec-path
/usr/libexec/git-core
bash-4.4$

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


bash-4.4$ make PREFIX=/usr install

Наличие переменной DESTDIR позволяет без дополнительных усилий (разумеется, если мы находимся не в cross-окружении) сделать пакет для любого дистрибутива Linux, что может быть полезно для DevOps инженеров.


Инсталлируем git-subrepo от имени суперпользователя:


bash-4.4$
bash-4.4$ cd git-subrepo/
bash-4.4$ make PREFIX=/usr install
install -C -d -m 0755 /usr/libexec/git-core/
install -C -m 0755 lib/git-subrepo /usr/libexec/git-core/
install -C -d -m 0755 /usr/libexec/git-core/git-subrepo.d/
install -C -m 0755 lib/git-subrepo.d/help-functions.bash lib/git-subrepo.d/bash+.bash /usr/libexec/git-core/git-subrepo.d/
install -C -d -m 0755 /usr/share/man/man1/
install -C -m 0644 man/man1/git-subrepo.1 /usr/share/man/man1/
bash-4.4$

Для анализа возможностей git-subrepo нам понадобится простое тестовое окружение, где мы сможем воспроизвести стандартные сценарии работы.


Тестовое окружение


Создадим три каталога owner, remote, user, в которых разместим модели upstream- и локальных репозиториев разработчика и пользователя.


bash-4.4$ vim _init.sh
#!/bin/sh

CWD=`pwd`

mkdir remote owner user

cd remote
git init --bare build-system.git
git init --bare platform.git

cd ../owner

git clone $CWD/remote/build-system.git
git clone $CWD/remote/platform.git

cd build-system
echo -e "\n[master] build-system 1.0.0\n" >README
git add README
git commit -m "init build-system master 1.0.0"
git push

cd ../platform

echo -e "\n[master] platform 1.0.0\n" >README
git add README
git commit -m "init platform master 1.0.0"
git push

cd ../../user

git clone $CWD/remote/build-system.git
git clone $CWD/remote/platform.git

cd $CWD

:wq

bash-4.4$
bash-4.4$ ./_init.sh
bash-4.4$


Здесь,


owner рабочий каталог автора проектов ;
remote каталог представляющий сервер автора проектов, на котором располагаются upstream-репозитории основного проекта platform.git и подпроекта build-system.git ;
user рабочий каталог пользователя или участника команды разработчиков.

Автор проекта и пользователи имеют собственные копии upstream-репозиториев на своих машинах, представленные в нашем примере в каталогах owner и user соответствено.


Задача автора состоит в том, чтобы включив подпроект builld-system в основное дерево platform обеспечить пользователям и участникам проекта следующие возможности:


  • клонировать основной репозиторий с включенным в его состав подпроектом build-system и при этом не заботиться о настройке версиий или ревизий. То есть каждой ветке репозитория platform должна соответствовать определенная ревизия определенной ветки репозитория build-system и пользователь должен получать настроенное дерево исходников за одну операцию git-clone(1), без каких-либо дополнительных действий.
  • поставлять свои изменения в upstream репозитории проекта, как в основной, так и во вспомогательный.
  • получать изменения, сделанные другими участниками проекта или пользователями, разумеется если они имеют соответствующие права.

Рассмотрим действия автора, которые он должен осуществить для реализации данных требований.


Подключение субпроекта


Для подключения нового поддерева следует воспользоваться командой git subrepo clone, которая по своему назначению похожа на команду git-clone(1). Обязательным параметром команды служит URL удаленного репозитория. Также можно указать каталог в котором будет располагаться подпроект и ветку удаленного репозитория. Мы будем работать с master-ветками, поэтому, в нашем примере, мы опускаем ненужные параметры комманд.


Итак, автор проекта, на своей рабочей машине, может подключить подпроект build-system с помощью команды git subrepo clone ../../remote/build-system.git/ build-system:


bash-4.4$
bash-4.4$ cd owner/platform/
bash-4.4$ git subrepo clone ../../remote/build-system.git/ build-system
Subrepo '../../remote/build-system.git' (master) cloned into 'build-system'.
bash-4.4$

Рассмотрим, какие изменения произошли в локальном репозитории platform:


bash-4.4$
bash-4.4$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
bash-4.4$
bash-4.4$
bash-4.4$ git subrepo status
1 subrepo:

Git subrepo 'build-system':
  Remote URL:      ../../remote/build-system.git
  Upstream Ref:    b2f5079
  Tracking Branch: master
  Pulled Commit:   b2f5079
  Pull Parent:     b5e76a7

bash-4.4$ 

История подпроекта build-system не поставляется в основное дерево, мы имеем лишь один squashed-комит, который сопровождается справочной информацией. Данная информация поступает под версионный контроль в файле ./build-system/.gitrepo/config:


[subrepo]
	remote = ../../remote/build-system.git
	branch = master
	commit = b2f507918f2821cb7dd90c33223ed5cc3c9922a2
	parent = b5e76a713f895565b06ee3ccfa29f19131ba06dd
	method = merge
	cmdver = 0.4.1

Информацию о подпроектах можно получать с помощью команды git subrepo config, например узнать ревизию upstream-проекта remote/build-system.git, которая только что пришла в основной репозиторий, можно в помощью команды:


bash-4.4$
bash-4.4$ git subrepo config build-system commit
Subrepo 'build-system' option 'commit' has value 'b2f507918f2821cb7dd90c33223ed5cc3c9922a2'.
bash-4.4$

Следует упомянуть о том, что оригинальный пакет git-subrepo сохраняет информацию о подпроектах не в файле .gitrepo/config, а в файле .gitrepo. Если вы предпочитаете хранить информацию в скрытом подкаталоге, то можете выбрать ветку git-subrepo-0.3.2 или git-subrepo-0.4.1 дочернего репозитория git-subrepo.

Итак, мы получили последнюю версию master-ветки upstream-репозитория remote/build-system.git и поместили ее в подкаталог build-system основного проекта platform.


Для поставки этих изменений в upstream-репозиторий remote/platform.git, автору необходимо выполнить команду git push:


bash-4.4$
bash-4.4$ git push
Enumerating objects: 7, done.
Counting objects: 100% (7/7), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 849 bytes | 849.00 KiB/s, done.
Total 6 (delta 0), reused 0 (delta 0)
To /home/prog/0.4.1/remote/platform.git
   <font color="#8b0000">b5e76a7..6b831e4</font>  master -> master
bash-4.4$

Более подробную информацию о командах git subrepo можно получить из файла ReadMe.pod или в командной строке


bash-4.4$ git subrepo help <command>

например:


bash-4.4$ git subrepo help clone

Рассмотрим теперь все происходящее со стороны пользователя.



Получение кода пользователями


На данный момент, когда пользователь еще не получил обновления upstream-репозитория platform.git, его копия содержит один файл README


bash-4.4$
bash-4.4$ cd user/platform/
bash-4.4$ ls
README
bash-4.4$

содержащий одну строку:


bash-4.4$
bash-4.4$ cat README 

[master] platform 1.0.0

bash-4.4$

После снятия изменений upstream-репозитория


bash-4.4$
bash-4.4$ git pull
remote: Enumerating objects: 7, done.
remote: Counting objects: 100% (7/7), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 6 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (6/6), done.
From /home/prog/0.4.1/remote/platform
   b5e76a7..6b831e4  master     -> origin/master
Updating <font color="#8b0000">b5e76a7..6b831e4</font>
Fast-forward
 build-system/.gitrepo/config | 12 ++++++++++++
 build-system/README          |  3 +++
 2 files changed, 15 insertions(+)
 create mode 100644 build-system/.gitrepo/config
 create mode 100644 build-system/README
bash-4.4$

пользователь будет иметь в своем распоряжении код подпроекта build-system именно той ревизии, которую определил автор проекта. Пользователь может в любой момент уточнить текущую ревизию с помощью команды config:


bash-4.4$
bash-4.4$ git subrepo config build-system/ commit
Subrepo 'build-system' option 'commit' has value 'b2f507918f2821cb7dd90c33223ed5cc3c9922a2'.
bash-4.4$

Примечательно то, что у пользователя нет необходимости осуществлять дополнительные настройки и он может положиться на то, что автор проекта поставил ему именно ту ревизию build-system, которая необходима для работы текущей версии platform.


Именно этого добивался автор проекта.


Поставка изменений в upstream-проект


Допустим теперь, что наш пользователь является участником проекта и ему разрешено поставлять изменения не только в upstream-репозиторий remote/platform.git, но еще и в upstream-репозиторий подпроекта remote/build-system.git.


Тогда, если пользователь сделает изменения:


bash-4.4$
bash-4.4$ cd build-system/
bash-4.4$ vim README
bash-4.4$ cat README

[master] build-system 1.0.1

bash-4.4$
bash-4.4$ git commit -a -m "update BS version to 1.0.1"
[master d30b001] update BS version to 1.0.1
 1 file changed, 1 insertion(+), 1 deletion(-)
bash-4.4$
bash-4.4$ cd ..
bash-4.4$ git log
commit d30b001286b08708f5c30c1f5346a90e4339f969 (HEAD -> master)
Author: user <___@_____>
Date:   Tue Oct 30 10:49:32 2018 +0300

    update BS version to 1.0.1

 . . .

bash-4.4$ 

он сможет поставить их в upstream-репозитории следующим образом:


bash-4.4$
bash-4.4$ git subrepo push build-system/
Subrepo 'build-system' pushed to '../../remote/build-system.git' (master).
bash-4.4$

Здесь важно заметить, что ...

Поскольку файлы конфигурации подпроектов .gitrepo/config хранятся под версионным контролем, пользователю необходимо отослать изменения статуса подпроекта в upstream-репозиторий основного проекта remote/platform.git.


То есть пользователь не должен забывать о проверке статуса локального репозитория и вовремя выполнять команду git-push(1).


bash-4.4$
bash-4.4$ git status
On branch master
Your branch is ahead of 'origin/master' by 2 commits.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
bash-4.4$
bash-4.4$ git push
Enumerating objects: 14, done.
Counting objects: 100% (14/14), done.
Delta compression using up to 4 threads
Compressing objects: 100% (7/7), done.
Writing objects: 100% (9/9), 992 bytes | 992.00 KiB/s, done.
Total 9 (delta 1), reused 0 (delta 0)
To /home/prog/0.4.1/remote/platform.git
   d00be9f..deccb66  master -> master
bash-4.4$

В противном случае, при последующем снятии изменений upstream-репозитория, он получит merge-конфликт.


Разумеется, здесь нет ни чего необычного, однако, после выполнения команды git subrepo push ..., легко забыть о состоянии локальной копии основного репозитория.




Непосредственная работа с upstream-репозиторием


Рассмотрим теперь, что произошло в upstream-репозитории remote/build-system.git


bash-4.4$
bash-4.4$ cd owner/build-system/
bash-4.4$
bash-4.4$ git pull
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
From /home/prog/0.4.1/remote/build-system
   b2f5079..d229920  master     -> origin/master
Updating b2f5079..d229920
Fast-forward
 README | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
bash-4.4$
bash-4.4$ git log
commit d229920c7de34405bc7b8d47f36d420987687908 (HEAD -> master, origin/master)
Author: user <___@_____>
Date:   Tue Oct 30 10:49:32 2018 +0300

    update BS version to 1.0.1

commit b2f507918f2821cb7dd90c33223ed5cc3c9922a2
Author: user <___@_____>
Date:   Tue Oct 30 10:05:30 2018 +0300

    init build-system master 1.0.0
bash-4.4$

То есть автор проекта получил изменения, внесенные участником проекта.


Разумеется, автор может вносить изменения непосредственно в upstream-репозиторий проекта build-system:


bash-4.4$
bash-4.4$ cd owner/build-system/
bash-4.4$
bash-4.4$ vim README
bash-4.4$ cat README

[master] build-system 1.0.2

bash-4.4$ git commit -a -m "update build-system version to 1.0.2"
[master 8255f59] update build-system version to 1.0.2
 1 file changed, 1 insertion(+), 1 deletion(-)
bash-4.4$ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (3/3), 281 bytes | 281.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /home/prog/0.4.1/remote/build-system.git
   d229920..8255f59  master -> master
bash-4.4$

И все участники, а также пользователи основного проекта смогут получать эти изменения с помощью команды git subrepo pull


bash-4.4$
bash-4.4$ cd owner/platform/
bash-4.4$
bash-4.4$ git subrepo pull build-system/
Subrepo 'build-system' pulled from '../../remote/build-system.git' (master).
bash-4.4$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean
bash-4.4$ git push
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 4 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (6/6), 670 bytes | 670.00 KiB/s, done.
Total 6 (delta 1), reused 0 (delta 0)
To /home/prog/0.4.1/remote/platform.git
   6b831e4..b6f4a7b  master -> master
bash-4.4$

Выводы


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


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


bash-4.4$ git subrepo clone ../../remote/build-system.git build-system -t 1.0.1
bash-4.4$ git subrepo clone ../../remote/build-system.git build-system 7f5d1113eb0bc6

не допустимы.


ЛИТЕРАТУРА:


Комментарии (25)


  1. Andy_U
    01.11.2018 14:10

    А не могли бы Вы сравнить возможности данного расширения с git subtree? Заранее спасибо.


    1. rcl Автор
      01.11.2018 15:08

      Обязательно. Я сейчас работаю над описанием внутренностей git-subtree и скоро выдам раезультат.


  1. gecube
    01.11.2018 19:34
    +1

    Я сейчас исследую возможности git'а для построения сложных проектов.
    Пока что осилил submodules. Они достаточно удобны, когда не нужно напрямую менять содержимое субмодулей. А ещё они нативной поддерживаются средствами сборки кода — gitlab-ci & co.
    Интересно узнать альтернативные подходы, но чтобы удовлетворить это требование + чтобы было этими подходами удобно


    1. alex1t
      02.11.2018 01:05
      +1

      Пользуемся сабмодулями достаточно активно для общих подпроектов сервисов. Всё можно менять и из основного репозитория. Точнее для работы с гитом сабмодуля — входишь в него и делаешь всё как и везде. Даже VSCode поддерживает работу с сабмодулями


  1. gdt
    02.11.2018 08:22

    В чём преимущество перед сабмодулями?


    1. rcl Автор
      02.11.2018 08:45

      Дело не в преимуществе, а в целесообразности. Главное отличие состоит в том, что при использовании submodules, пользователь снимает репозиторий-контейнер практически не настроенным и ему надо проделывать дополнительные мероприятия по согласованию ревизий подмодулей и репозитория-контейнера (так или иначе, это именно так, и автор проекта должен обеспечить пользователя соответствующими инструкциями, будь то простая инструкция по клонированию `git clone --recurse-submodules ...' или другое напоминание). Если же мы говорим о git-subrepo и git-subtree, то здесь, копируя репозиторий-контейнер, пользователь получает полностью настроенное дерево за одну операцию git-clone(1). Все для него уже сделано автором. А в остальном, все зависит от задач, которые решает автор и от его политики SCM (Source Configuration Management).


      1. gecube
        02.11.2018 10:08
        +1

        Т.е. правильно ли я понимаю, что раз тут все проделывается за одну команду git-clone, то интеграция с системами сборки получается прозрачная и автоматическая?


        1. rcl Автор
          02.11.2018 11:15

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


    1. rcl Автор
      02.11.2018 09:15

      Представим, например, следующую задачу. Ваш проект состоит из нескольких подпроектов/модулей и, допустим, один модуль представляет исходный код межмодульных интерфейсов. Набор интерфейсов, разрабатываемый отдельной командой, должен быть фиксирован для каждой ветки вашего проекта. Более того, никто из других команд разработчиков не должен иметь права изменять код интерфейсов, а наоборот, совершенствовать свой модуль в строгой согласованности с другими.

      В этом случае CM инженер решит поставлять в каждую ветку проекта конкретные, фиксированыые ревизии интерфейсного модуля и постарается запретить любые комиты со стороны разработчиков. Только при переходе на новую версию интерфейсного модуля, все остальные команды создадут новые ветки собственных модулей, подключат к ним новую версию интерфейсного модуля и начнут работать над собственным кодом с целью приведения его в соответствие новой версии интерфейсов.

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


  1. calg0n
    02.11.2018 10:39
    +1

    Ну фиг знает. Всё таки надёжнее каждый модуль проекта хранить в отдельной репе с полноценной историей. В основном проекте создаём папочку subreps, добавляем её в gitignore, в subreps клоним полноценные репы.


    1. Andy_U
      02.11.2018 11:21

      Вот только что делать при таком подходе, если у вас несколько веток в проекте и к каждой отдельной ветке нужно подцеплять «свою» ветку из другого проекта. git subtree эту проблему решает на раз. Единственное неудобство — merge между своими ветками нужно делать осторожно, чтобы подпроекты не смержились.


      1. calg0n
        02.11.2018 11:24
        +1

        А какая разница сколько веток и какой проект? Это ж полноценные репы, цепляйте что хотите.


        1. Andy_U
          02.11.2018 11:26

          Вы предлагаете после смены ветки в своем проекте еще ручками менять ветки в «подпроектах»?


          1. calg0n
            02.11.2018 11:30

            Ну не руками это делать в каждой репе конечно же :) Это легко автоматизируется скриптом.


          1. ashumkin
            03.11.2018 00:05

            git submodule update — это слишком сложно? :)


            1. Andy_U
              03.11.2018 00:26

              Я отвечал calg0n, который submodule не использует. См.выше.


      1. gdt
        02.11.2018 12:06

        В проекте, над которым я работаю, мы используем submodule и каждая ветка основного проекта связана с конкретной веткой сабмодуля. Меняю ветку — сабмодуль тоже меняется, что я делаю не так?


        1. calg0n
          02.11.2018 13:46

          Это если один проект. А если несколько проектов используют общий функционал? Если у каждого проекта своя репа и этот общий функционал нужно использовать в них. Сабмодули тут не подойдут.


          1. gdt
            02.11.2018 14:46

            Есть как минимум ещё один проект, где используется тот же самый сабмодуль.


            1. calg0n
              02.11.2018 15:05

              А как вы разруливаете конфликты когда несколько разрабов работают над общей репой?


              1. gdt
                02.11.2018 15:08

                Как обычно, не вижу разницы, если честно. Фичи делаются в отдельных ветках, перед merge делаем rebase чтобы свести конфликты к минимуму, если какие-то ломающие изменения — то да, всем придётся править код, но только после принудительного обновления сабмодуля до мастера (т. е. ничего не ломается само по себе).


                1. calg0n
                  02.11.2018 15:21

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


                  1. gdt
                    02.11.2018 15:39

                    Ну как, у нас сабмодуль — это полноценный репозиторий. В том плане, что если изменения в проекте требуют изменений в сабмодуле — делается отдельная ветка и там и там, два пулл реквеста и т. д. За счёт линейной истории конфликты сведены к минимуму. Грубо говоря, для проекта сабмодуль — это внешний компонент, и конфликт сводится к тому, что есть хэш, в котором реализована фича А, и есть хэш, в котором она не реализована, ничего сложного.
                    Проблемы с мержем сабмодулей, про которые вы говорите, за полтора года работы над этим проектом встречались раза два.


                    1. calg0n
                      02.11.2018 15:53

                      Мы постоянно сталкиваемся с конфликтами в своей общей репе :) Тут зависит от проекта конечно же, но с т.з. полноценного подрепозитория сабмодули нам не подошли.


    1. rcl Автор
      02.11.2018 11:22

      git-subrepo и git-subtree не отменяет возможность ведения upstream-репозиториев как самостоятельных продуктов, а в основном дереве держать либо squashed-комиты, либо полноценные истории.

      А на счет папочек в .gitignore все зависит от CM инженера. Либо он настраивает права пользователей и хуки, либо он отдает все на откуп инженерам команды разработчиков.

      Товарищ Сухов сказал: «Лучше конечно помучиться.»