Как удалить удаленный тег?


Ответы:


5758

Вам просто нужно нажать «пустую» ссылку на имя удаленного тега:

git push origin :tagname

Или, более выразительно, используйте --deleteопцию (или -dесли ваша версия git старше 1.8.0):

git push --delete origin tagname

Обратите внимание, что в git есть пространство имен тегов и пространство имен веток, поэтому вы можете использовать одно и то же имя для ветви и для тега. Если вы хотите убедиться, что вы не можете случайно удалить ветку вместо тега, вы можете указать полный ref, который никогда не удалит ветку:

git push origin :refs/tags/tagname

Если вам также необходимо удалить локальный тег, используйте:

git tag --delete tagname

Фон

Передача ветки, тега или другого ссылки в удаленный репозиторий включает в себя указание «какой репозиторий, какой источник, какой пункт назначения?»

git push remote-repo source-ref:destination-ref

Пример реального мира, где вы помещаете свою основную ветвь в основную ветку источника:

git push origin refs/heads/master:refs/heads/master

Который из-за путей по умолчанию может быть сокращен до:

git push origin master:master

Теги работают одинаково:

git push origin refs/tags/release-1.0:refs/tags/release-1.0

Который также может быть сокращен до:

git push origin release-1.0:release-1.0

Опуская исходную ссылку (часть перед двоеточием), вы помещаете 'ничто' в место назначения, удаляя ссылку на удаленном конце.


187
+1 и за ответ на вопрос, и за объяснение общего случая, и за подробное описание значения неограниченного синтаксиса
Peter Host

77
И на всякий случай, если кто-то задается вопросом, как удалить несколько тегов одновременно, вы просто перечислите их, используя пробел, например git push --delete origin tag1 tag2. То же самое относится и к удалению локальных теговgit tag -d tag1 tag2
dVaffection

8
Если имя тега совпадает с именем ветви, вы можете удалить свою ветку. Ха-ха. Смотрите второй ответ - это более экологично
Зуба

1
@EmmaHe A tagпривязан только к одному коммиту . Из-за этого название ветви не имеет значения.
CB2

1
Также интересно знать, что git tag -d `git tag`будут удалены все локальные теги. То же самое относится к git push --delete origin `git tag`предположению, что вы извлекли удаленные теги локально. Это было удобно в тестовой среде.
DarkFranX

383

Более простой способ

git push --delete origin YOUR_TAG_NAME

Синтаксис двоеточия с префиксом IMO в этой ситуации немного странный


4
Я думаю, что это правильный путь ... другой синтаксис для меня больше похож на хаки.
Луиджи Р. Виджано

11
Да, это просто и работает. Хотя я бы уточнил ответ, указав переменную часть:, git push --delete origin "TAGNAME"где TAGNAME - это имя исходного тега.
Теему Лейсти

12
Это работает. Одно дополнение: если у вас есть ветвь и тег с одинаковым именем, вы можете поместить слово tagперед именем тега, чтобы убедиться, что вы получите тег, а не ветвь.
Andypaxo

9
@andypaxo Что команда занимает refspecs, правильный путь будет предваряя тег с refs/tags/, как это: refs/tags/v2.3.1.
p3lim

Я каким-то образом создал «плохое» имя тега на удаленном сервере, в котором были специальные символы, поэтому я не могу синхронизироваться с ним, поэтому просто удалил его с вашим предложением: git push --delete origin "service - <default> - 151 ", не может удалить его не с intellij, не с тайником, не с sourceTree. Спасибо !
Дмитрий Алгазин

215

Если у вас есть удаленный тег v0.1.0для удаления, а ваш удаленный есть origin, то просто:

git push origin :refs/tags/v0.1.0

Если вам также нужно удалить тег локально:

git tag -d v0.1.0

См. Ответ Адама Франко для объяснения необычного :синтаксиса Git для удаления.


2
это также работает с jgit. сокращение: tag не работает с jgit
rynop

Я получил fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1...?
Хаим Элия

3
@ChaimEliyah у тебя ведущий слэш, может быть, это твоя проблема
Джоффри

5
Лучший ответ, так как это также работает, если у вас есть ветвь и тег, который называется одинаково.
Эрик А. Брандштадмоен

Просто :tagnameдолжно работать для удаленного удаления.
Acumenus

106

Удалите все локальные теги и получите список удаленных тегов :

git tag -l | xargs git tag -d
git fetch

Удалить все удаленные теги

git tag -l | xargs -n 1 git push --delete origin

Очистить локальные теги

git tag -l | xargs git tag -d

2
Как удалить все теги из локальных и удаленных репо. Это то, что я искал, спасибо!
Хорхе Орпинель

git fetch, удалить удаленный, а затем очистить местных жителей, работал красиво!
ДиегоРБакеро

