Como excluir uma tag remota?


3421

Como você exclui uma tag Git que já foi enviada por push?

Respostas:


5754

Você só precisa enviar uma referência 'vazia' ao nome do tag remoto:

git push origin :tagname

Ou, mais expressivamente, use a --deleteopção (ou -dse sua versão do git for anterior à 1.8.0):

git push --delete origin tagname

Observe que o git tem namespace de tag e namespace de ramificação, portanto você pode usar o mesmo nome para uma ramificação e uma tag. Se você quiser ter certeza de que não pode remover acidentalmente a ramificação em vez da tag, poderá especificar ref completo que nunca excluirá uma ramificação:

git push origin :refs/tags/tagname

Se você também precisar excluir a tag local, use:

git tag --delete tagname

fundo

Enviar uma ramificação, tag ou outra referência para um repositório remoto envolve especificar "qual repositório, qual fonte, qual destino?"

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

Um exemplo do mundo real em que você envia sua ramificação principal para a ramificação principal da origem é:

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

Que, devido aos caminhos padrão, pode ser reduzido para:

git push origin master:master

Tags funcionam da mesma maneira:

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

O que também pode ser reduzido para:

git push origin release-1.0:release-1.0

Ao omitir a ref da fonte (a parte antes dos dois pontos), você pressiona 'nada' para o destino, excluindo a ref na extremidade remota.


187
+1 para responder à pergunta e explicar o caso geral e detalhar o significado da sintaxe completa
— Peter Host

77
E, no caso de alguém se perguntar como excluir várias tags de uma vez, você simplesmente as lista usando espaço em branco, por exemplo git push --delete origin tag1 tag2. Mesmo é válido para as tags eliminação locaisgit tag -d tag1 tag2
— dVaffection

8
Se o nome da tag colidir com o nome de uma ramificação, você poderá excluir sua ramificação. Ha-ha. Veja a segunda resposta - é mais ecológico
— zuba 26/12/16

1
O @EmmaHe A tagestá anexado a um único commit. Por esse motivo, o nome do ramo é irrelevante.
— Cb2 21/09

1
Também é interessante saber que git tag -d `git tag`excluirá todas as tags locais. O mesmo se aplica ao git push --delete origin `git tag`assumir que você puxou as tags remotas localmente. Isso foi útil em um ambiente de teste.
— DarkFranX 31/07

383

Uma maneira mais direta é

git push --delete origin YOUR_TAG_NAME

A sintaxe do cólon com prefixo da IMO é um pouco estranha nessa situação


4
Eu acho que essa é a maneira correta ... outra sintaxe parece mais com hacks para mim.
— Luigi R. Viggiano

11
Sim, isso é simples e funciona. Embora eu esclareça a resposta especificando qual é a parte variável git push --delete origin "TAGNAME":, onde TAGNAME é o nome da tag original.
— Teemu Leisti

12
Isso funciona. Uma adição: se você tiver uma ramificação e uma tag com o mesmo nome, poderá colocar a palavra tagantes do nome da tag para garantir a obtenção da tag, não da ramificação.
— andypaxo

9
@andypaxo O que o comando toma é refspecs, a maneira correta seria prefixar as tags com refs/tags/, como este: refs/tags/v2.3.1.
— P3lim #

Eu tinha um nome de tag 'ruim' criado no servidor remoto de alguma forma, que tinha caracteres especiais, por isso não posso sincronizar com isso, então simplesmente o remova com sua sugestão: git push --delete origin "service-- <default> - 151 ", não é possível removê-lo nem com intellij, nem com stash, nem com sourceTree. Obrigado !
— Dmitri Algazin

215

Se você tiver um tag remoto v0.1.0para excluir e o seu controle remoto estiver origin, basta:

git push origin :refs/tags/v0.1.0

Se você também precisar excluir a tag localmente:

git tag -d v0.1.0

Veja a resposta de Adam Franco para uma explicação da :sintaxe incomum do Git para exclusão.


2
isso também funciona com o jgit. a tag: tag shorthand não funciona com jgit
— rynop 27/09/12

Eu tenho fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1...?
— Chaim Eliyah 13/09/16

3
@ChaimEliyah você tem uma barra inicial, talvez esse é o seu problema
— Joffrey

5
Melhor resposta, pois isso também funciona se você tiver uma ramificação e uma tag denominadas iguais.
— Erik A. Brandstadmoen

Só :tagnamedeve funcionar para a exclusão remota.
— Acumenus 5/02/19

106

Exclua todas as tags locais e obtenha a lista de tags remotas :

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

Remova todas as tags remotas

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

Limpar tags locais

git tag -l | xargs git tag -d

2
Como remover todas as tags dos repositórios locais e remotos. Isto é o que eu estava procurando, obrigado!
— Jorge Orpinel

git fetch, exclua o controle remoto e limpe os locais, funcionou lindamente!
— precisa saber é o seguinte

lento, mas o mais direto
— Lucent Fox

