Por que devo me preocupar com tags leves e anotadas?

346

Eu mudei do Subversion para o Git como meu VCS diário no ano passado e ainda estou tentando entender os pontos mais delicados do "Git-think".

O que me incomoda ultimamente são as tags "leves" vs. anotadas vs. assinadas. Parece universalmente aceito que as tags anotadas são superiores às leves para todos os usos reais, mas as explicações que encontrei para o porquê desse caso sempre parecem se resumir a "porque as melhores práticas" ou "porque são diferentes" . Infelizmente, esses argumentos são muito insatisfatórios sem saber por que são as melhores práticas ou como essas diferenças são relevantes para o meu uso do Git.

Quando mudei para o Git, tags leves pareciam ser a melhor coisa desde pão fatiado; Eu poderia simplesmente apontar para um commit e dizer "that was 1.0". Estou tendo problemas para entender como uma tag pode precisar ser mais do que isso, mas certamente não posso acreditar que os especialistas do Git em todo o mundo prefiram tags anotadas arbitrariamente! Então, o que é toda essa confusão?

(Pontos de bônus: por que eu precisaria assinar uma tag?)

EDITAR

Estou convencido de que as tags anotadas são uma coisa boa - saber quem marcou e quando é importante! Como acompanhamento, algum conselho sobre boas anotações de tags? Ambos git tag -am "tagging 1.0" 1.0e tentar resumir o log de confirmação desde a tag anterior parecem perder estratégias.

Ben Blank
fonte
Você encontrou uma boa resposta para o seu acompanhamento? Algo como? git log --pretty=oneline master..HEAD | git tag -a -F - $BRANCH.$BUILD_NUMBER
dalore 16/05
Resumir o log de confirmação desde a tag anterior me parece uma excelente estratégia para as mensagens de tag.
ROOBY
FYI (1.) Para listar a tag LIGHTWEIGHT por data, clique aqui . (2.) Para listar a tag ANNOTATED por data, clique aqui .
Trevor Boyd Smith

Respostas:

272

A grande vantagem de uma tag anotada é que você sabe quem a criou. Assim como no commit, às vezes é bom saber quem fez isso. Se você é um desenvolvedor e vê que a v1.7.4 foi marcada (declarada pronta) e não tem tanta certeza, com quem você conversa? A pessoa cujo nome está na tag anotada! (Se você mora em um mundo desconfiado, isso também impede as pessoas de rotular coisas que não deveriam.) Se você é consumidor, esse nome é um selo de autoridade: Junio ​​Hamano diz que esta versão do git é liberado.

Os outros metadados também podem ser úteis - às vezes é bom saber quando essa versão foi lançada, não apenas quando a confirmação final foi feita. E às vezes a mensagem pode até ser útil. Talvez isso ajude a explicar o objetivo dessa tag específica. Talvez a tag para um candidato a lançamento contenha um pouco de uma lista de status / tarefas.

Assinar tags é praticamente como assinar qualquer outra coisa - fornece mais um nível de segurança para os paranóicos. A maioria de nós nunca vai usá-lo, mas se você realmente deseja verificar tudo antes de colocar o software no seu computador, pode querer.

Editar:

Quanto ao que escrever em uma anotação de tag, você está certo - nem sempre há muito a dizer. Para uma tag de número de versão, é implicitamente entendido que ela marca essa versão e, se você estiver satisfeito com os registros de alterações em outros lugares, não há necessidade de colocá-los lá. Nesse caso, é realmente o etiquetador e a data que são os mais importantes. A única outra coisa em que consigo pensar é em algum tipo de selo de aprovação de uma suíte de testes. Dê uma olhada nas tags do git.git: todas dizem algo como "Git 1.7.3 rc1"; tudo o que realmente importa é o nome de Junio ​​Hamano.

No entanto, para tags com nomes menos óbvios, a mensagem pode se tornar muito mais importante. Eu poderia imaginar marcar uma versão específica de finalidade específica para um único usuário / cliente, algum marco importante que não seja da versão ou (como mencionado acima) um candidato a lançamento com informações adicionais. A mensagem é então muito mais útil.

