695 votes

En quoi une étiquette est-elle différente d'une branche dans Git ? Lequel dois-je utiliser, ici ?

J'ai des difficultés à comprendre comment utiliser tags contre branches en git .

Je viens de déplacer la version actuelle de notre code de cvs a git et je vais maintenant travailler sur un sous-ensemble de ce code pour une fonctionnalité particulière. Quelques autres développeurs vont également travailler sur ce projet, mais tous les développeurs de notre groupe ne vont pas s'intéresser à cette fonctionnalité. Devrais-je créer une branche ou un tag ? Dans quelles situations dois-je utiliser l'une plutôt que l'autre ?

11 votes

Puisque la recherche sur le web de la façon d'utiliser les balises git m'a amené à ce lien en premier, j'ajoute qu'il y a une meilleure réponse (IMHO) sur les balises ici : stackoverflow.com/questions/35979642/

585voto

Jakub Narębski Points 87537

De la théorique point de vue :

  • tags sont des noms symboliques pour une révision . Ils pointent toujours vers le même objet (généralement : vers la même révision) ; ils ne changent pas.
  • branches sont des noms symboliques pour Ligne de développement . De nouveaux commits sont créés au-dessus de la branche. Le pointeur de branche avance naturellement, pointant vers des commits de plus en plus récents.

De la technique point de vue :

  • tags résident à refs/tags/ et peut pointer vers objets de marquage (balises annotées et éventuellement signées GPG) ou directement à Objet de l'engagement (balise légère moins utilisée pour les noms locaux), ou même, dans de très rares cas, à objet arborescent o objet blob (par exemple, la signature GPG).
  • branches résident à refs/heads/ et ne peut pointer que vers de commettre des objets . Le site HEAD doit faire référence à une branche (référence symbolique) ou directement à un commit (HEAD détaché ou branche sans nom).
  • Branches de suivi à distance résident à refs/remotes/<remote>/ et suivre les branches ordinaires dans le dépôt distant. <remote> .

Voir aussi gitglossary page de manuel :

branche

Une "branche" est une ligne active de développement. Le commit le plus récent sur une branche est appelé l'extrémité de cette branche. L'extrémité de la branche est référencée par une tête de branche, qui avance au fur et à mesure que des développements supplémentaires sont effectués sur la branche. Un seul dépôt git peut suivre un nombre arbitraire de branches, mais votre arbre de travail est associé à une seule d'entre elles (la branche "courante" ou "sortie"), et HEAD pointe vers cette branche.

étiquette

Un ref pointant vers une balise ou un objet commit. Contrairement à une tête, une balise n'est pas modifiée par un commit. Les balises (et non les objets balises) sont stockées dans $GIT_DIR/refs/tags/ . [...]. Une balise est le plus souvent utilisée pour marquer un point particulier dans la chaîne d'ascendance de l'engagement.

objet tag

Un objet contenant un ref pointant vers un autre objet, qui peut contenir un message tout comme un objet commit. Il peut également contenir une signature (PGP), auquel cas il est appelé "objet tag signé".

42 votes