медленный, но самый простой
Lucent Fox

34

Чтобы удалить тег из удаленного хранилища:

git push --delete origin TAGNAME

Вы также можете удалить тег локально:

git tag -d TAGNAME

так что одна строка, чтобы сделать оба:git push --delete origin TAGNAME && git tag -d TAGNAME
sakurashinken

25

Из вашего терминала сделайте это:

git fetch
git tags
git tag -d {tag-name}
git push origin :refs/tags/{tag-name}

Теперь зайдите на Github.com и обновите, они исчезают.


3
git tag не теги
DSF

23
git tag -d your_tag_name
git push origin :refs/tags/your_tag_name
  1. Первая строка, удаляет your_tag_nameиз локального репо.
  2. Вторая строка, удаляет your_tag_nameиз удаленного репо.
  3. Нажмите кнопку « Сбросить черновик» в разделе « GitHub Releases ».

введите описание изображения здесь


2
Хотя эта команда может ответить на вопрос, предоставление дополнительного контекста относительно того, почему и / или как этот код отвечает на вопрос, повышает его долгосрочную ценность. Как ответить
Popo

20

Удалить локальный тег '12345'

git tag -d 12345

Удалить удаленный тег «12345» (например, версия GitHub тоже)

git push origin :refs/tags/12345

альтернативный подход

git push --delete origin tagName
git tag -d tagName

введите описание изображения здесь


15

Просто обратите внимание, что если у вас есть удаленная ветвь с именем удаленного тега, эти команды неоднозначны:

git push origin :tagname
git push --delete origin tagname

Поэтому вы должны использовать эту команду для удаления тега:

git push origin :refs/tags/<tag>

и этот, чтобы удалить ветку:

git push origin :refs/heads/<branch>

Если нет, вы получите сообщение об ошибке:

error: dst refspec <tagname> matches more than one.
error: failed to push some refs to '<repo>'

Коротко и кратко. Этот пост вместе с MeganZhou выскочил как ответ на то, почему у нас возникли проблемы, фирменное имя и тэг были идентичны. Я удалил локальный тег и нажал на: refs / tags и все было хорошо.
rwheadon

12

В 100 раз более быстрый метод для тысяч удаленных тегов

После прочтения этих ответов, при необходимости удалить более 11 000 тегов, я выучил эти методы, полагаясь или xargsзанимая слишком много времени, если у вас нет часов для записи.

Изо всех сил я нашел два гораздо более быстрых способа. Для обоих начните с git tagили git ls-remote --tagsсоставьте список тегов, которые вы хотите удалить на пульте дистанционного управления. В примерах ниже вы можете опустить или заменить sorting_proccessing_etcлюбой grepING, sortING, tailИНГ или headИНГ вы хотите ( например , и grep -P "my_regex" | sort | head -n -200 т.д. ):


Этот первый метод на сегодняшний день является самым быстрым, может быть, в 20-100 раз быстрее, чем при использовании xargs, и работает одновременно с несколькими тысячами тегов за раз.

git push origin $(< git tag | sorting_processing_etc \
| sed -e 's/^/:/' | paste -sd " ") #note exclude "<" for zsh

Как это работает? Обычный список тегов, разделенных строками, преобразуется в одну строку разделенных пробелами тегов, каждый из которых начинается с символа :так. , ,

tag1   becomes
tag2   ======>  :tag1 :tag2 :tag3
tag3

Использование git pushс этим тегом формата ничего не помещает в каждую удаленную ссылку, стирая ее (нормальный формат для этого способа - local_ref_path:remote_ref_path).

Второй метод приведен в качестве отдельного ответа в другом месте на этой же странице


После обоих этих методов вы, вероятно, захотите удалить свои локальные теги. Это намного быстрее, поэтому мы можем вернуться к использованию xargsи git tag -d, что достаточно.

git tag | sorting_processing_etc | xargs -L 1 git tag -d

ИЛИ аналогично удаленному удалению:

git tag -d $(< git tag | sorting_processing_etc | paste -sd " ")

Вы должны разделить это на несколько разных ответов. Ответ с несколькими тегами в одной строке, без сомнения, является правильным ответом для массового удаления тегов. На самом деле немного трудно найти эту информацию где-либо еще. Даже зная, что я ищу, мне трудно найти его на странице справки git :) Так что слава вам, выделите это как правильный ответ и перенесите GitHub API в другое место. И, наконец, массовое удаление тегов локально работает с тегами, разделенными пробелом (избавьтесь от двоеточий)
CubanX

Спасибо за похвалу и предложения. Я разделю это. Я не понимаю ваш комментарий об удалении локальных тегов. Я не думаю, что мой последний командный фрагмент использует какие-либо двоеточия, но я на мобильном, так что, возможно, что-то упустил.
TonyH

