Como você exclui uma tag Git que já foi enviada por push?
Como você exclui uma tag Git que já foi enviada por push?
Respostas:
Você só precisa enviar uma referência 'vazia' ao nome do tag remoto:
git push origin :tagname
Ou, mais expressivamente, use a --delete
opção (ou -d
se 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
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.
git push --delete origin tag1 tag2
. Mesmo é válido para as tags eliminação locaisgit tag -d tag1 tag2
tag
está anexado a um único commit. Por esse motivo, o nome do ramo é irrelevante.
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.
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
git push --delete origin "TAGNAME"
:, onde TAGNAME é o nome da tag original.
tag
antes do nome da tag para garantir a obtenção da tag, não da ramificação.
refs/tags/
, como este: refs/tags/v2.3.1
.
Se você tiver um tag remoto v0.1.0
para 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.
fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1
...?
:tagname
deve funcionar para a exclusão remota.
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
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
git push --delete origin TAGNAME && git tag -d TAGNAME
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.
git tag -d your_tag_name
git push origin :refs/tags/your_tag_name
your_tag_name
do repositório local .your_tag_name
do repositório remoto .git tag -d 12345
git push origin :refs/tags/12345
git push --delete origin tagName
git tag -d tagName
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>'
Depois de ler essas respostas e precisar excluir mais de 11.000 tags, aprendi esses métodos dependendo ou xargs
demorando muito, a menos que você tenha horas para gravar.
Lutando, encontrei duas maneiras muito mais rápidas. Para ambos, comece com git tag
ou git ls-remote --tags
faça uma lista de tags que deseja excluir no controle remoto. Nos exemplos abaixo, você pode omitir ou substituir sorting_proccessing_etc
por qualquer grep
ing, sort
ing, tail
ing ou head
ing que desejar ( por exemplo, grep -P "my_regex" | sort | head -n -200
etc ):
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 push
dessa 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
).
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 xargs
e 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 " ")
Se você usar o SourceTree - uma ótima interface gráfica do Git -, poderá fazer isso facilmente sem a linha de comando, fazendo o seguinte:
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.
Se você criou uma tag chamada release01
em um repositório Git, você a remove do seu repositório, fazendo o seguinte:
git tag -d release01
git push origin :refs/tags/release01
Para remover um de um repositório Mercurial:
hg tag --remove featurefoo
Consulte https://confluence.atlassian.com/pages/viewpage.action?pageId=282175551
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 $_ }
Como o @CubanX sugeriu, eu dividi esta resposta do meu original:
xargs
e 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\"`
parallel
possui 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 2
parâ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 xargs
e git tag -d
, o que é suficiente.
git tag | sorting_processing_etc | xargs -L 1 git tag -d
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.
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
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:
$> git-tag-purge.sh tag_name)
Parece muito trabalho para algo que xargs
já faz. Olhando para trás neste tópico, acho que a lentidão xargs
que você experimentou é porque a resposta original foi usada xargs -n 1
quando realmente não era necessária.
Isso é equivalente ao seu método 1, exceto que xargs
lida automaticamente com o comprimento máximo da linha de comando:
git tag | sorting_processing_etc | xargs git push --delete origin
xargs
també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.
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.
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
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)