Ветки и хирургия

Сабтри

Сабтри копирует другой репозиторий в каталог вашего. После этого файлы действительно там: обычный git clone их забирает, git checkout двигает их как любые другие файлы, и никому не обязательно знать, что каталог пришёл откуда-то со стороны.

В этом и вся разница с сабмодулем, который хранит только указатель и требует --recurse-submodules, собственного чекаута и собственного detached HEAD, за которым надо следить.

⌘K → Сабтри.

Вендоренный каталог, найденный в истории, и источник, который Gitcito для него помнит

Подвох, о котором никто не говорит

Git не записывает для сабтри никакого манифеста. У сабмодуля есть .gitmodules со списком всех url и путей. У сабтри нет ничего — только трейлер git-subtree-dir: на коммите, которым сделали импорт.

Так что репозиторий может содержать сабтри и не дать вам никакой возможности узнать, откуда он взялся. Gitcito делает что может:

  • Список обнаруживается из истории, чтением этих трейлеров. Любой сабтри, добавленный кем угодно и каким угодно инструментом, будет показан.
  • Исходный репозиторий и ссылку запоминает Gitcito — в git-конфиге этого репозитория. У сабтри, обнаруженного из истории, эти поля поначалу пусты: заполните их один раз, и pull и push дальше работают.

Запомненные значения лежат под gitcito.subtree.* в .git/config, так что они остаются при репозитории, но не путешествуют в клон. Забыть очищает их и больше ничего не трогает.

Как добавить

Поле Что означает
Каталог Куда он ляжет, например vendor/parser. Не должен существовать заранее
Исходный репозиторий URL или путь на диске
Ветка или тег Что импортировать
Squash Затащить одним коммитом вместо всей истории

Оставьте Squash включённым, если у вас нет причины поступить иначе. Без него каждый коммит библиотеки навсегда вплетается в ваш лог, и git log перестаёт быть про ваш проект.

Жизнь с ним

Действие Что запускается
Pull git subtree pull — изменения из upstream приходят слиянием в ваш каталог
Push git subtree push — ваши локальные изменения под этим каталогом уходят обратно в источник
Split git subtree split -b <branch> — извлекает собственную историю каталога в ветку, где файлы лежат в корне

Split — то, о чём стоит знать: он превращает вендоренный каталог обратно в историю отдельного репозитория, и именно так сабтри перестаёт быть сабтри.

Ограничения, о которых стоит знать

  • Push медленный. Он каждый раз пересчитывает историю каталога с нуля. На большом репозитории это секунды или минуты, а не мгновение, и Gitcito может только ждать.
  • Pull — это слияние, так что он может конфликтовать, как любое слияние, — вы окажетесь в резолвере.
  • git subtree — это скрипт из contrib, а не встроенная команда git. В урезанной установке git его может не быть; Gitcito говорит об этом прямо, а не пересказывает «'subtree' is not a git command».
  • Схлопнутую историю нельзя расхлопнуть потом. Эти коммиты никогда не были импортированы.
  • Gitcito не превращает сабмодуль в сабтри и наоборот.

См. также: Слияние и ребейз · Низкоуровневые команды с интерфейсом

Улучшить этот перевод на GitHub