Редагувати, 24 листопада 2016 року: ця відповідь, мабуть, популярна, тому я тут додаю примітку. Якщо ви заміните тег на центральному сервері, кожен, хто має старий тег - будь-який клон цього сховища центрального сервера, у якого вже є тег, може зберегти його старий тег . Тому, поки це говорить вам, як це зробити, будьте впевнені, що хочете це зробити. Ви повинні отримати всі , хто вже має «неправильний» тег , щоб видалити їх «неправильний тег» і замінити його на новий «правий тег».
Тестування в Git 2.10 / 2.11 показує, що збереження старого тегу - це поведінка за замовчуванням для клієнтів, що працюють git fetch
, а оновлення - це поведінка за замовчуванням для клієнтів, які працюють git fetch --tags
.
(Оригінальна відповідь випливає.)
Коли ви попросите натиснути теги, він git push --tags
надсилає (разом з будь-якими комісіями та іншими необхідними об'єктами та будь-якими іншими оновленнями оновлення з налаштувань 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
ваш натискання передає тег, а пульт дистанційного розгляду бачить це як зміну тегу та відхиляє зміну, якщо тільки це не є примусовим натисканням.
Таким чином, у вас є два варіанти:
- робити натиск, або
- видалити тег на пульті.
Останнє є можливим через git push
2 , навіть якщо видалити тег локально і push
ING не має ніякого ефекту. Припустимо, що ім'я віддаленого є origin
, і тег, який ви хочете, щоб його видалити, це dev
:
git push origin :refs/tags/dev
Це вимагає від пульта видалити тег. Наявність або відсутність тегу dev
у вашому локальному сховищі не має значення; такий тип push
, як респект, - це поштовх із чистою видаленням.:remoteref
Пульт може або не може дозволити видалення тегів (залежно від доданих додаткових гачків). Якщо це дозволить видалити, тег не буде втрачено, а по-друге git push --tags
, коли у вас є локальний dev
тег, який вказує на якийсь об'єкт репортажу чи анотованого тегу, відправте новий dev
тег. На пульті dev
тепер буде новостворений тег, тому віддалений, ймовірно, дозволить натиснути (знову це залежить від будь-яких додаткових доданих гаків).
Силовий натиск простіший. Якщо ви хочете бути впевнені , що не її поновлення нічого іншого крім тега, просто скажіть , 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
тег відсутній. (Вони будуть продовжувати мати свій власний старий тег, якщо вони вже є, і вони можуть навіть підштовхнути їх старий тег назад, перш ніж ви можете натиснути на новий.)