Question : si vous traitez une branche comme une étiquette (c'est-à-dire que vous la créez, puis ne la mettez jamais à jour), y a-t-il une réelle différence ?

36 votes

@SteveBennett absolument. Il contient différentes informations (vous pouvez signer un tag, vous pouvez ajouter une description à une branche). Vous pouvez déplacer une branche (donc même si vous ne la mettez jamais à jour, vous pouvez toujours la rebaser). Vous ne pouvez pas déplacer un tag (il est lié à un commit spécifique). Vous pouvez choisir de pousser une branche. Les tags ne sont pas poussés par défaut. Vous ne devriez jamais utiliser l'un pour l'autre (sauf si vous êtes vraiment dans un état d'esprit SVN, auquel cas vous devez "désapprendre" rapidement si vous voulez continuer avec git).

21 votes

@SteveBennett : Il y a une différence entre la façon dont Git traite les branches et la façon dont il traite les balises. En plus de ce que VonC a dit, vous ne pouvez pas avancer le tag par erreur : " git checkout <tag> "générerait une branche anonyme sans nom (appelée 'detached HEAD') et sélectionnerait état de l'étiquette. La création d'un nouveau commit le fait sur cette branche non nommée, et ne change pas ce vers quoi pointe le tag.

581voto

tvanfosson Points 268301

A étiquette représente une version d'une branche particulière à un moment donné. A branche représente un fil de développement distinct qui peut se dérouler en même temps que d'autres efforts de développement sur la même base de code. Les modifications apportées à une branche peuvent éventuellement être fusionnées dans une autre branche pour les unifier.

Habituellement, vous étiquette une version particulière afin de pouvoir la recréer, par exemple, c'est la version que nous avons envoyée à XYZ Corp. . A branche est plutôt une stratégie visant à fournir des mises à jour permanentes d'une version particulière du code tout en continuant à en assurer le développement. Vous créez une branche de la version livrée, poursuivez le développement sur la ligne principale, mais apportez des corrections de bogues à la branche qui représente la version livrée. Finalement, vous fusionnerez ces corrections de bogues dans la ligne principale. Souvent, vous utiliserez à la fois le branchement et le balisage. Vous aurez diverses étiquettes qui peuvent s'appliquer à la fois à la ligne principale et à ses branches, marquant des versions particulières (celles livrées aux clients, par exemple) le long de chaque branche que vous pouvez vouloir recréer -- pour la livraison, le diagnostic des bogues, etc.

C'est en fait plus compliqué que cela - ou aussi compliqué que vous voulez le faire - mais ces exemples devraient vous donner une idée des différences.

45 votes

Dans son cas, il veut utiliser des branches, peut-être devriez-vous également le noter dans votre réponse ;)

13 votes

A priori, les balises ne sont pas uniques par branche. Vous ne pouvez donc pas donner les mêmes noms à des commits différents dans des branches distinctes.

5 votes

@M.Y. Ce n'est certainement pas une mauvaise chose, à mon avis. Surtout de la manière décrite par tvanfosson, avoir plus d'une balise avec le même nom dans différentes branches pourrait devenir difficile à maintenir. Compte tenu de l'exemple, je pense que si vous pourrait avoir des étiquettes portant le même nom dans différentes branches, cela deviendrait rapidement une mauvaise pratique. Il est bon de savoir que ce n'est pas possible, cependant. Merci M.Y. !

44voto

VonC Points 414372

Ce que vous devez comprendre, en venant du CVS, c'est que vous ne créez plus répertoires lors de la création d'une succursale.
Plus de "sticky tag" (qui ne peut être appliqué qu'à un seul fichier), ni de "branch tag".
Les branches et les tags sont deux objets différents dans Git, et ils s'appliquent toujours à l'objet tous repo.

Vous n'auriez plus (avec SVN cette fois) à structurer explicitement votre dépôt avec :

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

Cette structure vient du fait que le CVS est un système de révision et non un système de version (voir Contrôle des sources ou contrôle des révisions ? ).
Cela signifie que les branches sont émulées par des balises pour CVS, des copies de répertoire pour SVN.

Votre question a du sens si vous avez l'habitude de vérifier une étiquette, et commencer à y travailler .
Ce que vous ne devriez pas faire ;)
Une balise est censée représenter un immuable le contenu, utilisé uniquement pour y accéder avec la garantie d'obtenir le même contenu à chaque fois.

Dans Git, l'historique des révisions est une série de commits, formant un graphe.
Une branche est un chemin de ce graphe

x--x--x--x--x # one branch
    \ 
     --y----y # another branch
       1.1
        ^
        |
        # a tag pointing to a commit
  • Si vous vérifiez une balise, vous devrez créer une branche pour commencer à travailler à partir de celle-ci.
  • Si vous extrayez une branche, vous verrez directement le dernier commit it('HEAD') de cette branche.

Ver La réponse de Jakub Narebski pour tous les détails techniques, mais franchement, à ce stade, vous n'avez pas besoin (encore) de tous les détails ;)

Le point principal est le suivant : une balise étant un simple pointeur vers un commit, vous ne serez jamais en mesure de modifier son contenu. Vous avez besoin d'une branche.


Dans votre cas, chaque développeur travaille sur une fonctionnalité spécifique :

  • doivent créer leur propre branche dans leur référentiel respectif.
  • suivre les branches des dépôts de leurs collègues (ceux qui travaillent sur la même fonctionnalité)
  • tirer/pousser afin de partager votre travail avec vos pairs.

Au lieu de suivre directement les branches de vos collègues, vous pourriez suivre uniquement la branche d'un dépôt central "officiel" vers lequel tout le monde pousse son travail afin d'intégrer et de partager le travail de chacun pour cette fonctionnalité particulière.

1 votes

Merci d'avoir clarifié le fonctionnement des branches et des balises :) je n'aurais pas été capable de le comprendre pleinement sans votre exemple.

3 votes

@VonC : Je pense que vous voulez dire "SVN" dans votre réponse et non "CVS". CVS n'a pas de structure de répertoire ; SVN en a une. En fait, le balisage dans git me rappelle beaucoup plus le balisage dans RCS/CVS que le balisage dans SVN (où tag == branche dégénérée).

1 votes

@ChrisCleeland bon point. J'ai essayé de séparer un peu plus les points CVS et SVN dans la réponse (éditée).

17voto

Il semble que la meilleure façon d'expliquer est que les balises agissent comme des branches en lecture seule. Vous pouvez utiliser une branche comme balise, mais vous pouvez par inadvertance la mettre à jour avec de nouveaux commits. Les étiquettes sont garanties de pointer vers le même commit tant qu'elles existent.

11 votes

Les étiquettes sont garanties de pointer vers le même commit tant qu'elles existent. Pas tout à fait vrai. Vous pouvez en fait déplacer une balise avec git tag -f .

10voto

Bombe Points 34185

El Parabole de Git explique comment un DVCS typique est créé et pourquoi ses créateurs ont fait ce qu'ils ont fait. Vous pouvez également jeter un coup d'œil à Git pour informaticien ; il explique ce que fait chaque type d'objet dans Git, y compris les branches et les balises.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X