Edit, 24 Nov 2016: esta resposta é aparentemente popular, por isso estou adicionando uma nota aqui. Se você substituir uma marca em um servidor central, qualquer pessoa que possua a marca antiga - qualquer clone do repositório do servidor central que já tenha a marca - poderá reter sua marca antiga . Portanto, embora isso lhe diga como fazê-lo, tenha certeza de que deseja fazê-lo. Você precisará solicitar a todos que já possuem a tag "errada" para excluir a "tag errada" e substituí-la pela nova "tag correta".
Testar no Git 2.10 / 2.11 mostra que manter a tag antiga é o comportamento padrão para clientes em execução git fetch, e atualizar é o comportamento padrão para clientes em execução git fetch --tags.
(A resposta original segue.)
Quando você pede para enviar tags por envio, git push --tagsenvia (juntamente com quaisquer confirmações e outros objetos necessários e quaisquer outras atualizações de referência das configurações de envio) para o remoto uma solicitação de atualização do formulário . (Bem, ele envia muitos: um desses para cada tag.)new-sha1 refs/tags/name
A solicitação de atualização é modificada pelo controle remoto para adicionar um old-sha1(ou novamente, um para cada tag) e depois entregue aos ganchos de pré-recebimento e / ou atualização (os ganchos existentes no controle remoto). Esses ganchos podem decidir se permitem ou rejeitam a tag create / delete / update.
O old-sha1valor é o SHA-1 "nulo" com todos os zeros se a tag estiver sendo criada. O new-sha1é o SHA-1 nulo se a tag estiver sendo excluída. Caso contrário, os dois valores SHA-1 são reais e válidos.
Mesmo sem ganchos, existe um tipo de "gancho embutido" que também é executado: o controle remoto se recusará a mover uma tag, a menos que você use o sinalizador "force" (embora o "gancho embutido" esteja sempre bem com os dois "adicionar" e "excluir"). A mensagem de rejeição que você vê é proveniente desse gancho embutido. (Aliás, esse mesmo gancho embutido também rejeita atualizações de ramificações que não são rápidas). 1
Mas - eis uma das chaves para entender o que está acontecendo - a git pushetapa não faz ideia se o controle remoto tem essa tag agora e, se sim, qual o valor do SHA-1. Diz apenas "aqui está minha lista completa de tags, junto com seus valores SHA-1". O controle remoto compara os valores e, se houver adições e / ou alterações, os ganchos serão executados. (Para tags iguais, não faz absolutamente nada. Para tags que você não possui, elas também não fazem nada!)
Se você excluir a tag localmente push, seu envio simplesmente não transferirá a tag. O controle remoto pressupõe que nenhuma alteração deve ser feita.
Se você excluir a tag localmente, crie-a apontando para um novo local, pushseu push transferirá a tag e o controle remoto verá isso como uma alteração de tag e rejeitará a alteração, a menos que seja um push forçado.
Assim, você tem duas opções:
- fazer um empurrão forçado, ou
- exclua a tag no controle remoto.
O último é possível via git push2, mesmo que a exclusão local da tag e o pushing não tenham efeito. Supondo que o nome do controle remoto seja origine a tag que você deseja excluir seja dev:
git push origin :refs/tags/dev
Isso pede ao controle remoto para excluir a tag. A presença ou ausência da tag devno seu repositório local é irrelevante; esse tipo de push, como refspec, é um push de exclusão pura.:remoteref
O controle remoto pode ou não permitir a exclusão de tags (dependendo dos ganchos extras adicionados). Se permitir a exclusão, a tag desaparecerá e, um segundo git push --tags, quando você tiver uma devtag local apontando para algum objeto de repo de tag de confirmação ou anotação, envie sua nova devtag. No controle remoto, devagora será uma tag recém-criada; portanto, o controle remoto provavelmente permitirá o envio (novamente isso depende de quaisquer ganchos extras adicionados).
O empurrão forçado é mais simples. Se você quiser ter certeza de não atualização qualquer outro do que a tag, basta dizer git pushpara empurrar apenas que uma refspec:
git push --force origin refs/tags/dev:refs/tags/dev
(observação: você não precisa --tagsse estiver pressionando explicitamente apenas uma tag ref-spec).
1 Obviamente, o motivo desse gancho interno é ajudar a reforçar o comportamento que outros usuários do mesmo repositório remoto esperam: que ramos não sejam rebobinados e que as tags não sejam movidas. Se você forçar, deve informar os outros usuários que você está fazendo isso, para que eles possam corrigi-lo. Observe que "as tags não se movem" são aplicadas recentemente pelo Git 1.8.2; versões anteriores permitiriam que a tag "avançasse" no gráfico de confirmação, como os nomes das ramificações. Veja as notas de lançamento do git 1.8.2 .
2 É trivial se você puder fazer login no controle remoto. Basta ir ao repositório Git lá e executar git tag -d dev. Observe que, de qualquer maneira - excluindo a tag no controle remoto ou usando-a git pushpara excluí-la -, há um período em que qualquer pessoa que acessa o controle remoto descobre que a devtag está ausente. (Eles continuarão a ter sua própria tag antiga, se já a tiverem, e podem até empurrar a tag antiga de volta antes que você possa empurrar a nova.)