Извините, я просто имел в виду, что то, что вы делаете для удаления удаленных тегов, работает с удалением локальных тегов, предоставляя весь список сразу. :) Просто вместо git push origin: tag1: tag2 и т. Д. Вы будете делать git tag --dedele tag1 tag2 tag3 таким образом, чтобы вы могли полностью очиститься. Опять же огромное спасибо!
CubanX

11

Если вы используете SourceTree - отличный графический интерфейс Git - вы можете легко сделать это без командной строки, выполнив следующие действия:

  1. Откройте свой репозиторий в SourceTree
  2. Выберите и разверните вкладку «Теги» слева
  3. Щелкните правой кнопкой мыши на теге, который вы хотите удалить
  4. Выберите "Удалить YOUR_TAG_NAME"
  5. В окне подтверждения выберите «Удалить тег из удаленного»

YOUR_TAG_NAME теперь будет удален из вашего локального хранилища и всех удаленных устройств - будь то GitHub, BitBucket или где-либо еще, что вы указали в качестве удаленного для этого хранилища.

Кроме того, если вы удалили тег локально, но не в удаленных источниках, и хотите удалить его везде, просто создайте новый тег с тем же именем и прикрепленный к тому же коммиту, что и источники. Затем повторите шаги выше, чтобы удалить везде.


Работает как шарм. Спасибо!
Native_Mobile_Arch_Dev

9

Если вы создали тег с именем release01в Git-репозитории, вы можете удалить его из своего репозитория, выполнив следующие действия:

git tag -d release01 
git push origin :refs/tags/release01 

Чтобы удалить один из репозитория Mercurial:

hg tag --remove featurefoo

Пожалуйста, обратитесь https://confluence.atlassian.com/pages/viewpage.action?pageId=282175551


7

Если вы используете PowerShell и хотите удалить несколько из них:

# Local tags:
git tag -l | foreach { git tag -d $_ }

# Remote tags:
git tag -l | foreach { git push --delete origin $_ }

Конечно, вы также можете отфильтровать их перед удалением:

git tag -l | Where-Object { $_ -like "build-*" } | foreach { git tag -d $_ }

Это был плавный и хороший пример регулярного выражения. Спасибо, сэр
Юнус

7

Как предложил @CubanX, я отделил этот ответ от моего оригинала:

Вот метод, который в несколько раз быстрее xargsи может масштабироваться гораздо больше при настройке. Он использует Github API , токен личного доступа и использует утилиту parallel.

git tag | sorting_processing_etc | parallel --jobs 2 curl -i -X DELETE \ 
https://api.github.com/repos/My_Account/my_repo/git/refs/tags/{} -H 
\"authorization: token GIT_OAUTH_OR_PERSONAL_KEY_HERE\"  \
-H \"cache-control: no-cache\"`

parallelимеет много режимов работы, но обычно распараллеливает любую команду, которую вы ей даете, позволяя вам устанавливать ограничения на количество процессов. Вы можете изменить --jobs 2параметр, чтобы разрешить более быструю работу, но у меня были проблемы с ограничениями скорости Github , которые в настоящее время составляют 5000 / час, но, похоже, также имеют недокументированное краткосрочное ограничение.


После этого вы, вероятно, захотите удалить свои локальные теги. Это намного быстрее, поэтому мы можем вернуться к использованиюxargs и git tag -d, что достаточно.

git tag | sorting_processing_etc | xargs -L 1 git tag -d

Это кажется намного сложнее, чем принятый ответ. В чем выгода?
TheStherSide

2
Если вам нужно удалить несколько тысяч тегов, то скорость будет в 10-100 раз быстрее
TonyH

Спасибо за разъяснения. ОП спросил об удалении одного тега. Я не мог представить, почему кто-то использует этот подход для одного тега. Возможно, этот ответ лучше для другого вопроса, связанного с удалением многих тегов
theUtherSide

Я не думаю, что это существует. Я мог бы создать это, чтобы ответить самому себе. Вы хотите думать, что это уместно?
TonyH

1
Я делаю! Я думаю, что это довольно распространенная практика, на самом деле.
TheStherSide

6

Другие ответы указывают, как это сделать, но вы должны помнить о последствиях, так как это удаленное хранилище.

Страница руководства по тегу git в разделе « Повторная маркировка » содержит хорошее объяснение того, как вежливо информировать других пользователей удаленного репо об изменениях. Они даже предоставляют удобный шаблон объявлений, чтобы сообщить, как другие должны получить ваши изменения.


6

Я хотел удалить все теги, кроме тех, которые соответствуют шаблону, чтобы я мог удалить все, кроме последних двух месяцев производственных тегов, вот что я использовал с большим успехом:

Удалить все удаленные теги и исключить выражение из удаления

