Как работают ветки Git?
Ветки являются основной функцией отслеживания версий Git и постоянно используются командами, работающими над одной и той же кодовой базой программного обеспечения. Мы углубимся в то, как они работают внутри, и как вы можете использовать их для улучшения рабочего процесса Git.
Что такое филиалы на самом деле?
Ветки используются для разделения истории Git. Вы можете думать о коммитах Git как о череде изменений, уходящих в прошлое. Вы можете «проверить» любой из этих коммитов и переместить свой локальный каталог назад во времени в состояние, в котором он был, когда этот коммит был сделан.
Ветки обычно используются для работы над экспериментальными функциями или изменениями, которые требуют времени, или чем-то еще, что может нарушить репозиторий. Например, вы можете работать над рефакторингом большого компонента своей кодовой базы, и до тех пор, пока это не будет сделано, вы хотите, чтобы ветка master
была стабильной.
Как только новая ветка feature
станет стабильной, ее можно снова объединить с master
, часто с помощью запроса на включение, что представляет собой процесс, позволяющий обзор кода и тестирование, которые должны быть выполнены до внесения изменений.
Однако под капотом ветки работают немного иначе, чем вы могли бы ожидать на первый взгляд. В Git ветки — это просто метки или указатели на конкретный коммит. Вот и все, ветка master
просто указывает на последнюю фиксацию, сделанную на master
; когда вы делаете новую фиксацию, метка обновляется, чтобы указать на новую фиксацию.
Хотя полезно думать о коммитах как о движении вперед во времени; на самом деле Git фиксирует точки друг относительно друга. Каждый коммит имеет ссылку на последний коммит, и эта цепочка используется для построения состояния репозитория.
Однако, если вы создадите новую ветку, все будет работать немного по-другому. Любая ветка, которую вы извлекли (с помощью git checkout
), будет использоваться в качестве метки для новой фиксации.
Чтобы создать ветку в этом примере, вы должны сначала убедиться, что для вашего репозитория HEAD задана ветка master
. Это потому, что вы можете создавать ветки, начиная откуда угодно, включая прошлые коммиты или коммиты в других ветках.
git checkout master
Затем создайте новую ветку и переключитесь на нее:
git branch feature git checkout feature
На данный момент в вашем репозитории ничего не изменилось. Метки веток feature
и master
указывают на одну и ту же фиксацию.
Однако все, что вы зафиксируете с этого момента, будет добавлено в ветку feature
. В частности, будет создана новая фиксация, настроенная так, чтобы она указывала на текущую фиксацию, а метка «функция» будет обновлена, чтобы указывать на эту новую фиксацию.
Вы даже можете checkout master
и сделать больше коммитов в основной ветке. Это не повлияет на ветку feature
, потому что все, что известно ярлыку, это то, что он указывает на конкретный коммит. Он не будет обновлен ярлыком master
.
Слияние и перебазирование
Конечно, ветки не были бы слишком полезными, если бы они застряли там навсегда, поэтому Git предоставляет инструменты для их объединения обратно в ветку master
. Технически вы можете объединять подветви с любой другой веткой, если истории совместимы.
Самый простой случай, когда у вас есть простая ветка, которую просто нужно объединить обратно. Вы можете проверить ветку master
, а затем запустить git merge feature
, чтобы «воспроизвести» все коммиты, сделанные в ветке feature, на master.
Это включает их в основную временную шкалу и создает новую «коммит слияния» с изменениями.
Однако это не всегда так просто, и во многих случаях возникают конфликты слияния, которые необходимо разрешить. Это может включать ветки, изменяющие одни и те же строки в файлах, перемещение или удаление файлов или другие виды ошибок, возникающие при изменении программного обеспечения с момента создания ветки feature
.
Если у вас есть давно работающая ветка feature
, одним из способов минимизировать эту проблему является выполнение частых слияний, на этот раз в обратном порядке — из master
в feature
. Это поддерживает feature
в актуальном состоянии и, хотя на самом деле не снижает требуемой рабочей нагрузки, предотвращает ее накопление в огромный беспорядок.
Эта стратегия распространена для долгоживущих веток и обычно считается лучшей практикой для Git.
Другим инструментом, который также используется в этом сценарии, является перебазирование. По сути, перебазирование похоже на выбор всей ветки и ее перемещение в начало из нового местоположения, часто это последняя фиксация в репозитории. В некоторых случаях это приводит к более чистой истории Git и является предпочтительным решением для некоторых сложных ситуаций.
Однако история Git «неизменяема», и из-за этого перебазирование копий коммитов вместо фактического их перемещения. Это может привести к множеству проблем в общих ветках, если они не будут должным образом скоординированы с вашей командой — если вы перебазируете, а ваш коллега сделает новую фиксацию в «старой», теперь удаленной функциональной ветке, она останется заблокированной. Им придется спрятать коммит и поместить его в новую ветку, чтобы согласовать изменения.
Как вы используете ветки?
Чтобы начать создавать новую ветку, вам нужно привести репозиторий в нужное состояние, чтобы метка новой ветки начиналась там, где вы хотите. Если вы отклоняетесь от master
, просто извлеките всю ветку, чтобы начать с последней фиксации. В противном случае вы можете перевести репозиторий в отсоединенное состояние HEAD, проверив отдельный коммит.
git checkout master git checkout aa3e570923b8ee61414cec17d9033faab4f084a6
Затем вы можете создать новую ветку и переключиться на нее с помощью проверки:
git branch feature git checkout feature
Это можно сделать одной командой с флагом -b
для оформления заказа:
git checkout -b feature
На этом этапе любые коммиты, сделанные в вашем репо, будут сделаны в новой ветке.
Если вам нужно снова поменять местами ветки, просто запустите git checkout master
, чтобы вернуться к нормальному состоянию.
Если у вас есть локальные изменения, которые нужно переместить, вы можете поместить их в git stash
. Изменения будут сохранены и могут быть повторно применены после замены веток.
git stash git checkout feature git stash apply