Ответ 1
Как работают теги
В git каждый тег называется "указывать на" (один, единственный) фиксатор. Фактически, то же самое относится к ветке: имя ветки также просто указывает на одно коммит.
Что делает эта работа двух вещей:
- каждая фиксация также указывает на другую фиксацию (или, возможно, несколько), и
- для ветвей (и только для ветвей), фиксация, на которую ветвь указывает "движется вперед" автоматически. То есть, когда вы добавляете новые коммиты - в некотором смысле, что в основном все git: добавляет новые коммиты в свой коллектив, вроде как Borg из старой серии Star Trek TNG - независимо от того, в какой ветке вы находитесь, что ветвь, которая получает повторную настройку, чтобы указать на новую фиксацию.
Таким образом, основное различие между веткой и тегом заключается в том, что тег не перемещается.
Чтобы узнать, как это работает, рассмотрите простой репозиторий git с тремя коммитами. Пусть эти метки обозначают A
, B
и C
. Первая фиксация (A
) указывает на ничего, поскольку первая фиксация и ветвь master
указывают на A
:
A <-- master
Когда вы совершаете вторую фиксацию, git создает B
, обращаясь к A
, и продвигает имя ветки, чтобы указать на B
:
A <- B <-- master
Затем, когда вы делаете третий фиксатор, git снова заставляет его указывать на свой родительский коммит и продвигает ветвь:
A <- B <- C <-- master
Если вы создадите тег, этот тег по умолчанию укажет на commit C
:
A <- B <- C <-- master
\- sometag
Если вы затем создаете новый фиксатор D
, git продвигает ветвь, но не тег:
A <- B <- C <- D <-- master
\
`--------- sometag
Вы можете в любое время создать или удалить любой тег, указывающий на какое-либо конкретное сообщение:
$ git tag -d sometag
удалит тег sometag
, после чего:
$ git tag sometag master~2
добавит sometag
, указывающий на commit B
. 1
(Мы только что доказали, что тег может двигаться. Реальная разница в том, что теги не должны двигаться, а ветки - и git не будет автоматически перемещать теги. 2 Предполагается, что ветки перемещаются в направлении "вперед", т.е. Если master
используется для указания на фиксацию C
и теперь указывает на фиксацию D
, commit C
обычно должен быть найден, начиная с D
и работа в обратном направлении. Каждый раз, когда вы перемещаете ветвь так, чтобы это правило нарушалось, вы "переписываете историю", смотрите другие статьи, когда это нормально, и когда это вызывает у людей проблемы.)
Нажатие тегов
Когда вы используете git push
, то, что вы действительно делаете, инструктирует какой-то другой репозиторий git принимать какие-либо новые коммиты, которые у вас есть, а они задают некоторые имена (-а) - обычно ветки и/или теги - чтобы указать на некоторые коммиты (по одному в каждом) в результирующем наборе. 3 Эти имена (ветки, теги и т.д.) в целом называются "ссылками", но позволяют просто использовать "ветвь" и "tag" на данный момент.
Аргумент after git push
называет репозиторий (обычно с помощью имени "remote", например origin
) для push-to. Если вы оставите это, git попытается определить один из них, но если вы хотите добавить название ветки или тега, вам нужно включить его явно, так как первое слово здесь считается удаленным именем. (То есть git push master
пытается использовать master
как имя удаленного, а не имя ветки.)
Чтобы вывести все ваши теги, вы можете просто добавить --tags
в команду git push
:
git push --tags origin
Чтобы нажать конкретный тег, вы можете его назвать:
git push origin sometag
так же, как вы можете нажать конкретную ветвь:
git push origin master
(На самом деле, этот четвертый аргумент представляет собой пару имен, таких как master:master
или sometag:sometag
, но по умолчанию он использует одно и то же имя с обеих сторон в большинстве случаев. 4)
Вы можете оставить имя origin
, если вам не нужно, чтобы все аргументы, например, git push --tags
совпадали с git push --tags origin
(при условии, что все ваши нажатия идут на origin
, в любом случае).
Совмещение
Чтобы установить тег на пульте дистанционного управления, сначала установите его локально, git tag name commit-identifier
. Используйте любой зритель, который вам нравится, чтобы убедиться, что он установлен правильно. Затем нажмите его, либо git push origin name
, либо git push --tags
.
1 Синтаксис master~2
инструктирует git начать с фиксации, найденной с помощью master
, затем выполнить резервное копирование на два шага. Вместо этого вы можете написать raw SHA-1 для фиксации B
здесь.
2 Старые версии git (pre 1.8.4) случайно применяли правила ветвления к тэгам при нажатии (на удаленной стороне, т.е. они позволяют тегу перемещаться, если он был "быстрым" вперед ").
3 В некоторых случаях вы можете указать имя на "аннотированный тег", и ничто не мешает имени указывать на объект "tree" или "blob", но это не так нормальная настройка.
4Фактически, dst refspec по умолчанию для ветки сложный: это зависит от вашей конфигурации push.default
и есть ли параметр remote.repository.push
, а также настроен ли восходящий поток и т.д. Для тегов правила проще, поскольку нет такой вещи, как "восходящий поток".