git tag -l | grep -P '^(?!Production-2017-0[89])' | xargs -n 1 git push --delete origin

Удалить все локальные теги и исключить выражение из удаления

git tag -l | grep -P '^(?!Production-2017-0[89])' | xargs git tag -d

5

Простой скрипт для удаления данного тега из локального и исходного местоположений. С проверкой, если тег действительно существует.

if [ $(git tag -l "$1") ]; then
    git tag --delete  $1
    git push --delete origin $1

    echo done.
else
    echo tag named "$1" was not found
fi

Как пользоваться:

  • Создайте файл сценария оболочки (например, git-tag-purge.sh) и вставьте содержимое.
  • chmod ваш файл скрипта, чтобы сделать его исполняемым.
  • Сделайте сценарий глобально доступным
  • перейдите на ваш проект git
  • Сценарий вызова (например,
    $> git-tag-purge.sh tag_name
    )

4

Похоже, много работы для чего-то xargsуже делает. Оглядываясь назад в этой ветке, я предполагаю, что медлительность, с xargsкоторой вы столкнулись, заключается в том, что первоначальный ответ использовался xargs -n 1тогда, когда это действительно не нужно.

Это эквивалентно вашему методу 1, за исключением того, что он xargsавтоматически определяет максимальную длину командной строки:

git tag | sorting_processing_etc | xargs git push --delete origin

xargsтакже может запускать процессы параллельно. Способ 2 с xargs:

git tag | sorting_processing_etc | xargs -P 5 -n 100 git push --delete origin

Выше используется максимум 5 процессов для обработки максимум 100 аргументов в каждом процессе. Вы можете поэкспериментировать с аргументами, чтобы найти то, что лучше всего подходит для ваших нужд.


Интересно. Вы узнаете что-то новое о команде Unix каждый день. Мне нужно проверить мой вариант использования с этой альтернативой.
TonyH

4

Если у вас есть созданный тег, начинающийся с символа # , например #ST002, вы можете обнаружить, что вы не можете удалить его, используя обычные шаблоны. т.е.

git tag -d #STOO2

Не удалит тег, но обернет его в строковый литерал примерно так

git tag -d "#ST002" or git tag -d '#ST002'

Это удалит это. Надеясь, это поможет кому-то, кто совершил ошибку, используя # для написания имен тегов.


2

Вот локальный тестовый пример для локального тестирования, не связываясь с удаленным:

~/p $ mkdir gittest    
~/p/git $ cd gittest/
~/p/gittest $ git init
Initialized empty Git repository in /Users/local_user/p/gittest/.git/
 ~/p/gittest $ touch testfile.txt
 ~/p/gittest $ git add testfile.txt
 ~/p/gittest $ git commit -m "initial commit"
[master (root-commit) 912ce0e] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 testfile.txt
 ~/p/gittest $ git tag
 ~/p/gittest $ git tag -a testtag
 ~/p/gittest $ git tag
testtag
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
b0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag
 ~/p/gittest $ cd ..
 ~/p $ mkdir gitbare
 ~/p $ cd gitbare
 ~/p/gitbare $ git init --bare
Initialized empty Git repository in /Users/local_user/p/gitbare/
 ~/p/gitbare $ cd ..
 ~/p $ cd gittest/
 ~/p/gittest $ git remote add origin /Users/local_user/p/gitbare
 ~/p/gittest $ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 215 bytes | 215.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /Users/local_user/p/gitbare
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
 ~/p/gittest $ git push origin testtag
Counting objects: 1, done.
Writing objects: 100% (1/1), 163 bytes | 163.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To /Users/local_user/p/gitbare
 * [new tag]         testtag -> testtag
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master
b0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag
 ~/p/gittest $ git push -d origin testtag
To /Users/local_user/p/gitbare
 - [deleted]         testtag
 ~/p/gittest    git tag -d testtag
Deleted tag 'testtag' (was b0a6c15)
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master
 ~/p/gittest

1

Привет просто хотел поделиться псевдонимом, который я создал, который делает то же самое:

Добавьте следующее в ваш ~ / .gitconfig

[alias]
    delete-tag = "!f() { \
            echo 'deleting tag' $1 'from remote/origin ausing command: git push --delete origin tagName;'; \
            git push --delete origin $1; \
            echo 'deleting tag' $1 'from local using command: git tag -d tagName;'; \
            git tag -d $1; \
        }; f"

Использование выглядит так:

-->git delete-tag v1.0-DeleteMe
deleting tag v1.0-DeleteMe from remote/origin ausing command: git push --delete origin tagName;
To https://github.com/jsticha/pafs
 - [deleted]             v1.0-DeleteMe
deleting tag v1.0-DeleteMe from local using command: git tag -d tagName;
Deleted tag 'v1.0-DeleteMe' (was 300d3ef22)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.