Изменить, 24 ноября 2016 года: этот ответ, по-видимому, популярен, поэтому я добавляю здесь примечание. Если вы замените тег на центральном сервере, любой, у кого есть старый тег - любой клон этого репозитория центрального сервера, который уже имеет этот тег, - может сохранить свой старый тег . Итак, хотя здесь рассказывается, как это сделать, будьте уверены, что вы хотите это сделать. Вам нужно будет убедить всех, у кого уже есть «неправильный» тег, удалить свой «неправильный тег» и заменить его новым «правильным тегом».
Тестирование в Git 2.10 / 2.11 показывает, что сохранение старого тега является поведением по умолчанию для работающих клиентов git fetch
, а обновление - поведением по умолчанию для работающих клиентов git fetch --tags
.
(Исходный ответ следует.)
Когда вы запрашиваете push-теги, git push --tags
отправляет (вместе с любыми коммитами и другими необходимыми объектами, а также любыми другими обновлениями ref из настроек push) удаленному устройству запрос на обновление формы . (Ну, он отправляет сколько угодно: по одному для каждого тега.)new-sha1 refs/tags/name
Запрос на обновление модифицируется удаленным устройством для добавления old-sha1
(или, опять же, по одному для каждого тега), затем доставляется на обработчики предварительного приема и / или обновления (в зависимости от того, какие перехватчики существуют на удаленном устройстве). Эти хуки могут решить, разрешить или отклонить создание / удаление / обновление тега.
old-sha1
Значение является все-нули «нуль» SHA-1 , если тег создается. Это new-sha1
пустой SHA-1, если тег удаляется. В противном случае оба значения SHA-1 являются действительными допустимыми значениями.
Даже без перехватчиков есть своего рода «встроенный перехватчик», который также запускается: пульт откажется перемещать тег, если вы не используете флаг «принудительно» (хотя «встроенный перехватчик» всегда подходит для обоих «добавить» и «удалить»). Сообщение об отказе, которое вы видите, исходит от этого встроенного крючка. (Между прочим, тот же самый встроенный обработчик также отклоняет обновления веток, которые не являются ускоренными.) 1
Но - вот один из ключей к пониманию того, что происходит - этот git push
шаг не знает, есть ли на пульте этот тег сейчас, и если да, то какое значение SHA-1 у него есть. Там только сказано: «вот мой полный список тегов с их значениями SHA-1». Пульт дистанционного управления сравнивает значения и, если есть дополнения и / или изменения, запускает их. (Для одинаковых тегов он вообще ничего не делает. Для тегов, которых у вас нет, он также ничего не делает!)
Если вы удалите тег локально, push
ваш push просто не передаст тег. Пульт ДУ предполагает, что никаких изменений вносить не следует.
Если вы удаляете тег локально, а затем создаете его, указывая на новое место, тогда push
ваш push передает тег, а удаленный видит это как изменение тега и отклоняет изменение, если только это не принудительное нажатие.
Таким образом, у вас есть два варианта:
- сделать силовой толчок, или
- удалить метку на пульте.
Последнее является возможным через git push
2 , даже если удалить тег локально и push
ING не имеет никакого эффекта. Предположим, что имя пульта дистанционного управления origin
и тег, который вы хотите удалить, следующий dev
:
git push origin :refs/tags/dev
Это попросит пульт удалить тег. Наличие или отсутствие тега dev
в вашем локальном репозитории не имеет значения; этот вид push
, с refspec, представляет собой принудительное удаление.:remoteref
Пульт дистанционного управления может разрешать или не разрешать удаление тегов (в зависимости от добавленных дополнительных хуков). Если он разрешает удаление, тогда тег исчезнет, а во-вторых git push --tags
, когда у вас есть локальный dev
тег, указывающий на какой-то фиксированный или аннотированный объект репо тега, отправьте новый dev
тег. На пульте dev
теперь будет вновь созданный тег, поэтому пульт, вероятно, разрешит push (опять же, это зависит от любых добавленных дополнительных хуков).
Force-push проще. Если вы хотите быть уверены , что не обновление ничего другого кроме тега, просто скажите , git push
чтобы нажать только , что один refspec:
git push --force origin refs/tags/dev:refs/tags/dev
(примечание: вам не нужно, --tags
если вы явно нажимаете только один тег ref-spec).
1 Конечно, причина для этого встроенный в крюк, чтобы помочь в обеспечении поведения , что другие пользователи в том же удаленного репо ожидается , что ветви не перемотать, а метки не двигаются. Если вы нажимаете принудительно, вы должны сообщить другим пользователям, что вы делаете это, чтобы они могли исправить это. Обратите внимание, что «теги вообще не перемещаются» введено в действие Git 1.8.2; предыдущие версии позволяли тегу «двигаться вперед» в графе фиксации, как и имена веток. См. Примечания к выпуску git 1.8.2 .
2 Это тривиально, если вы можете войти в систему с пульта. Просто зайдите в репозиторий Git и запустите git tag -d dev
. Обратите внимание, что в любом случае - удаление тега на пульте дистанционного управления или использование его git push
для его удаления - есть период времени, когда любой, кто обращается к пульту дистанционного управления, обнаружит, что dev
тег отсутствует. (У них по-прежнему будет свой старый тег, если он у них уже есть, и они могут даже подтолкнуть свой старый тег обратно, прежде чем вы сможете отправить новый.)