Como uma tag é diferente de uma ramificação no Git? Qual devo usar aqui?

Eu estou tendo alguma dificuldade em entender como usar tags versus branches no git .

Acabei de mover a versão atual do nosso código de cvs para git e agora vou trabalhar em um subconjunto desse código para um recurso específico. Alguns outros desenvolvedores também trabalharão nisso, mas nem todos os desenvolvedores do nosso grupo vão se importar com esse recurso. Devo estar criando uma filial ou uma tag? Em que situações devo usar um versus o outro?

Uma tag representa uma versão de uma ramificação específica em um momento no tempo. Uma ramificação representa um encadeamento de desenvolvimento separado que pode ser executado simultaneamente com outros esforços de desenvolvimento na mesma base de código. Alterações em uma ramificação podem eventualmente ser mescladas em outra ramificação para unificá-las.

Normalmente, você marcará uma versão específica para que possa recriá-la, por exemplo, esta é a versão que enviamos para a XYZ Corp. Uma ramificação é mais uma estratégia para fornecer atualizações contínuas em uma versão específica do código, continuando a fazer desenvolvimento nele. Você fará uma ramificação da versão entregue, continuará o desenvolvimento na linha principal, mas fará correções de bugs na ramificação que representa a versão entregue. Eventualmente, você mesclará essas correções de bugs de volta na linha principal. Muitas vezes você vai usar tanto ramificação e marcação juntos. Você terá várias tags que podem ser aplicadas à linha principal e a suas ramificações, marcando versões específicas (aquelas entregues aos clientes, por exemplo) ao longo de cada filial que você queira recriar – para entrega, diagnóstico de erros etc.

Na verdade, é mais complicado do que isso – ou tão complicado quanto você quiser – mas esses exemplos devem dar uma ideia das diferenças.

Do ponto de vista teórico :

  • tags são nomes simbólicos para uma determinada revisão . Eles sempre apontam para o mesmo object (geralmente: para a mesma revisão); eles não mudam.
  • Ramos são nomes simbólicos para linha de desenvolvimento . Novos commits são criados no topo do branch. O ponteiro de ramificação avança naturalmente, apontando para novos e mais recentes commits.

Do ponto de vista técnico :

  • tags residem em refs/tags/ namespace e podem apontar para objects de tag (anotados e opcionalmente tags assinadas por GPG) ou diretamente para o object de commit (menos lightweight tag para nomes locais), ou em casos muito raros até mesmo para objects tree ou blob (por exemplo, assinatura GPG).
  • branches residem em refs/heads/ namespace e podem apontar apenas para submeter objects . O ponteiro HEAD deve referir-se a um ramo (referência simbólica) ou diretamente a um commit (HEAD separado ou ramificação sem nome).
  • As ramificações de rastreamento remoto residem em refs/remotes// namespace e seguem as ramificações comuns no repository .

Veja também gitglossary manpage:

ramo

Um “branch” é uma linha ativa de desenvolvimento. O commit mais recente em um branch é referido como a ponta desse branch. A ponta da ramificação é referenciada por um chefe de ramificação, que avança conforme o desenvolvimento adicional é feito na ramificação. Um único repository git pode rastrear um número arbitrário de ramificações, mas sua tree de trabalho é associada a apenas uma delas (a ramificação “atual” ou “retirada”), e HEAD aponta para essa ramificação.

tag

Uma referência apontando para uma tag ou um object commit. Em contraste com uma cabeça, uma tag não é alterada por um commit. Tags (não objects de tags) são armazenadas em $GIT_DIR/refs/tags/ . […]. Geralmente, uma tag é usada para marcar um ponto específico na cadeia de ancestral de confirmação.

object de tag

Um object que contém uma referência apontando para outro object, que pode conter uma mensagem como um object de confirmação. Ele também pode conter uma assinatura (PGP), caso em que é chamado de “object de tag assinado”.

Se você pensar em seu repository como um livro que narra o progresso em seu projeto …

Ramos

Você pode pensar em um ramo como um desses marcadores pegajosos:

insira a descrição da imagem aqui

Um novo repository tem apenas um desses (chamado master ), que automaticamente se move para a página mais recente (think commit ) que você escreveu. No entanto, você pode criar e usar mais marcadores para marcar outros pontos de interesse no livro, para poder voltar rapidamente a eles.

Além disso, você sempre pode mover um marcador específico para alguma outra página do livro (usando git-reset , por exemplo); os pontos de interesse variam tipicamente ao longo do tempo.

Tag

Você pode pensar em tags como títulos de capítulos .

favoritos

Pode conter um título (pense em tags anotadas ) ou não. Uma tag é semelhante, mas diferente de uma ramificação, na medida em que marca um ponto de interesse histórico no livro. Para manter seu aspecto histórico, depois de compartilhar uma tag (ou seja, empurrá-la para um controle remoto compartilhado), você não deve movê-la para outro lugar do livro.

