(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 com refs/heads/
nomes de uma ramificação; uma sequência começando com refs/remotes/
nomes de uma ramificação de rastreamento remoto; e uma sequência iniciando com refs/tags/
nomes de uma tag. O nome refs/stash
é a referência de stash (conforme usado por git 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
, e CHERRY_PICK_HEAD
, em particular, são também nomes que podem se referem a commits específicas (embora HEAD
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 seguinte refs/
. Por exemplo, você pode omitir refs/heads/
ou refs/tags/
ao se referir a uma filial ou tag local - e, de fato, deve omitir refs/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
e push
operações. Você também pode usar git ls-remote
ou git remote show
vê-los, mas fetch
e push
são os pontos de contato mais interessantes.
Refspecs
Durante fetch
e push
, 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 aqui fetch
, 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 dentro refs/heads/
e tudo dentro refs/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
:
$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/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 para refs/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 remoto origin
. O nome da filial se torna o nome da filial de rastreamento remoto, com o nome do controle remoto, nesse caso origin
, 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 adicionar refs/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 diz Edit, 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 tag xyzzy
, 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 tag xyzzy
, se você tiver uma, será substituída pela de origin
. 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) algumas git 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, e refs/heads/
e refs/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 tag xyzzy
e uma ramificação xyzzy
, e elas apontarem para confirmações diferentes, então:
git rev-parse xyzzy
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
ou refs/tags/xyzzy
. (Note que este faz o trabalho com git 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ção xyzzy
mesmo que a tag xyzzy
exista. Se você quiser fazer check-out da tag, poderá usá-la refs/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.
git checkout A
. o que éA
? Como você criouA
?