Ответ 1
Вы правы, Git подмодули не могут напрямую делать именно то, что вы хотите. Он работает в SVN, потому что корень репозитория, ветки и любой его подкаталог - это один и тот же объект. В Git репозиторий, ветвь и каталог представляют собой различные виды объектов (вы не можете использовать каталог как полный репозиторий или как ветвь).
Есть несколько косвенных способов выполнить то, что вы хотите.
Использование субмодулей и символических ссылок
Ядро подмодуля Git является клоном другого репозитория в дереве работы "суперпроекта" *. Git только клонирует полные репозитории. Невозможно клонировать только один подкаталог из существующего репозитория †.
* Нормальные подмодули также требуют специальной ссылки в суперпроекте commits/index и (обычно) записи в файле superproject .gitmodules
.
В несвязаном рабочем дереве можно иметь не отслеживаемые клоны других репозиториев, но такое использование не создает подмодуля.
† Git 1.7.0, а позже имеет функцию "редкой проверки", но это не помогло бы переместить каталог lib
на верхний уровень каждого клона подмодулей.
Однако вы можете использовать Git поддержку символических ссылок, чтобы сделать что-то довольно близко:
#
# Make the lib directory of each submodule appear in the superproject as
# lib/vendor/packages/$submod_name
#
# With this structure in each of the submodules (a, b, c):
#
# lib/
# tests/
#
# We end up with this structure in the superproject:
#
# lib/
# vendor/
# packages/
# a (a symlink to ../../../_submodules/a/lib)
# b (a symlink to ../../../_submodules/b/lib)
# c (a symlink to ../../../_submodules/c/lib)
# _submodules
# a/ (a Git submodule)
# lib/
# tests/
# b/ (a Git submodule)
# lib/
# tests/
# c/ (a Git submodule)
# lib/
# tests/
#
add_one() {
dir=lib/vendor/package
dest="$dir/$1"
# use fewer ".."s to put the _submodules closer to the symlinks
s=../../../_submodules/"$1"
git submodule add "$2" "$dir/$s"
ln -s "$s"/lib "$dest"
git add "$dest"
}
cd "$main_repo_toplevel"
mkdir -p lib/vendor/package
add_one a [email protected]:user/package-a.git
add_one b git://public.example.com/work/package-b-dev.git
add_one c ssh://special.example.com/foo.git
Использование Git поддерева
apenwarr git поддерево может отделить и объединить части репозиториев (т.е. отдельные подкаталоги, это оболочка вокруг "сложение поддерева" с другими приятными функциями). Первым шагом будет извлечение истории lib
в каждом из ваших подпроектов. Затем либо непосредственно используйте извлеченную историю как подмодуль, либо используйте поддерево Git, чтобы выполнить слияние поддерева в ваш основной репозиторий. В любом случае это обеспечит дополнительный шаг (повторное извлечение истории lib
), прежде чем вы сможете интегрировать изменения из подпроекта в основной репозиторий.