Cascabel
fonte
4
apenas para comparar com o SVN, uma vez que o OP é proveniente desse sistema: os metadados da tag anotada são equivalentes à alteração real do SVN e torna a ramificação da tag, que no SVN tem seu próprio autor e mensagem. E, potencialmente, restrições separadas sobre quem pode fazer uma marca, diferente de quem pode fazer o check-in, uma distinção que é irrelevante se você estiver apenas usando o sistema para suas próprias coisas.
Araqnid
10
Ah-ha! Parece que meu entendimento aqui foi prejudicado pelo fato de todos os meus projetos Git até agora terem sido solo. Eu nunca precisei saber a quem culpar por algo (sou sempre eu!), Por isso não havia notado que as etiquetas leves não rastreiam o etiquetador.
Ben Blank
5
git help logagora resume isso como: "Tags anotadas são destinadas a lançamento, enquanto tags leves são destinadas a rótulos de objetos particulares ou temporários".
Jon Gjengset
11
@javabrett Embora essa seja uma boa parte de uma resposta para "quais são as diferenças entre tags anotadas e leves", a pergunta aqui foi especificamente por que as pessoas desejam armazenar informações extras e, portanto, usar tags anotadas. (E acho que não posso dizer seriamente que "cria um blob" é uma desvantagem - você faz o que precisa para armazenar as informações que deseja armazenar e, se forem informações significativas, exigirá um blob. )
Cascabel
11
@ Chris sim, como a resposta diz: "A grande vantagem de uma tag anotada é que você sabe quem a criou". Você sempre pode tentar as coisas sozinho para descobrir:git tag -a -m 'my message' my-tag; git show my-tag
Cascabel
64

Minha opinião pessoal, ligeiramente diferente, sobre esse tópico:

  • Tags anotadas são aquelas que devem ser publicadas para outros desenvolvedores, provavelmente novas versões (que também devem ser assinadas). Não apenas para ver quem marcou e quando foi marcado, mas também o porquê (geralmente um registro de alterações).
  • Os leves são mais apropriados para uso privado, o que significa marcar confirmações especiais para poder encontrá-las novamente. Que seja para revê-los, verificá-los para testar alguma coisa ou qualquer outra coisa.
Koraktor
fonte
4
Isso também é mencionado no homem git-tag: "marcas anotadas são destinadas para a liberação enquanto marcas leves são destinadas para rótulos de objetos particulares ou temporários.": Stackoverflow.com/a/35059291/895245
Ciro Santilli郝海东冠状病六四事件法轮功
28

Por padrão, o Git olha apenas as tags anotadas como uma linha de base para comandos como git describe. Pense nas tags anotadas como sinalizações que têm um significado duradouro para si e para os outros, enquanto as tags leves são mais como marcadores para você encontrar mais tarde. Portanto, vale a pena usar tags anotadas como referência, enquanto tags leves não devem ser.

Assinar uma tag é uma garantia da identidade do assinante. Ele permite que os usuários verifiquem, por exemplo, que o código do kernel Linux que eles pegaram é o mesmo código que Linus Torvalds realmente lançou. A assinatura também pode ser uma afirmação de que o assinante está atestando a qualidade e a integridade do software naquele commit.

Phil Miller
fonte
11
git push --follow-tagsé outro comando que trata tanto de forma diferente: stackoverflow.com/a/26438076/895245
Ciro Santilli郝海东冠状病六四事件法轮功
11
Obrigado pela dica sobre git describe. Eu o uso no sistema de integração contínua e algumas vezes a string da versão não era o que eu esperaria.
Jjmontes
9

Assinar uma tag é uma maneira fácil de afirmar a autenticidade de uma liberação.

Isso é particularmente útil em um DVCS porque qualquer um pode clonar o repositório e modificar o histórico (por exemplo, via git-filter-branch). Se uma tag for assinada, a assinatura não sobreviverá a uma operação de git-filter-branch, portanto, se você tiver uma política de que toda versão seja marcada e assinada por um committer, é possível detectar uma tag de versão falsa no repositório.

Se não fosse pela assinatura, também não veria muito sentido nas tags anotadas.

cwilper
fonte
11
Na verdade, para isso, pode ser útil ter uma assinatura que assine apenas a árvore confirmada, não toda a sua história (não me importo se alguém adulterou a história, só quero ter certeza de que tenho o código correto).
Pa Elo Ebermann
9

Empurre tags anotadas, mantenha local leve

Certos comportamentos do Git diferenciam entre si de uma maneira que essa recomendação é útil, por exemplo:

  • as tags anotadas podem conter uma mensagem, criador e data diferentes da confirmação para a qual apontam. Portanto, você pode usá-los para descrever um release sem fazer um commit de lançamento.

    Tags leves não possuem essas informações extras e não precisam delas, pois você as usará apenas para desenvolver.

  • git push --follow-tags apenas enviará tags anotadas
  • git describe sem opções de linha de comando vê apenas tags anotadas

man git-tag diz:

Tags anotadas destinam-se à liberação, enquanto tags leves destinam-se a rótulos de objetos particulares ou temporários.