O que você precisa perceber, vindo do CVS, é que você não cria mais diretórios ao configurar uma ramificação.
Não há mais “etiqueta adesiva” (que pode ser aplicada a apenas um arquivo) ou “tag de ramificação”.
Branch e tags são dois objects diferentes no Git, e eles sempre se aplicam ao repository all .

Você não precisaria mais (com o SVN desta vez) estruturar explicitamente seu repository com:

 branches myFirstBranch myProject mySubDirs mySecondBranch ... tags myFirstTag myProject mySubDirs mySecondTag ... 

Essa estrutura vem do fato de o CVS ser um sistema de revisão e não um sistema de versão (consulte Controle de origem vs. Controle de revisão? ).
Isso significa que as ramificações são emuladas através de tags para CVS, cópias de diretório para o SVN.

Sua pergunta faz sentido se você está acostumado a fazer o checkout de uma tag e começar a trabalhar nela .
Qual você não deveria;)
Uma tag supostamente representa um conteúdo imutável , usado apenas para acessá-lo com a garantia de obter o mesmo conteúdo todas as vezes.

No Git, o histórico de revisões é uma série de commits, formando um gráfico.
Um ramo é um caminho desse gráfico

 x--x--x--x--x # one branch \ --y----y # another branch 1.1 ^ | # a tag pointing to a commit 
  • Se você fizer o checkout de uma tag, precisará criar uma ramificação para começar a trabalhar a partir dela.
  • Se você fizer o checkout de um branch, você verá diretamente o último commit dele (‘HEAD’) daquele branch.

Veja a resposta de Jakub Narębski para todos os detalhes técnicos, mas francamente, neste ponto, você não precisa (ainda) de todos os detalhes;)

O ponto principal é: uma tag sendo um ponteiro simples para um commit, você nunca poderá modificar seu conteúdo. Você precisa de um ramo.


No seu caso, cada desenvolvedor trabalhando em um recurso específico:

  • deve criar sua própria filial em seu respectivo repository
  • rastrear filiais dos repositorys de seus colegas (aquele trabalhando no mesmo recurso)
  • puxando / empurrando para compartilhar seu trabalho com seus colegas.

Em vez de rastrear diretamente as ramificações de seus colegas, você poderia rastrear apenas o ramo de um repository central “oficial” para o qual todos enviam seu trabalho para integrar e compartilhar o trabalho de todos para esse recurso em particular.

Ramos são feitos de madeira e crescem do tronco da tree. Tags são feitas de papel (derivado de madeira) e penduradas como enfeites de Natal de vários lugares da tree.

Seu projeto é a tree e seu recurso que será adicionado ao projeto crescerá em uma ramificação. A resposta é ramo.

Parece que a melhor maneira de explicar é que as tags agem como ramificações somente leitura. Você pode usar um branch como tag, mas você pode inadvertidamente atualizá-lo com novos commits. As tags têm a garantia de apontar para o mesmo commit, desde que existam.

A Parábola do Git explica como um DVCS típico é criado e por que seus criadores fizeram o que fizeram. Além disso, você pode querer dar uma olhada no Git for Computer Scientist ; Ele explica o que cada tipo de object no Git faz, incluindo ramificações e tags.

Tags podem ser assinadas ou não assinadas ; ramos nunca são assinados.

As tags assinadas nunca podem ser movidas porque estão criptograficamente ligadas (com uma assinatura) a um commit específico. Tags não assinadas não são vinculadas e é possível movê-las (mas as tags em movimento não são um caso de uso normal).

As ramificações podem não apenas passar para um commit diferente, mas devem fazê-lo. Você deve usar um ramo para o seu projeto de desenvolvimento local. Não faz sentido comprometer o trabalho em um repository Git “em uma tag”.

Uma tag é usada para marcar uma versão, mais especificamente, faz referência a um ponto no tempo em uma ramificação. Um ramo é normalmente usado para adicionar resources a um projeto.

simples:

Espera-se que as tags apontem sempre para a mesma versão de um projeto, enquanto espera-se que as cabeças avancem à medida que o desenvolvimento progride.

Manual do usuário do Git

Tronco : seria o principal corpo de desenvolvimento, originando-se desde o início do projeto até o presente.

Filial : será uma cópia do código derivado de um determinado ponto no tronco que é usado para aplicar grandes alterações ao código, preservando a integridade do código no tronco. Se as principais mudanças funcionarem de acordo com o planejado, elas geralmente são mescladas de volta ao tronco.

Tag : será um ponto no tempo no tronco ou um ramo que você deseja preservar. As duas principais razões para a preservação seria que ou esta é uma versão principal do software, seja alfa, beta, RC ou RTM, ou este é o ponto mais estável do software antes que grandes revisões no tronco fossem aplicadas.