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

: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.