Commençons par expliquer ce qu'est un tag dans git
Une balise est utilisée pour étiqueter et marquer un commit spécifique dans l'historique.
Il est généralement utilisé pour marquer les points de sortie (par exemple, v1.0, etc.).
Bien qu'une balise puisse sembler similaire à une branche, une balise, cependant, ne change pas . Il pointe directement vers un commit spécifique dans l'historique.
Vous ne pourrez pas extraire les balises si elles ne sont pas localement dans votre référentiel, vous devez donc d'abord fetch
les balises dans votre référentiel local.
Tout d'abord, assurez-vous que la balise existe localement en faisant
# --all will fetch all the remotes.
# --tags will fetch all tags as well
$ git fetch --all --tags --prune
Vérifiez ensuite la balise en exécutant
$ git checkout tags/<tag_name> -b <branch_name>
Au lieu d' origin
utiliser le tags/
préfixe.
Dans cet exemple, vous avez 2 balises version 1.0 et version 1.1, vous pouvez les vérifier avec l'une des options suivantes:
$ git checkout A ...
$ git checkout version 1.0 ...
$ git checkout tags/version 1.0 ...
Tout ce qui précède fera de même puisque la balise n'est qu'un pointeur vers une validation donnée.
origine: https://backlog.com/git-tutorial/img/post/stepup/capture_stepup4_1_1.png
Comment voir la liste de toutes les balises?
# list all tags
$ git tag
# list all tags with given pattern ex: v-
$ git tag --list 'v-*'
Comment créer des tags?
Il existe 2 façons de créer une balise:
# lightweight tag
$ git tag
# annotated tag
$ git tag -a
La différence entre les 2 est que lors de la création d'une balise annotée, vous pouvez ajouter des métadonnées comme vous l'avez fait dans un commit git:
nom, e-mail, date, commentaire et signature
Comment supprimer des 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>
Comment cloner une balise spécifique?
Afin de saisir le contenu d'une balise donnée, vous pouvez utiliser la checkout
commande. Comme expliqué ci-dessus, les balises sont comme tout autre commit, nous pouvons donc utiliser checkout
et au lieu d'utiliser le SHA-1 le remplacer simplement par le tag_name
Option 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>
Option 2:
Utilisation de la commande clone
Puisque git prend en charge le clone superficiel en ajoutant la --branch
à la commande clone, nous pouvons utiliser le nom de la balise au lieu du nom de la branche. Git sait comment "traduire" le SHA-1 donné en commit approprié
# Clone a specific tag name using git clone
$ git clone <url> --branch=<tag_name>
git clone --branch =
--branch
peut également prendre des balises et détacher le HEAD lors de cette validation dans le référentiel résultant.
Comment pousser les tags?
git push --tags
Pour pousser toutes les balises:
# Push all tags
$ git push --tags
Utiliser le refs/tags
au lieu de simplement spécifier le <tagname>
.
Pourquoi? - Il est recommandé d'utiliser refs/tags
car parfois les balises peuvent avoir le même nom que vos branches et une simple poussée git poussera la branche au lieu de la balise
Pour envoyer des balises annotées et des balises de chaîne d'historique actuelles, utilisez:
git push --follow-tags
Cet indicateur --follow-tags
pousse à la fois les validations et uniquement les balises qui sont à la fois:
- Balises annotées (vous pouvez donc ignorer les balises de construction locales / temporaires)
- Balises accessibles (un ancêtre) de la branche actuelle (située sur l'historique)
Depuis Git 2.4, vous pouvez le configurer en utilisant la configuration
$ git config --global push.followTags true
Cheatsheet:
git checkout A
. c'est quoiA
? Comment avez-vous crééA
?A
est un hachage de validationgit checkout tags/<tag_name> -b <branch_name>
cela nécessite le-b <branch_name>
.git checkout tags/<tag_name>
m'a donné une tête détachée. Conformément à cet article sur la tête détachée , vous évitez une tête détachée en créant et en supprimant temporairement une branche. C'est un flux de travail assez étranger. De toute évidence, en tant qu'utilisateur git, je dois m'habituer à créer et supprimer des branches pour le plaisir et le profit.(Cette réponse a pris du temps à écrire, et la réponse de codeWizard est correcte dans son objectif et son essence, mais pas entièrement complète, donc je posterai tout de même.)
Il n'existe pas de "balise Git distante". Il n'y a que des "tags". Je signale tout cela ne pas être pédant, 1 mais parce qu'il ya beaucoup de confusion à ce sujet avec les utilisateurs occasionnels Git, ainsi que la documentation Git est pas très utile 2 pour les débutants. (Il n'est pas clair si la confusion vient d'une mauvaise documentation, ou si la mauvaise documentation vient parce que c'est intrinsèquement quelque peu déroutant, ou quoi.)
Il existe des "succursales distantes", plus précisément appelées "succursales de suivi à distance", mais il convient de noter qu'il s'agit en fait d'entités locales. Il n'y a cependant pas de balises distantes (sauf si vous les (ré) inventez). Il n'y a que des balises locales, vous devez donc obtenir la balise localement pour l'utiliser.
La forme générale des noms pour les validations spécifiques - que Git appelle références - est n'importe quelle chaîne commençant par
refs/
. Une chaîne qui commence parrefs/heads/
nomme une branche; une chaîne commençant par lesrefs/remotes/
noms d'une branche de suivi à distance; et une chaîne commençant parrefs/tags/
nomme une balise. Le nomrefs/stash
est la référence cachée (tel qu'utilisé pargit stash
; notez l'absence d'une barre oblique de fin).Il y a des noms inhabituels de cas de spécial qui ne commencent pas avec
refs/
:HEAD
,ORIG_HEAD
,MERGE_HEAD
, etCHERRY_PICK_HEAD
en particulier sont aussi des noms qui peuvent se référer à commits spécifiques (bien queHEAD
contient normalement le nom d'une branche, à savoir, contient ). Mais en général, les références commencent par .ref: refs/heads/branch
refs/
Une chose que Git fait pour rendre cela déroutant, c'est qu'il vous permet d'omettre le
refs/
, et souvent le mot aprèsrefs/
. Par exemple, vous pouvez omettrerefs/heads/
ourefs/tags/
lorsque vous faites référence à une branche ou une balise locale - et en fait, vous devez l' omettrerefs/heads/
lors de la vérification d'une branche locale! Vous pouvez le faire chaque fois que le résultat est sans ambiguïté ou, comme nous venons de le noter, lorsque vous devez le faire (pour ).git checkout branch
Il est vrai que les références existent non seulement dans votre propre référentiel, mais également dans des référentiels distants. Cependant, Git vous donne accès aux références d'un référentiel distant uniquement à des moments très précis: à savoir pendant
fetch
et pendant lespush
opérations. Vous pouvez également utilisergit ls-remote
ougit remote show
pour les voir, maisfetch
etpush
sont les points de contact les plus intéressants.Refspecs
Pendant
fetch
etpush
, Git utilise des chaînes qu'il appelle refspecs pour transférer des références entre le référentiel local et distant. Ainsi, c'est à ces moments, et via les refspecs, que deux référentiels Git peuvent se synchroniser. Une fois vos noms synchronisés, vous pouvez utiliser le même nom que celui qui utilise la télécommande. Il y a cependant une magie spéciale icifetch
, et elle affecte à la fois les noms de branche et les noms de balise.Vous devriez penser
git fetch
à demander à votre Git d'appeler (ou peut-être un SMS) un autre Git - le "distant" - et d'avoir une conversation avec lui. Au début de cette conversation, la télécommande répertorie toutes ses références: toutrefs/heads/
cerefs/tags/
qu'il contient et tout ce qu'il contient, ainsi que toutes les autres références qu'il possède. Votre Git les analyse et (en se basant sur la refspec fetch habituelle) renomme leurs branches.Jetons un coup d'œil à la spécification normale pour la télécommande nommée
origin
:Cette spécification spécifie à votre Git de prendre chaque correspondance de
refs/heads/*
nomrefs/remotes/origin/*
- c'est- à -dire , chaque branche de la télécommande - et de changer son nom en , c'est- à -dire de garder la partie correspondante la même, en changeant le nom de la branche (refs/heads/
) en un nom de branche de suivi à distance (refs/remotes/
, spécifiquement ,refs/remotes/origin/
).C'est grâce à cette refspec que
origin
les branches deviennent vos branches de suivi à distance pour les télécommandesorigin
. Le nom de la branche devient le nom de la branche de suivi à distance, avec le nom de la télécommande, dans ce casorigin
, inclus. Le signe plus+
à l'avant de la spécification spécifie le drapeau "force", c'est-à-dire que votre branche de suivi à distance sera mise à jour pour correspondre au nom de la branche de la télécommande, indépendamment de ce qu'il faut pour la faire correspondre. (Sans le+
, les mises à jour de branche sont limitées aux changements "d'avance rapide", et les mises à jour de balises sont simplement ignorées depuis la version 1.8.2 de Git environ - avant les mêmes règles d'avance rapide appliquées.)Mots clés
Mais qu'en est-il des tags? Il n'y a pas de spécification pour eux, du moins pas par défaut. Vous pouvez en définir un, auquel cas la forme de la spécification vous appartient; ou vous pouvez courir
git fetch --tags
. L'utilisation--tags
a pour effet d'ajouterrefs/tags/*:refs/tags/*
à la refspec, c'est-à-dire qu'elle apporte toutes les balises (mais ne met pas à jour votre balise si vous avez déjà une balise avec ce nom, indépendamment de ce que dit la balise de la télécommandeEdit, Jan 2017: à partir de Git 2.10 , les tests montrent que--tags
les balises sont mises à jour de force à partir des balises de la télécommande, comme si la spécification était lue+refs/tags/*:refs/tags/*
; cela peut être une différence de comportement par rapport à une version antérieure de Git).Notez qu'il n'y a pas de renommage ici: si remote
origin
a une balisexyzzy
, et vous ne l'avez pas, et vousgit fetch origin "refs/tags/*:refs/tags/*"
, vous êtesrefs/tags/xyzzy
ajouté à votre référentiel (pointant vers le même commit que sur la remote). Si vous utilisez+refs/tags/*:refs/tags/*
alors votre balisexyzzy
, si vous en avez une, est remplacée par celle deorigin
. C'est-à-dire que l'+
indicateur de force sur une refspec signifie "remplacer la valeur de ma référence par celle que mon Git obtient de son Git".Balises automagiques lors de la récupération
Pour des raisons historiques, 3 si vous n'utilisez ni l'
--tags
option ni l'--no-tags
option,git fetch
prend des mesures spéciales. N'oubliez pas que nous avons dit ci-dessus que la télécommande commence par afficher sur votre Git local toutes ses références, que votre Git local veuille les voir ou non. 4 Votre Git prend note de toutes les balises qu'il voit à ce stade.Ensuite, alors qu'il commence à télécharger les objets de validation dont il a besoin pour gérer tout ce qu'il récupère, si l'une de ces validations a le même ID que l'une de ces balises, git ajoutera cette balise - ou ces balises, si plusieurs balises ont cet ID - à votre référentiel.Edition, janvier 2017: Les tests montrent que le comportement dans Git 2.10 est maintenant: Si leur Git fournit une balise nommée T , et vous n'avez pas une balise nommée T , et la validation ID associé à T est un ancêtre d'une de leurs branches que vous
git fetch
examinez, votre Git ajoute T à vos balises avec ou sans--tags
. L'ajout--tags
oblige votre Git à obtenir toutes ses balises et force également la mise à jour.Conclusion
Vous devrez peut-être utiliser
git fetch --tags
pour obtenir leurs balises. Si leurs noms de balises entrent en conflit avec vos noms de balises existants, vous pouvez (selon la version de Git) même supprimer (ou renommer) certaines de vos balises, puis exécutergit fetch --tags
, pour obtenir leurs balises. Étant donné que les balises, contrairement aux branches distantes, n'ont pas de renommage automatique, vos noms de balises doivent correspondre à leurs noms de balises, c'est pourquoi vous pouvez rencontrer des problèmes avec les conflits.Dans la plupart des cas normaux, cependant, un simple
git fetch
fera le travail, en apportant leurs validations et leurs balises correspondantes, et puisqu'ils - qui qu'ils soient - marqueront les validations au moment où ils publieront ces validations, vous suivrez leurs balises. Si vous ne créez pas vos propres balises, ni ne mélangez leur référentiel et d'autres référentiels (via plusieurs télécommandes), vous n'aurez pas non plus de collision de noms de balises, vous n'aurez donc pas à vous soucier de supprimer ou de renommer des balises afin de obtenir leurs étiquettes.Lorsque vous avez besoin de noms qualifiés
Je l' ai mentionné ci - dessus que vous pouvez omettre
refs/
presque toujours, etrefs/heads/
etrefs/tags/
et ainsi de suite la plupart du temps. Mais quand ne le pouvez- vous pas ?La réponse complète (ou presque complète de toute façon) se trouve dans la
gitrevisions
documentation . Git résoudra un nom en ID de validation en utilisant la séquence en six étapes indiquée dans le lien. Curieusement, les balises remplacent les branches: s'il y a une balisexyzzy
et une branchexyzzy
, et qu'elles pointent vers des validations différentes, alors:vous donnera l'ID vers lequel pointe le tag. Cependant - et c'est ce qui manque
gitrevisions
-git checkout
préfère les noms de branche, doncgit checkout xyzzy
vous mettra sur la branche, sans tenir compte de la balise.En cas d'ambiguïté, vous pouvez presque toujours épeler le nom ref en utilisant son nom complet,
refs/heads/xyzzy
ourefs/tags/xyzzy
. (Notez que cela fait travailler avecgit checkout
, mais d'une manière peut - être inattendue:git checkout refs/heads/xyzzy
provoque un départ-HEAD individuelle plutôt que d' une caisse de branche Ceci est la raison pour laquelle il vous suffit de noter que.git checkout
Utilisera le nom court comme nom de la branche première: qui est la façon dont vous extraire la branchexyzzy
même si la balisexyzzy
existe. Si vous souhaitez extraire la balise, vous pouvez l'utiliserrefs/tags/xyzzy
.)Parce que (comme des
gitrevisions
notes) Git va essayer , vous pouvez aussi simplement écrire pour identifier le commit balisé . (Si quelqu'un a réussi à écrire une référence valide nommée dans , cependant, cela se résoudra en . Mais normalement, seuls les différents noms doivent être inclus .)refs/name
tags/xyzzy
xyzzy
xyzzy
$GIT_DIR
$GIT_DIR/xyzzy
*HEAD
$GIT_DIR
1 D'accord, d'accord, "pas seulement pour être pédant". :-)
2 Certains diraient «très inutile», et j'aurais tendance à être d'accord, en fait.
3 Fondamentalement,
git fetch
et tout le concept des télécommandes et des refspecs, était un peu un ajout tardif à Git, se produisant à l'époque de Git 1.5. Avant cela, il n'y avait que quelques cas spéciaux ad hoc, et la récupération de balises en faisait partie, donc il a été protégé par un code spécial.4 Si cela peut vous aider, considérez le Git distant comme un clignotant , dans le sens de l'argot.
la source
git fetch
ne récupérera que les balises de la télécommande en fonction de l'--tags
arg.--tags
,--no-tags
et par défaut est en fait assez difficile. La valeur par défaut est d'introduire des balises que vous n'avez pas dans les commits que vous apportez. (Voir l'édition de janvier 2017.) Mais il y a aussi des problèmes ici, et Git moderne a ses --tags / - Le code de gestion des non-balises a encore été révisé, ce qui entraînera probablement des cas d'angle encore plus spéciaux.Pour extraire une balise git, vous devez exécuter la commande suivante
par exemple, comme mentionné ci-dessous.
Pour récupérer toutes les balises, utilisez la commande
la source
Pour obtenir le code d'étiquette spécifique, essayez de créer une nouvelle branche, ajoutez-y le code d'étiquette. Je l'ai fait par commande:
$git checkout -b newBranchName tagName
la source