34

Para remover a marca do repositório remoto:

git push --delete origin TAGNAME

Você também pode excluir a tag localmente:

git tag -d TAGNAME

então uma linha para fazer as duas coisas:git push --delete origin TAGNAME && git tag -d TAGNAME
— sakurashinken

25

No seu terminal, faça o seguinte:

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

Agora vá ao Github.com e atualize, eles desaparecem.


3
git tag not tags
— DSF

23
git tag -d your_tag_name
git push origin :refs/tags/your_tag_name
  1. Primeira linha, exclui your_tag_namedo repositório local .
  2. Segunda linha, exclui your_tag_namedo repositório remoto .
  3. Pressione o botão Descartar rascunho na seção Versões do GitHub .

insira a descrição da imagem aqui


2
Embora esse comando possa responder à pergunta, fornecer um contexto adicional a respeito de por que e / ou como esse código responde à pergunta melhora seu valor a longo prazo. Como responder
— Popo

20

Excluir marca local '12345'

git tag -d 12345

Exclua a tag remota '12345' (por exemplo, versão do GitHub também)

git push origin :refs/tags/12345

Abordagem alternativa

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

insira a descrição da imagem aqui


15

Observe que, se você tiver uma ramificação remota nomeada como tag remota, esses comandos serão ambíguos:

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

Portanto, você deve usar este comando para excluir a tag:

git push origin :refs/tags/<tag>

e este para excluir o ramo:

git push origin :refs/heads/<branch>

Caso contrário, você receberá um erro como este:

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

Curto e conciso. Esta publicação, juntamente com a de MeganZhou, surgiu como a resposta para o motivo de estarmos tendo problemas, o nome da filial e o nome da tag eram idênticos. Eu apaguei a tag local e empurrei para: refs / tags e tudo estava bem.
— Rwheadon

12

Método até 100x mais rápido para milhares de tags remotas

Depois de ler essas respostas e precisar excluir mais de 11.000 tags, aprendi esses métodos dependendo ou xargsdemorando muito, a menos que você tenha horas para gravar.

Lutando, encontrei duas maneiras muito mais rápidas. Para ambos, comece com git tagou git ls-remote --tagsfaça uma lista de tags que deseja excluir no controle remoto. Nos exemplos abaixo, você pode omitir ou substituir sorting_proccessing_etcpor qualquer greping, sorting, tailing ou heading que desejar ( por exemplo, grep -P "my_regex" | sort | head -n -200 etc ):


Esse primeiro método é de longe o mais rápido, talvez 20 a 100 vezes mais rápido que o uso xargs, e funciona com pelo menos vários milhares de tags por vez.

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

Como é que isso funciona? A lista normal de tags separadas por linhas é convertida em uma única linha de tags separadas por espaço, cada uma delas anexada a ele :. . .

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

O uso git pushdessa tag de formato não empurra nada para cada referência remota, apagando-a (o formato normal para empurrar dessa maneira é local_ref_path:remote_ref_path).

O método dois é dividido como uma resposta separada em outro lugar nesta mesma página


Após os dois métodos, você provavelmente também desejará excluir suas tags locais. Isso é muito mais rápido, para que possamos voltar a usar xargse git tag -d, o que é suficiente.

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

OU semelhante à exclusão remota:

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

Você deve dividir isso em algumas respostas diferentes. A resposta com várias tags em uma linha é, sem dúvida, a resposta certa para a exclusão de tags em massa. Na verdade, é um pouco difícil encontrar essas informações em quase qualquer outro lugar. Mesmo sabendo o que estou procurando, é difícil encontrá-lo na página de ajuda do git :) Então, parabéns a você e destaque isso como a resposta certa e mova a API do GitHub para um lugar diferente. E, finalmente, as tags Apagar localmente, a granel, trabalha com etiquetas do espaço delimitado (se livrar dos dois pontos)
— CubanX

Obrigado pelos elogios e sugestões. Vou dividir isso. Não entendo seu comentário sobre a exclusão de tags locais. Eu não acho que meu snippet de comando final use dois pontos, mas estou no celular, talvez perdendo alguma coisa.
— TonyH

Desculpe, apenas quis dizer que o que você está fazendo para excluir tags remotas funciona com a exclusão de tags locais, fornecendo a lista inteira de uma só vez. :) Apenas em vez da origem do git push: tag1: tag2 etc., você faria o git tag --delete tag1 tag2 tag3 dessa maneira para ter uma limpeza total. Mais uma vez, muito obrigado!
— CubanX

11

Se você usar o SourceTree - uma ótima interface gráfica do Git -, poderá fazer isso facilmente sem a linha de comando, fazendo o seguinte:

  1. Abra seu repositório no SourceTree
  2. Selecione e expanda a guia "Tags" à esquerda
  3. Clique com o botão direito do mouse na tag que você deseja excluir
  4. Selecione "Excluir YOUR_TAG_NAME"
  5. Na janela de verificação, selecione "Remover etiqueta dos controles remotos"

