Библиотека сайта rus-linux.net
Git
Глава 6 из книги "Архитектура приложений с открытым исходным кодом", том 2.
Оригинал: Git
Автор: Susan Potter
Перевод: А.Панин
6.8. История объединения ветвей
Как было сказано ранее, подход системы Git к хранению истории объединения ветвей фундаментально отличается от подхода семейства систем контроля версий на основе RCS. Система Subversion, например, представляет историю изменения файла или дерева директорий в виде линейной последовательности; в этом случае любой элемент файловой системы с большим номером ревизии будет заменять элемент с меньшим номером ревизии. Непосредственное выделение ветвей не поддерживается и может осуществляться только путем самостоятельного создания специальной структуры директорий в репозитории.
Рисунок 6.4: Диаграмма, показывающая ход процесса объединения ветвей
Давайте используем пример для демонстрации проблем, которые могут возникать при поддержке множества ветвей для одной и той же работы. После этого мы рассмотрим сценарий, показывающий возникающие ограничения.
При работе с "ветвью" в системе Subversion в рамках стандартной корневой директории branches/branch-name
мы работаем с деревом поддиректорий директории trunk
(обычно в эквивалентной директории располагается код ветви master). Предположим, что в рамках этой ветви производится параллельная разработка программного компонента, изначально разрабатываемого в рамках директории trunk
.
К примеру, мы можем изменять кодовую базу приложения для поддержки другого типа базы данных. После частичной реализации необходимых функций у нас может возникнуть желание добавить в основную ветвь разработки код из поддиректории другой ветви (не относящийся к коду из директории trunk). Мы объединим изменения, прибегнув в случае необходимости к ручной правке, и продолжим нашу разработку. В конце концов мы закончим реализацию нашего кода для миграции на отличный тип базы данных в рамках ветви branches/branch-name
и объединим код ветви с кодом из директории trunk
. Проблема, с которой столкнутся пользователи таких систем контроля версий, как Subversion с линейным представлением истории изменений, заключается в том, что не существует способа получения информации о том, какие какие изменения из других ветвей были добавлены в код из директории trunk ранее.
Системы контроля версий, записывающие историю объединений ветвей с помощью направленных ациклических графов, такие, как Git, обрабатывают подобные сценарии достаточно хорошо. Предполагая, что другая ветвь не содержит изменений, которые были внесены в нашу ветвь с реализацией кода миграции на другой тип базы данных (скажем, ветви db-migration
из нашего репозитория Git), на основе взаимосвязей родительских объектов мы можем установить что изменения, внесенные в ветвь db-migration
содержали ссылку (tip или HEAD) на другую ветвь, в которой ведется основная разработка. Следует отметить, что объект добавления данных может не иметь или иметь произвольное количество (ограниченное только возможностями объединяющего ветки пользователя) родительских объектов. Следовательно, в случае объединения ветвей ветвь db-migration
получит информацию о том, будет ли она объединяться с текущей ветвью или с ветвью, в рамках которой производится основная разработка, получив хэши SHA родительских объектов. Это же утверждение актуально и для объединения с ветвью master
(эквивалентом директории trunk
при работе с системой Git).
Вопрос, на который сложно ответить при использовании истории объединений ветвей на основе направленных ациклических графов (и линейных представлений) заключается в том, какие изменения содержатся в каждой из ветвей. Например, в сценарии выше мы предположили, что все изменения из обоих рассматриваемых ветвей были внесены в каждую из ветвей. Но это не всегда так.
При работе в более простых ситуациях Git может извлекать изменения из других ветвей и вносить их в текущую ветвь, но только в том случае, если изменение может быть непосредственно применено без дополнительного редактирования.
Следующий раздел: Что дальше?