Утверждение, что «ветвление свободно в git» является упрощением фактов, потому что оно само по себе не «бесплатно». Если заглянуть под капот, то более правильным утверждением было бы сказать, что ветвление вместо этого обходится дешево , потому что ветки - это в основном ссылки на коммиты . Здесь я определяю «дешевизну» как меньшие накладные расходы, тем дешевле.
Давайте рассмотрим, почему Git такой «дешевый», изучив, какие накладные расходы у него есть:
Как ветки реализованы в git?
Репозиторий git, в .git
основном, состоит из каталогов с файлами, которые содержат метаданные, используемые git. Всякий раз, когда вы создаете ветку в git, например git branch {name_of_branch}
, происходит несколько вещей:
- Ссылка на местный филиал создается по адресу:
.git/refs/heads/{name_of_branch}
- Журнал истории создается для локальной ветки по адресу:
.git/logs/refs/heads/{name_of_branch}
Вот и все, пара текстовых файлов созданы. Если вы откроете ссылку в виде текстового файла, содержимое будет идентификатором шага коммита, на который указывает ветка. Обратите внимание, что ветвление не требует от вас каких-либо коммитов, поскольку они представляют собой объект другого типа. И ветки, и коммиты являются «первоклассными гражданами» в git, и один из способов - рассматривать отношения ветвь-к-коммит как совокупность, а не как композицию. Если вы удалите ветку, коммиты все еще будут существовать как «висячие». Если вы случайно удалили ветку, вы всегда можете попытаться найти коммит с помощью git-lost-found
или git-fsck --lost-found
и создать ветку на sha-id, который вы нашли оставленным висеть (и до тех пор, пока git еще не выполнил сборку мусора).
Так как же git отслеживает, над какой веткой вы работаете? Ответ с .git/HEAD
файлом, который выглядит примерно так, если вы находитесь на master
ветке.
ref: refs/heads/master
Переключение веток просто изменяет ссылку в .git/HEAD
файле, а затем переходит к изменению содержимого вашего рабочего пространства с теми, которые определены в коммите.
Как это соотносится в других системах контроля версий?
В Subversion ветви - это виртуальные каталоги в хранилище . Таким образом, самый простой способ ветвления - сделать это удаленно, с помощью одной строки svn copy {trunk-url} {branch-url} -m "Branched it!"
. SVN сделает следующее:
- Скопируйте исходный каталог, например
trunk
, в целевой каталог,
- Передайте изменения, чтобы завершить действие копирования.
Вы захотите выполнить это действие удаленно на сервере, потому что локальное создание этой копии - это операция с линейным временем, когда файлы копируются и символически связываются. Это очень медленная операция, тогда как выполнение на сервере - это операция с постоянным временем. Обратите внимание, что даже при выполнении ветвления на сервере subversion требует фиксации при ветвлении, а git нет, что является ключевым отличием. Это один из видов накладных расходов, который делает SVN чуть дешевле, чем Git.
Команда для переключения веток в SVN , т. Е.svn switch
Действительно svn update
скрытая. Благодаря концепции виртуального каталога команда немного более гибкая в svn, чем в git. Подкаталоги в вашем рабочем пространстве могут быть переключены для отражения другого URL репозитория. Самым близким было бы использование, git-submodule
но семантически его использование сильно отличается от ветвления. К сожалению, это также конструктивное решение, которое делает переключение немного медленнее в SVN, чем в Git, так как он должен проверять каждый каталог рабочей области, какой URL-адрес удаленного зеркала он отражает. По моему опыту, Git быстрее переключает ветки, чем SVN.
Разветвление SVN обходится дорого, поскольку оно копирует файлы и всегда должно быть общедоступным. В git, как объяснялось выше, ветки являются «просто ссылками» и могут храниться в вашем локальном репозитории и публиковаться на ваше усмотрение. Однако, по моему опыту, SVN все еще значительно дешевле и эффективнее, чем, например, ClearCase.
Облом только, что SVN не децентрализован. У вас может быть несколько репозиториев, отраженных в каком-либо исходном репозитории, но синхронизация различных изменений в нескольких SVN-репозиториях невозможна, поскольку SVN не имеет уникальных идентификаторов для коммитов (git хэширует идентификаторы, которые основаны на содержимом коммита). Причина, по которой я лично начал использовать git поверх SVN, заключается в том, что запуск репозитория в git значительно проще и дешевле . Концептуально с точки зрения управления конфигурацией программного обеспечения, каждая расходящаяся копия проекта (клон, разветвление, рабочая область или что-то еще) является «ветвью», и, учитывая эту терминологию, создание новой копии в SVN не так дешево, как Git, где последняя имеет филиалы "встроенные".
В качестве другого примера, в Mercurial ветвление начиналось немного иначе, чем DVCS, а создание / уничтожение именованных веток требовало отдельных фиксаций. Разработчики Mercurial, реализованные позже в закладках разработки, имитируют ту же модель ветвления в git, хотя heads
и называются tips
и branches
используются bookmarks
в терминологии Mercurial .
This command causes a near-instantaneous commit in the repository, creating a new directory in revision 341. The new directory is a copy of /calc/trunk.
- Создание ветки в SVN тривиально, если вы явно не делаете копию каждого файла.Реальная стоимость филиала - это слияние. Git делает это проще, чем некоторые другие системы контроля версий. См. Вопрос переполнения стека. Как и / или почему слияние в Git лучше, чем в SVN? ,
источник
В Git ветка - это просто ссылка на коммит локального репо. Создание это очень дешево, нет сети вообще. Не совсем бесплатно (нужно набрать команду), но чертовски близко.
В SVN ветвление не особенно дорогое - это просто копия, что является очень дешевым коммитом. У SVN есть модель центрального хранилища, так что это сетевой доступ, но не ужасный.
В почтенном CVS, с другой стороны, ветвление очень дорого. По сути, ветки CVS включают добавление тега, но в CVS это означает, что КАЖДЫЙ ФАЙЛ ВОЗДЕЙСТВУЕТ, должен быть изменен. Каждый файл перезаписывается, чтобы включить новый тег. Это ужасно дорого. И если ваш репозиторий большой, он также ужасно медленный. На самом деле, если вы работаете над большим проектом, он достаточно медленный, и некоторые люди стараются избегать создания веток, если могут.
источник
Ветвление SVN так же свободно, как и у Git. Это просто немного служебных данных, которые говорят, где начинается ветка, никаких изменений в сохраненных файлах. Копирование в SVN похоже на добавление символической ссылки в каталог Unix. Обратите внимание, что ветвь SVN не потребует отключения по сети, пока вы не зафиксируете изменения своей рабочей копии (но нет особого смысла иметь SCM, если в какой-то момент вы не зафиксируете его вне локальной сети).
Обратите внимание, что ветка Git также будет включать в себя некоторую служебную работу - например, добавление этого тега внутренне - это нужно будет где-то хранить при фиксации. Это не имеет большого значения, поэтому его называют «бесплатным».
источник
Это «бесплатно» (в данном контексте «бесплатно» действительно означает быстро и легко и не занимает места), потому что в некоторых старых системах контроля версий ветвь была полной копией кода на тот момент, поэтому ветки занимали много времени. места, и было легко получить много разных полностью полных версий программного обеспечения, которые затем взяли на себя управление. В других это была не полная копия кода, но каждый файл все еще нужно было модифицировать для тега, поэтому он был медленным и болезненным («дорогостоящим»).
Ветви git - это, по сути, метки, указывающие на коммит и, таким образом, избегающие вышеуказанных проблем
источник
Другой аспект «бесплатно / дешево / дорого» связан с тем, сколько стоят затраты с точки зрения ресурсов разработчика, чтобы справиться с последующими последствиями ветвления; т.е. процесс слияния изменений из веток.
И здесь объединение ветвей в системах DVCS, таких как Git и Mercurial, проще, чем в старых системах ... потому что системы DVCS намного лучше отслеживают историю версий в графе; т.е. там, где произошло предыдущее ветвление, произошло слияние. Это делает слияния более точными, уменьшает ненужные конфликты и ... делает слияние субъективно «легче» или «менее страшным» для вовлеченных разработчиков.
источник