YOUR_TAG_NAME agora será removido do seu repositório local e de todos os controles remotos - seja GitHub, BitBucket ou qualquer outro local que você listou como remoto para esse repositório.

Além disso, se você excluiu uma marca localmente, mas não nas origens remotas, e deseja excluí-la em todos os lugares, crie uma nova marca que tenha o mesmo nome e esteja anexada no mesmo commit das origens. Em seguida, repita as etapas acima para excluir todos os lugares.


Funciona como um encanto. Obrigado!
— Native_Mobile_Arch_Dev


7

Se você estiver usando o PowerShell e deseja excluir vários deles:

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

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

Obviamente, você também pode filtrá-los antes de excluir:

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

Esse foi um bom exemplo de regexp. Obrigado bom senhor
— Yunus

7

Como o @CubanX sugeriu, eu dividi esta resposta do meu original:

Aqui está um método que é várias vezes mais rápido do que xargse pode escalar muito mais com os ajustes. Ele usa a API do Github , um token de acesso pessoal e aproveita o utilitário 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\"`

parallelpossui muitos modos de operação, mas geralmente paralela qualquer comando que você der, permitindo definir limites para o número de processos. Você pode alterar o --jobs 2parâmetro para permitir uma operação mais rápida, mas tive problemas com os limites de taxa do Github , que atualmente são de 5000 / h, mas também parece ter um limite de curto prazo não documentado.


Depois disso, você provavelmente também desejará excluir suas tags locais. Isso é muito mais rápido, para que possamos voltar a usar xargse git tag -d, o que é suficiente.

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

Isso parece muito mais complicado que o answe aceito. Qual o benefício?
— theUtherSide 25/09

2
Se você precisar excluir vários milhares de etiquetas, então a velocidade é 10-100 vezes mais rápido
— TonyH

Obrigado por esclarecer. O OP perguntou sobre a exclusão de uma única tag. Eu não conseguia imaginar por que alguém usaria essa abordagem para uma única tag. Talvez esta resposta é melhor para uma outra questão envolvendo a exclusão de muitas tags
— theUtherSide

Eu acho que não existe. Eu poderia criá-lo para me responder. Você quer pensar que é apropriado?
— TonyH

1
Eu faço! Eu acho que é uma prática bastante comum aqui, na verdade.
— theUtherSide 26/09

6

As outras respostas apontam como fazer isso, mas você deve ter em mente as conseqüências, pois este é um repositório remoto.

A página man da tag git, na seção On Retagging , tem uma boa explicação de como informar educadamente os outros usuários do repo remoto sobre a mudança. Eles até fornecem um modelo de anúncio útil para comunicar como os outros devem receber suas alterações.


6

Eu queria remover todas as tags, exceto aquelas que correspondam a um padrão, para poder excluir todas as tags de produção, exceto os últimos dois meses, eis o que eu usei com grande sucesso:

Excluir todas as tags remotas e excluir expressões de excluir

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

Excluir todas as tags locais e excluir expressões de excluir

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

5

Script simples para remover a tag especificada dos locais local e de origem. Com uma verificação se a etiqueta realmente existe.

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

Como usar:

  • Crie um arquivo de script de shell (por exemplo, git-tag-purge.sh) e cole o conteúdo.
  • chmod seu arquivo de script para torná-lo executável.
  • Tornar o script disponível globalmente
  • cd para o seu projeto git
  • Script de chamada (por exemplo,
    $> git-tag-purge.sh tag_name
    )

4

Parece muito trabalho para algo que xargsjá faz. Olhando para trás neste tópico, acho que a lentidão xargsque você experimentou é porque a resposta original foi usada xargs -n 1quando realmente não era necessária.

Isso é equivalente ao seu método 1, exceto que xargslida automaticamente com o comprimento máximo da linha de comando:

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

xargstambém pode executar processos em paralelo. Método 2 com xargs:

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

O exemplo acima usa no máximo 5 processos para manipular no máximo 100 argumentos em cada processo. Você pode experimentar os argumentos para descobrir o que funciona melhor para suas necessidades.


Interessante. Você aprende algo novo sobre um comando Unix todos os dias. Vou precisar testar meu caso de uso com essa alternativa.
— TonyH

4

Se você criou uma tag iniciando com o caractere # , por exemplo #ST002, pode achar que não é possível excluir usando padrões normais. ie

git tag -d #STOO2

Não excluirá a tag, mas a envolverá em um String Literal como esse

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

Isso fará com que seja excluído. Espero que ajude alguém que cometeu o erro de usar # para escrever nomes de tags.


2

Aqui está um caso de teste local para testá-lo localmente sem mexer com um controle remoto:

~/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

Oi, só queria compartilhar um alias que eu criei que faz a mesma coisa:

Adicione o seguinte ao seu ~ / .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"

O uso é semelhante a:

-->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)
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.