Close

git subtree: альтернатива git submodule

Фотография Николы Паолуччи
Никола Паолуччи

Консультант по разработке


В Интернете полно статей о том, почему не стоит использовать подмодули Git. В отдельных ситуациях подмодули все же полезны, однако не лишены недостатков.

Есть ли альтернативы? Да! Как минимум два инструмента позволят вам отслеживать историю зависимостей ПО в проекте, по-прежнему работая с git:

  • Поддерево Git
  • Репозиторий Google

В этой статье рассматривается команда git subtree и объясняется, почему это средство хотя и не идеально, но тем не менее лучше git submodule.

Что такое команда git subtree и зачем ее использовать?


git subtree позволяет вложить один репозиторий в другой в виде подкаталога. Это один из способов управления зависимостями в проектах Git.

Схема «До и после использования git subtree»

git subtree обладает следующими преимуществами.

  • Легко управлять несложными рабочими процессами.
  • Поддерживаются предыдущие версии Git (даже старше 1.5.2).
  • Код подпроекта доступен сразу после клонирования суперпроекта.
  • При использовании git subtree пользователям репозитория не нужно осваивать новые навыки. Управление зависимостями с помощью git subtree никак не влияет на их работу.
  • Использование git subtree не приводит к добавлению новых файлов метаданных, в отличие от применения git submodule (файл .gitmodules).
  • Содержимое модуля может быть изменено без копирования зависимости в отдельный репозиторий.

Недостатки (которые мы в большинстве случаев считаем несущественными) перечислены ниже.

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

Перемещение полного репозитория Git

Логотип Bitbucket
СМ. РЕШЕНИЕ

Изучите Git с помощью Bitbucket Cloud

Использование git subtree


Команда git subtree доступна в стандартной версии Git с мая 2012 года (т. е. начиная с версии 1.7.11). В версии, которую устанавливает утилита Homebrew в OS X, команда subtree уже настроена, но на некоторых платформах может понадобиться выполнить инструкции по установке.

Ниже приведен классический пример того, как можно отслеживать плагин vim с помощью git subtree.

Быстрый, но неоптимальный способ без удаленного отслеживания

Если вас интересуют однострочные скрипты, которые можно просто скопировать и вставить, достаточно будет прочитать этот раздел. Сначала добавьте git subtree в папку с указанным префиксом:

git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

(Обычно в главном репозитории не хранят полную историю подпроекта, но если вы захотите ее оставить, то просто не используйте флаг --squash.)

Вывод приведенной выше команды:

git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'

Как видите, в результате создан коммит слияния путем склеивания коммитов по всей истории репозитория vim-surround:

1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]

Если позднее вы захотите обновить код плагина содержимым из вышестоящего репозитория, можете просто осуществить pull в git subtree:

git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash

В этом нет ничего сложного, кроме того, что команды довольно длинные, из-за чего их трудно запомнить. Укоротим их, добавив подпроект как удаленное подключение.

Добавление подпроекта в качестве удаленного подключения

Добавив поддерево subtree в виде удаленного подключения, мы сможем ссылаться на него в краткой форме:

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

Теперь, как и раньше, добавим subtree, только на этот раз ссылка на удаленный репозиторий будет краткой:

git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

Команда для последующего обновления подпроекта будет выглядеть так:

git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

Отправка кода в вышестоящую ветку

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

git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git

Теперь можно выполнить команду subtree push:

git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main

Все готово, и можно открывать запрос pull для специалиста, сопровождающего пакет.

Можно ли сделать то же самое без команды git subtree?

Конечно! git subtree и слияние поддерева — разные стратегии. Слияние можно использовать, даже если по какой-то причине команда git subtree недоступна. Порядок действий следующий.

Добавим зависимость как простое удаленное подключение Git:

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git

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

git merge -s ours --no-commit tpope-vim-surround/main

Вывод команды будет следующим:

Automatic merge went well; stopped before committing as requested

Считаем содержимое последнего дерева из репозитория плагина в рабочий каталог, готовый к коммиту:

git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main

Теперь можно выполнить коммит (это будет коммит слияния, при котором сохранится история считанного дерева):

git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround

Чтобы обновить проект, можно осуществить pull, используя стратегию слияния git subtree:

git pull -s subtree tpope-vim-surround main

git subtree — отличная альтернатива


Поработав с git submodule, вы заметите, что многих проблем можно избежать, перейдя на git subtree. Но конечно, как и с другими функциями Git, придется потратить время и силы на освоение этой возможности, чтобы использовать ее максимально эффективно.

Подпишитесь на меня в Twitter (@durdn), чтобы пополнять свои знания о Git. А если вы ищете хороший инструмент для управления репозиториями Git, советую попробовать Atlassian Bitbucket.

Обновление: опубликовав эту статью, я написал еще одну — о мощных возможностях git subtree.

Nicola Paolucci

Nicola is an all-round hacker who loves exploring and teaching bleeding edge technologies. He writes and talks about Git, development workflows, code collaboration and more recently about Docker. Prior to his current role as Developer Instigator at Atlassian he led software teams, built crowd sourcing applications for geo-spacial data, worked on huge e-commerce deployments. Little known facts about Nicola: he gesticulates a lot while speaking (being Italian), lives in Amsterdam and rides a Ducati.


Поделитесь этой статьей
Следующая тема

Рекомендуемые статьи

Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.

Люди сотрудничают друг с другом, используя стену со множеством инструментов

Блог Bitbucket

Рисунок: DevOps

Образовательные программы DevOps

Демонстрация функций в демо-зале с участием экспертов Atlassian

Как инструмент Bitbucket Cloud работает с Atlassian Open DevOps

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up