Что означает «ветвление бесплатно» в Git?

27

Что означает "ветвление бесплатно" в Git?

Я часто слышу об этом, когда упоминается Git по сравнению с другими системами контроля версий.

У меня не было возможности (?) Иметь дело с другими ( SVN и т. Д.), Так как же ветвление "дорого" в других?

laggingreflex
источник

Ответы:

28

Утверждение, что «ветвление свободно в 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 .

Spoike
источник
Вау. Большое спасибо за «дорогое» объяснение.
laggingreflex
2
Из вашего собственного источника: 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 тривиально, если вы явно не делаете копию каждого файла.
Бобсон
@Bobson Я думал о переписывании фрагментов ветвления, так как в связи с этим я много размахиваю руками, но моя точка зрения по-прежнему заключается в том, что для создания ветки требуется коммит, а в Git это не так. В моем скромном опыте я все еще чувствую, что переключение веток в SVN происходит медленнее, чем в Git, но я не могу указать на какую-либо конкретную причину, почему.
Спойл
2
@Spoike - Переключение, конечно. И обязательство определенно требуется. Я сделал правку, чтобы уточнить, с чем у меня была проблема. Не стесняйтесь вернуть его, если хотите.
Бобсон
20

Реальная стоимость филиала - это слияние. Git делает это проще, чем некоторые другие системы контроля версий. См. Вопрос переполнения стека. Как и / или почему слияние в Git лучше, чем в SVN? ,

dan_waterworth
источник
5
Строго говоря , Git делает это проще, чем некоторые другие SCM.
Donal Fellows
10

В Git ветка - это просто ссылка на коммит локального репо. Создание это очень дешево, нет сети вообще. Не совсем бесплатно (нужно набрать команду), но чертовски близко.

В SVN ветвление не особенно дорогое - это просто копия, что является очень дешевым коммитом. У SVN есть модель центрального хранилища, так что это сетевой доступ, но не ужасный.

В почтенном CVS, с другой стороны, ветвление очень дорого. По сути, ветки CVS включают добавление тега, но в CVS это означает, что КАЖДЫЙ ФАЙЛ ВОЗДЕЙСТВУЕТ, должен быть изменен. Каждый файл перезаписывается, чтобы включить новый тег. Это ужасно дорого. И если ваш репозиторий большой, он также ужасно медленный. На самом деле, если вы работаете над большим проектом, он достаточно медленный, и некоторые люди стараются избегать создания веток, если могут.

Майкл Кон
источник
4
С Git это даже меньше, чем коммит - ветка это просто метка. А SVN звучит так же дорого, как CVS, поскольку они оба копируют все файлы.
Изката
8
@Izkata: если мы видим с точки зрения пользователя - да, все файлы копируются, с точки зрения реализации (и производительности) - нет, просто добавляется запись о копировании.
maxim1000
@Изката слишком много, чтобы комментировать - см. Мой ответ.
gbjbaanb
6
@Izkata SVN создает указатели и ссылки, но не копирует все.
Аарон Макивер
2
Ветвь Git - это не коммит, это просто ссылка на коммит, который можно свободно перемещать в другие коммиты. Думайте о репозитории Git как о дереве коммитов, а о ветвях - как о заметках, которые можно свободно перемещать к различным коммитам в этом дереве.
40XUserNotНайдено
5

Ветвление SVN так же свободно, как и у Git. Это просто немного служебных данных, которые говорят, где начинается ветка, никаких изменений в сохраненных файлах. Копирование в SVN похоже на добавление символической ссылки в каталог Unix. Обратите внимание, что ветвь SVN не потребует отключения по сети, пока вы не зафиксируете изменения своей рабочей копии (но нет особого смысла иметь SCM, если в какой-то момент вы не зафиксируете его вне локальной сети).

Обратите внимание, что ветка Git также будет включать в себя некоторую служебную работу - например, добавление этого тега внутренне - это нужно будет где-то хранить при фиксации. Это не имеет большого значения, поэтому его называют «бесплатным».

gbjbaanb
источник
5

Это «бесплатно» (в данном контексте «бесплатно» действительно означает быстро и легко и не занимает места), потому что в некоторых старых системах контроля версий ветвь была полной копией кода на тот момент, поэтому ветки занимали много времени. места, и было легко получить много разных полностью полных версий программного обеспечения, которые затем взяли на себя управление. В других это была не полная копия кода, но каждый файл все еще нужно было модифицировать для тега, поэтому он был медленным и болезненным («дорогостоящим»).

Ветви git - это, по сути, метки, указывающие на коммит и, таким образом, избегающие вышеуказанных проблем

Майкл Даррант
источник
1

Другой аспект «бесплатно / дешево / дорого» связан с тем, сколько стоят затраты с точки зрения ресурсов разработчика, чтобы справиться с последующими последствиями ветвления; т.е. процесс слияния изменений из веток.

И здесь объединение ветвей в системах DVCS, таких как Git и Mercurial, проще, чем в старых системах ... потому что системы DVCS намного лучше отслеживают историю версий в графе; т.е. там, где произошло предыдущее ветвление, произошло слияние. Это делает слияния более точными, уменьшает ненужные конфликты и ... делает слияние субъективно «легче» или «менее страшным» для вовлеченных разработчиков.

Стивен С
источник