Vamos começar explicando o que é uma tag no git
Uma tag é usada para rotular e marcar um commit específico no histórico.
Geralmente é usado para marcar pontos de liberação (por exemplo, v1.0, etc.).
Embora uma tag possa parecer semelhante a uma ramificação , ela não é alterada . Aponta diretamente para um commit específico na história.
Você não poderá fazer check-out das tags se elas não estiverem localmente no seu repositório; portanto, primeiro você deve fazer fetch
as tags no seu repositório local.
Primeiro, verifique se a tag existe localmente fazendo
# --all will fetch all the remotes.
# --tags will fetch all tags as well
$ git fetch --all --tags --prune
Em seguida, verifique a tag executando
$ git checkout tags/<tag_name> -b <branch_name>
Em vez de origin
usar o tags/
prefixo.
Neste exemplo, você tem 2 tags versão 1.0 e versão 1.1. Você pode vê-las com uma das seguintes opções:
$ git checkout A ...
$ git checkout version 1.0 ...
$ git checkout tags/version 1.0 ...
Todas as opções acima farão o mesmo, pois a tag é apenas um ponteiro para um determinado commit.
origem: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
Como ver a lista de todas as tags?
# list all tags
$ git tag
# list all tags with given pattern ex: v-
$ git tag --list 'v-*'
Como criar tags?
Existem 2 maneiras de criar uma tag:
# lightweight tag
$ git tag
# annotated tag
$ git tag -a
A diferença entre os dois é que, ao criar uma tag anotada, você pode adicionar metadados conforme o seu git commit:
nome, email, data, comentário e assinatura
Como excluir tags?
# delete any (local) given tag
$ git tag -d <tag name>
# Delete a tag from the server with push tags
$ git push --delete origin <tag name>
Como clonar uma tag específica?
Para capturar o conteúdo de uma determinada tag, você pode usar o checkout
comando Conforme explicado acima, as tags são como qualquer outro commit, portanto, podemos usar checkout
e, em vez de usar o SHA-1, basta substituí-lo pelo tag_name
Opção 1:
# Update the local git repo with the latest tags from all remotes
$ git fetch --all
# checkout the specific tag
$ git checkout tags/<tag> -b <branch>
Opção 2:
Usando o comando clone
Como o git suporta clone superficial adicionando o --branch
comando clone, podemos usar o nome da tag em vez do nome da ramificação. O Git sabe como "traduzir" o SHA-1 fornecido para o commit relevante
# Clone a specific tag name using git clone
$ git clone <url> --branch=<tag_name>
git clone --branch =
--branch
também pode pegar tags e desanexar o HEAD naquele commit no repositório resultante.
Como enviar tags?
git push --tags
Para enviar todas as tags por push:
# Push all tags
$ git push --tags
Usando o em refs/tags
vez de apenas especificar o <tagname>
.
Por quê? - É recomendado o uso, refs/tags
pois às vezes as tags podem ter o mesmo nome que seus branches e o simples git push pressiona o branch em vez da tag
Para enviar tags anotadas e cadeia de histórico atual, use:
git push --follow-tags
Esse sinalizador --follow-tags
envia as confirmações e somente as tags que são ambas:
- Tags anotadas (para que você possa pular tags de criação local / temporária)
- Tags acessíveis (um ancestral) da ramificação atual (localizada no histórico)
No Git 2.4, você pode configurá-lo usando a configuração
$ git config --global push.followTags true
Folha de dicas:
git checkout A
. o que éA
? Como você criouA
?A
é um hash comprometergit checkout tags/<tag_name> -b <branch_name>
requer o-b <branch_name>
.git checkout tags/<tag_name>
me deu uma cabeça desapegada. De acordo com este artigo sobre cabeça desanexada , você evita uma cabeça desanexada criando e excluindo temporariamente uma ramificação. Este é um fluxo de trabalho bastante estranho. Claramente, eu, como usuário do git, preciso me acostumar a criar e excluir ramos por diversão e lucro.(Essa resposta demorou um pouco para ser escrita, e a resposta do codeWizard está correta em objetivo e essência, mas não totalmente completa, portanto, postarei isso de qualquer maneira.)
Não existe uma "tag Git remota". Existem apenas "tags". Eu aponto tudo isso para não ser pedante, 1 mas porque há muita confusão sobre isso com usuários casuais do Git, e a documentação do Git não ajuda muito 2 para iniciantes. (Não está claro se a confusão ocorre por causa da documentação inadequada ou se a documentação ruim ocorre porque isso é inerentemente um tanto confuso, ou o quê.)
Não são "filiais remotas", mais propriamente chamados "-monitoramento remoto ramos", mas é importante notar que estas são realmente entidades locais. Porém, não há tags remotas (a menos que você as (re) invente). Existem apenas tags locais, então você precisa obtê-la localmente para usá-lo.
A forma geral de nomes para confirmações específicas - às quais o Git chama referências - é qualquer sequência iniciada
refs/
. Uma sequência que começa comrefs/heads/
nomes de uma ramificação; uma sequência começando comrefs/remotes/
nomes de uma ramificação de rastreamento remoto; e uma sequência iniciando comrefs/tags/
nomes de uma tag. O nomerefs/stash
é a referência de stash (conforme usado porgit stash
; observe a falta de uma barra final).Existem alguns nomes incomuns casos especiais que não começam com
refs/
:HEAD
,ORIG_HEAD
,MERGE_HEAD
, eCHERRY_PICK_HEAD
, em particular, são também nomes que podem se referem a commits específicas (emboraHEAD
normalmente contém o nome de uma sucursal, ou seja, contém ). Mas, em geral, as referências começam com .ref: refs/heads/branch
refs/
Uma coisa que o Git faz para tornar isso confuso é que ele permite que você omita
refs/
a palavra, e geralmente a palavra seguinterefs/
. Por exemplo, você pode omitirrefs/heads/
ourefs/tags/
ao se referir a uma filial ou tag local - e, de fato, deve omitirrefs/heads/
ao fazer check-out de uma filial local! Você pode fazer isso sempre que o resultado for inequívoco, ou - como acabamos de observar - quando precisar fazê-lo (por ).git checkout branch
É verdade que as referências existem não apenas no seu próprio repositório, mas também em repositórios remotos. No entanto, o Git fornece acesso às referências de um repositório remoto apenas em horários muito específicos: ou seja, durante
fetch
epush
operações. Você também pode usargit ls-remote
ougit remote show
vê-los, masfetch
epush
são os pontos de contato mais interessantes.Refspecs
Durante
fetch
epush
, o Git usa strings que chama refspecs para transferir referências entre o repositório local e remoto. Portanto, é nesses momentos, e via refspecs, que dois repositórios Git podem entrar em sincronia. Depois que seus nomes estiverem sincronizados, você poderá usar o mesmo nome que alguém com o controle remoto usa. Há alguma mágica especial aquifetch
, porém, e afeta os nomes das filiais e os tags.Você deve pensar
git fetch
em direcionar o seu Git para chamar (ou talvez mensagem de texto) outro Git - o "remoto" - e conversar com ele. No início desta conversa, o controle remoto lista todas as suas referências: tudo dentrorefs/heads/
e tudo dentrorefs/tags/
, juntamente com outras referências que ele possui. Seu Git varre esses e (com base na busca usual refspec) renomeia suas ramificações.Vamos dar uma olhada no refspec normal para o controle remoto chamado
origin
:Este refspec instrui o Git a usar todos os nomes correspondentes -
refs/heads/*
ou seja, todas as ramificações do controle remoto - e alterar seu nome pararefs/remotes/origin/*
, ou seja, manter a parte correspondente igual, alterando o nome da ramificação (refs/heads/
) para um nome de ramificação de rastreamento remoto (refs/remotes/
especificamente ,refs/remotes/origin/
).É através deste refspec que
origin
as ramificações se tornam suas ramificações de rastreamento remoto para controle remotoorigin
. O nome da filial se torna o nome da filial de rastreamento remoto, com o nome do controle remoto, nesse casoorigin
, incluído. O sinal de mais+
na frente do refspec define o sinalizador "force", ou seja, sua ramificação de rastreamento remoto será atualizada para corresponder ao nome da ramificação do controle remoto, independentemente do que for necessário para fazer a correspondência. (Sem isso+
, as atualizações de ramificação são limitadas a alterações de "avanço rápido" e as atualizações de tags são simplesmente ignoradas desde a versão 1.8.2 do Git, aproximadamente - antes disso, as mesmas regras de avanço rápido são aplicadas.Tag
Mas e as tags? Não há refspec para eles - pelo menos, não por padrão. Você pode definir um, caso em que a forma do refspec depende de você; ou você pode correr
git fetch --tags
. O uso--tags
tem o efeito de adicionarrefs/tags/*:refs/tags/*
ao refspec, ou seja, ele traz todas as tags (mas não atualiza sua tag se você já tiver uma tag com esse nome, independentemente do que a tag do controle remoto dizEdit, jan 2017: a partir do Git 2.10 , testing mostra que--tags
atualiza forçosamente suas tags a partir das tags do controle remoto, como se o refspec lesse+refs/tags/*:refs/tags/*
; isso pode ser uma diferença no comportamento de uma versão anterior do Git).Observe que não há renomeação aqui: se remote
origin
tiver tagxyzzy
, e você não tiver, e vocêgit fetch origin "refs/tags/*:refs/tags/*"
, você serárefs/tags/xyzzy
adicionado ao seu repositório (apontando para o mesmo commit que no remoto). Se você usar+refs/tags/*:refs/tags/*
, sua tagxyzzy
, se você tiver uma, será substituída pela deorigin
. Ou seja, o+
sinalizador de força em um refspec significa "substituir o valor da minha referência pelo valor que meu Git obtém do Git".Tags automagic durante a busca
Por motivos históricos, 3 se você não usar nem a
--tags
opção nem a--no-tags
opção,git fetch
executará uma ação especial. Lembre-se de que dissemos acima que o controle remoto exibe todas as referências ao Git local, independentemente de o Git local querer vê-las ou não. 4 Seu Git toma nota de todas as tags que vê neste momento.Então, quando começar a baixar qualquer objeto de confirmação necessário para lidar com o que estiver buscando, se um deles confirmar o mesmo ID de qualquer uma dessas tags, o git adicionará essa tag - ou essas tags, se várias tags tiverem esse ID - a seu repositório.Editar, Jan 2017: Teste mostra que o comportamento em Git 2.10 agora é: Se o seu Git fornece uma tag chamado T , e você não tem uma etiqueta com o nome T , e a cometer ID associada a T é um ancestral de um dos seus ramos que você
git fetch
está examinando, seu Git adiciona T às suas tags com ou sem--tags
. Adicionar--tags
faz com que o Git obtenha todas as suas tags e também force a atualização.Bottom line
Você pode ter que usar
git fetch --tags
para obter as tags. Se os nomes de suas marcas entrarem em conflito com os nomes de marcas existentes, você pode (dependendo da versão do Git) precisar excluir (ou renomear) algumasgit fetch --tags
delas e depois executá -las para obtê-las. Como as tags - diferentemente das ramificações remotas - não têm renomeação automática, os nomes das tags devem corresponder aos nomes das tags, e é por isso que você pode ter problemas com conflitos.Na maioria dos casos normais, no entanto, um simples
git fetch
fará o trabalho, trazendo suas confirmações e suas tags correspondentes, e como elas - quem quer que sejam - marcarão as confirmações no momento em que publicarem essas confirmações, você as acompanhará. Se você não criar suas próprias tags, nem misturar seu repositório e outros repositórios (por meio de vários controles remotos), também não terá colisões de nomes de tags, portanto não precisará se preocupar em excluir ou renomear tags para obtenha suas tags.Quando você precisar de nomes qualificados
Mencionei acima que você pode omitir
refs/
quase sempre, erefs/heads/
erefs/tags/
e assim por diante na maioria das vezes. Mas quando você não pode ?A (de qualquer maneira ou quase completa) resposta completa é a
gitrevisions
documentação . O Git resolverá um nome para um ID de confirmação usando a sequência de seis etapas fornecida no link. Curiosamente, as tags substituem as ramificações: se houver uma tagxyzzy
e uma ramificaçãoxyzzy
, e elas apontarem para confirmações diferentes, então:fornecerá o ID para o qual a tag aponta. No entanto - e é isso que está faltando
gitrevisions
-git checkout
prefere os nomes das ramificações,git checkout xyzzy
o colocará na ramificação, desconsiderando a tag.Em caso de ambiguidade, você quase sempre pode soletrar o nome ref usando seu nome completo,
refs/heads/xyzzy
ourefs/tags/xyzzy
. (Note que este faz o trabalho comgit checkout
, mas de uma forma talvez inesperada:git checkout refs/heads/xyzzy
provoca um checkout-HEAD destacada em vez de um check-out ramo É por isso que você só tem que nota isso.git checkout
Usará o nome curto como um nome de filial em primeiro lugar: é assim que você verifique a ramificaçãoxyzzy
mesmo que a tagxyzzy
exista. Se você quiser fazer check-out da tag, poderá usá-larefs/tags/xyzzy
.)Como o
gitrevisions
Git tentará (como notas) , você também pode simplesmente escrever para identificar o commit marcado . (Se alguém conseguiu escrever uma referência válida nomeada em , no entanto, isso será resolvido como . Mas normalmente apenas os vários nomes devem estar .)refs/name
tags/xyzzy
xyzzy
xyzzy
$GIT_DIR
$GIT_DIR/xyzzy
*HEAD
$GIT_DIR
1 Ok, ok, "não apenas para ser pedante". :-)
2 Alguns diriam "muito inútil", e eu tenderia a concordar, na verdade.
3 Basicamente,
git fetch
e todo o conceito de controles remotos e refspecs, foi um acréscimo tardio ao Git, ocorrendo na época do Git 1.5. Antes disso, havia apenas alguns casos especiais ad-hoc, e a busca de tags era um deles, por isso foi adquirido por meio de um código especial.4 Se ajudar, pense no Git remoto como um pisca - pisca , no significado da gíria.
fonte
git fetch
buscará apenas as tags do controle remoto, dado o--tags
argumento.--tags
,--no-tags
e o padrão é realmente muito complicado. O padrão é trazer as tags que você não possui e que estão nos commits que você está trazendo. (Veja a edição de janeiro de 2017). Mas também existem falhas aqui, e o Git moderno está com suas - tags / --no-tags manipulação de código revisado mais uma vez, o que provavelmente levará a casos de canto ainda mais especiais.Para fazer o checkout de uma tag git, você deve executar o seguinte comando
por exemplo, conforme mencionado abaixo.
Para buscar todas as tags, use o comando
fonte
Para obter o código de tag específico, tente criar uma nova ramificação, adicione o código de tag nele. Eu fiz isso por comando:
$git checkout -b newBranchName tagName
fonte