Diferenças internas

  • as tags leve e anotada são um arquivo .git/refs/tagsque contém um SHA-1

  • para tags leves, o SHA-1 aponta diretamente para um commit:

    git tag light
    cat .git/refs/tags/light
    

    imprime da mesma forma que o SHA-1 da HEAD.

    Portanto, não admira que eles não possam conter outros metadados.

  • tags anotadas apontam para um objeto de tag no banco de dados de objetos.

    git tag -as -m msg annot
    cat .git/refs/tags/annot
    

    contém o SHA do objeto de tag anotado:

    c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    e então podemos obter seu conteúdo com:

    git cat-file -p c1d7720e99f9dd1d1c8aee625fd6ce09b3a81fef
    

    saída de amostra:

    object 4284c41353e51a07e4ed4192ad2e9eaada9c059f
    type commit
    tag annot
    tagger Ciro Santilli <[email protected]> 1411478848 +0200
    
    msg
    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v1.4.11 (GNU/Linux)
    
    <YOUR PGP SIGNATURE>
    -----END PGP SIGNAT
    

    E é assim que ele contém metadados extras. Como podemos ver na saída, os campos de metadados são:

    Uma análise mais detalhada do formato está presente em: Qual é o formato de um objeto de tag git e como calcular seu SHA?

Bónus

  • Determine se uma tag está anotada:

    git cat-file -t tag
    

    Saídas commitpara leves, tagpara anotadas.

  • Listar apenas tags leves: como listar todas as tags leves?

Ciro Santilli adicionou uma nova foto
fonte
6

Encontrei um bom uso para tags leves - criando uma versão no GitHub em retrospectiva.

Lançamos nosso software e tivemos as confirmações necessárias, mas não nos preocupamos em manter a seção 'Release' no GitHub. E quando demos uma pequena atenção, percebemos que também gostaríamos de adicionar alguns lançamentos anteriores, com datas de lançamento antigas corretas para eles.

Se apenas criarmos uma tag anotada em uma confirmação antiga, o GitHub levará a data da liberação do objeto da tag. Por outro lado, quando criamos uma tag leve para esse commit antigo, o lançamento começou a mostrar a data (antiga) correta. Ajuda do Source @ GitHub, 'Sobre lançamentos'

Parece que também é possível especificar a data desejada para uma confirmação anotada, mas não me parece tão simples: https://www.kernel.org/pub/software/scm/git/docs/git-tag. html # _on_backdating_tags

evilkos
fonte
Embora hoje eu tenha descoberto que o GitHub parou de honrar as datas das tags para mim (para tags leves e anotadas). Ele simplesmente desconsidera a data em que publicou o lançamento e, em vez disso, lembra a data e a hora em que pressionei o botão "Publicar" para o lançamento.
Evilkos # 13/17
Sim, eu também me deparei com essa bagunça sobre o GitHub e tags anotadas. Eu não entendo por que eles implementaram-lo desta forma ..
YakovL
1

No meu escritório, colocaremos o endereço da página de lançamento no corpo da tag. A página da Web da versão detalha todos os diferentes novos recursos e correções desde a última versão. A gerência não procurará no repositório git para descobrir quais mudanças aconteceram, e é bom ter uma lista concisa do que está nessa versão.

David
fonte
0

Tags anotadas armazenam metadados extras, como nome do autor, notas de versão, mensagem de tag e data como objetos completos no banco de dados Git. Todos esses dados são importantes para uma liberação pública do seu projeto.

tag git -a v1.0.0

Tags leves são a maneira mais simples de adicionar uma tag ao seu repositório git porque armazenam apenas o hash do commit ao qual se referem. Eles podem agir como "favoritos" de um commit, pois são ótimos para uso privado.

tag git v1.0.0

Você pode classificar, listar, excluir, mostrar e editar tags antigas. Todas essas funções ajudarão você a identificar versões específicas do seu código. Encontrei este artigo que pode ajudá-lo a ter uma idéia melhor do que as tags podem fazer.

Nesha Zoric
fonte
0

Para mim, a diferença importante é que a marca leve não tem carimbo de data e hora. Digamos que você adicionou várias tags leves:

git tag v1
git tag v2
git tag v3

e depois, talvez mais tarde, você deseja obter a última tag leve adicionada. Não há como fazê-lo. Nem "git description" nem "git tag" não fornecerão a última tag leve cronologicamente. "git tag -l" pode retornar todos eles ou classificá-los em ordem lex, mas não por data / hora. "git description --tags" retornará "v1", que definitivamente não é a última tag adicionada.

Por outro lado, se você adicionar tags anotadas:

git tag v1 -m v1
git tag v2 -m v1
git tag v3 -m v1

você sempre pode obter o carimbo de data e hora de cada tag e "git description" retornará "v3", que é realmente a última tag adicionada.

Ezh
fonte
Você precisa usar -a para que seja anotado.
21719 Alex