Прежде всего, как указывают @AndrewFinnell и @KenLiu, в SVN имена каталогов сами по себе ничего не значат - «ствол, ветви и теги» - это просто общее соглашение, которое используется большинством репозиториев. Не во всех проектах используются все каталоги (достаточно часто вообще не использовать «теги»), и на самом деле ничто не мешает вам называть их как угодно, хотя нарушение соглашения часто сбивает с толку.
Я опишу, вероятно, наиболее распространенный сценарий использования ветвей и тегов и приведу пример сценария их использования.
Магистраль : основная зона разработки. Это место, где живет ваш следующий основной выпуск кода, и, как правило, имеет все новейшие функции.
Ветви : Каждый раз, когда вы выпускаете основную версию, создается ветка. Это позволяет вам исправлять ошибки и создавать новые версии, не выпуская новейшие - возможно, незавершенные или непроверенные - функции.
Теги : Каждый раз, когда вы выпускаете версию (финальный выпуск, релиз-кандидаты (RC) и бета-версии), вы делаете для нее тег. Это дает вам на момент времени копию кода, которая была в этом состоянии, позволяя вам вернуться и воспроизвести любые ошибки, если это необходимо в предыдущей версии, или переиздать предыдущую версию в точности так, как это было. Ветви и теги в SVN облегчены - на сервере он не создает полную копию файлов, а просто маркер, говорящий «эти файлы были скопированы с этой версией», занимающий всего несколько байтов. Имея это в виду, вы никогда не должны беспокоиться о создании тега для любого выпущенного кода. Как я уже говорил ранее, теги часто опускаются, и вместо этого в журнале изменений или другом документе номер редакции уточняется при выпуске.
Например, допустим, вы начинаете новый проект. Вы начинаете работать в «стволе», над чем в конечном итоге будет выпущена версия 1.0.
- trunk / - версия для разработки, скоро будет 1.0
- ветви / - пусто
Как только 1.0.0 закончен, вы ветвитесь на ствол в новую ветку "1.0" и создаете тег "1.0.0". Теперь работа над тем, что в итоге будет 1.1, продолжается в багажнике.
- trunk / - версия для разработки, скоро будет 1.1
- филиалы / 1.0 - 1.0.0 релизная версия
- теги / 1.0.0 - версия 1.0.0
Вы сталкиваетесь с некоторыми ошибками в коде и исправляете их в trunk, а затем объединяете исправления с веткой 1.0. Вы также можете сделать обратное и исправить ошибки в ветке 1.0, а затем объединить их обратно в транк, но обычно проекты придерживаются одностороннего объединения только для уменьшения шансов что-то упустить. Иногда ошибка может быть исправлена только в 1.0, потому что она устарела в 1.1. Это на самом деле не имеет значения: вам нужно только убедиться, что вы не выпускаете 1.1 с теми же ошибками, которые были исправлены в 1.0.
- trunk / - версия для разработки, скоро будет 1.1
- Branchs / 1.0 - Предстоящий релиз 1.0.1
- теги / 1.0.0 - версия 1.0.0
Как только вы найдете достаточно ошибок (или, может быть, одну критическую ошибку), вы решаете выпустить 1.0.1. Итак, вы делаете тег «1.0.1» из ветки 1.0 и выпускаете код. На этом этапе транк будет содержать то, что будет 1.1, а ветвь "1.0" содержит код 1.0.1. В следующий раз, когда вы выпустите обновление до 1.0, это будет 1.0.2.
- trunk / - версия для разработки, скоро будет 1.1
- Branchs / 1.0 - Предстоящий релиз 1.0.2
- теги / 1.0.0 - версия 1.0.0
- тегов / 1.0.1 - версия 1.0.1
В конце концов вы почти готовы к выпуску 1.1, но сначала вы хотите сделать бета-версию. В этом случае вы, скорее всего, сделаете ветку «1.1» и тег «1.1beta1». Теперь работа над тем, что будет 1.2 (или, может быть, 2.0), продолжается в транке, но работа над 1.1 продолжается в ветви "1.1".
- trunk / - версия для разработки, скоро будет 1.2
- branch / 1.0 - готовится к выпуску 1.0.2
- филиалов / 1.1 - предстоящий выпуск 1.1.0
- теги / 1.0.0 - версия 1.0.0
- теги / 1.0.1 - версия 1.0.1
- теги / 1.1beta1 - версия 1.1 1.1 beta 1
Как только вы выпускаете 1.1 final, вы делаете тег "1.1" из ветви "1.1".
Вы также можете продолжать поддерживать 1.0, если хотите, портируя исправления ошибок между всеми тремя ветвями (1.0, 1.1 и trunk). Важным выводом является то, что для каждой основной версии программного обеспечения, которую вы поддерживаете, у вас есть ветвь, которая содержит последнюю версию кода для этой версии.
Другое использование веток для функций. Здесь вы ветвитесь в ствол (или одну из веток релиза) и работаете над новой функцией изолированно. Как только функция завершена, вы объединяете ее и удаляете ветку.
- trunk / - версия для разработки, скоро будет 1.2
- Branchs / 1.1 - предстоящая версия 1.1.0
- branch / ui-rewrite - экспериментальная ветвь функций
Идея этого заключается в том, что вы работаете над чем-то разрушительным (что может задержать или мешать другим людям выполнять свою работу), чем-то экспериментальным (что может даже не войти), или, возможно, просто тем, что требует долгое время (и вы боитесь, что если он будет поддерживать релиз 1.2, когда вы будете готовы перейти с 1.2 на транк), вы можете сделать это изолированно в ветке. Как правило, вы поддерживаете его в актуальном состоянии с транком, постоянно объединяя в него изменения, что облегчает повторную интеграцию (слияние обратно в транк), когда вы закончите.
Также обратите внимание, что схема управления версиями, которую я здесь использовал, является лишь одной из многих. Некоторые команды могут делать исправления ошибок / выпуски поддержки как 1.1, 1.2 и т. Д., А основные изменения - как 1.x, 2.x и т. Д. Здесь используется то же самое, но вы можете назвать ветвь «1» или «1». .x "вместо" 1.0 "или" 1.0.x ". (Кроме того, семантическое управление версиями - хорошее руководство о том, как делать номера версий).