Comment commander la balise git distante

Lorsque je récupère la balise git distante, utilisez la commande comme ceci:

git checkout -b local_branch_name origin/remote_tag_name

J'ai eu une erreur comme ceci:

error: pathspec `origin/remote_tag_name` did not match any file(s) known to git.

Je peux trouver remote_tag_name lorsque j'utilise la commande git tag.

249
demandé sur Steven Vascellaro 2016-03-14 07:38:50

2 réponses

Commençons par expliquer ce qu'est une balise 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 libération (par exemple. v1. 0, etc.).

Bien qu'une balise puisse sembler similaire à la branche, une balise, cependant, ne change pas .
Il pointe directement vers un commit spécifique dans l'historique.

entrez la description de l'image ici


Vous ne serez pas capable de récupérer les balises si ce n'est pas localement dans votre référentiel, vous devez 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

Ensuite, vérifiez la balise en exécutant

git checkout tags/<tag_name> -b <branch_name>

Au lieu de origin utilisez le préfixe tags/.


Dans cet exemple, vous avez 2 balises version 1.0 et version 1.1, vous pouvez les extraire avec l'un des éléments suivants:

git checkout A  ...
git checkout version 1.0  ...
git checkout tags/version 1.0  ...

Tous les ci-dessus fera la même chose puisque tag n'est qu'un pointeur vers un commit donné.

entrez la description de l'image ici
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 balises?

Il y a 2 façons de créer une balise:

# normal 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 dans un git commit:
Nom, e-mail, date, commentaire et signature

entrez la description de l'image ici

Comment supprimer les balises?

# delete any given tag
git tag -d <tag name>

# Don't forget to remove the deleted tag form the server with push tags

Comment cloner une balise spécifique?

Pour saisir l'ocntent d'une balise donnée, vous pouvez utiliser la commande checkout.
Comme expliqué ci-dessus, les balises sont comme n'importe quel autre commit afin que nous puissions utiliser checkout et au lieu d'utiliser le SHA-1, remplacez-le simplement par le tag_name

Option 1:

# Update the local gir 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 shalow clone en ajoutant le --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é au commit correspondant

# Clone a specific tag name
 git clone <url. --branch=<tag_name>

Git clone --branche=

--branch peut également prendre des balises et détache la tête à ce commit dans le référentiel résultant.

521
répondu CodeWizard 2018-09-24 13:41:34

(cette réponse a pris un certain temps à écrire, et la réponse de codeWizard est correcte dans le but et l'essence, mais pas entièrement complète, donc je vais poster ceci de toute façon.)


Il n'existe pas de "tag Git distant". Il y a seulement des "tags". Je signale tout cela pour ne pas être pédant,1 mais parce qu'il y a beaucoup de confusion à ce sujet avec les utilisateurs occasionnels de Git, et la documentation Git n'est pas très utile2 pour les débutants. (Il n'est pas clair si l' la confusion vient à cause d'une mauvaise documentation, ou la mauvaise documentation vient parce que c'est intrinsèquement quelque peu déroutant, ou quoi.)

Il y a "branches distantes", plus correctement appelées" branches de suivi à distance", mais il convient de noter que ce sont en fait des entités locales. Il n'y a pas de balises distantes, cependant (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 commits spécifiques-que git appelle references - sont n'importe quelle chaîne commençant par refs/. Une chaîne commençant par refs/heads/ nomme une branche; une chaîne commençant par refs/remotes/ nomme une branche de suivi à distance; et une chaîne commençant par refs/tags/ nomme une balise. Le nom refs/stash est la référence stash (tel qu'utilisé par git stash; notez l'absence d'une barre oblique finale).

Il y a des noms de cas spéciaux inhabituels qui ne commencent pas par refs/: HEAD, ORIG_HEAD, MERGE_HEAD, et CHERRY_PICK_HEAD en particulier sont tous aussi des noms cela peut faire référence à des commits spécifiques (bien que HEAD contienne normalement le nom d'une branche, c'est-à-dire contient ref: refs/heads/branch). Mais en général, les références commencent par refs/.

Une chose que Git fait pour rendre cette confusion est qu'il vous permet d'omettre le refs/, et souvent le mot après refs/. Par exemple, vous pouvez omettre refs/heads/ ou refs/tags/ lorsque vous faites référence à une branche locale ou à une balise-et en fait vous devez omettre refs/heads/ lorsque vous extrayez une branche locale! Vous pouvez le faire chaque fois que le résultat est sans ambiguïté, ou-comme nous venons de le noter-quand 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 aussi 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 les opérations fetch et push. Vous pouvez également utiliser git ls-remote ou git remote show voir, mais fetch et push sont les points les plus intéressants de contact.

Refspecs

Pendant fetch et push, Git utilise des chaînes qu'il appelle refspecs pour transférer des références entre le référentiel local et le référentiel distant. Ainsi, c'est à ces moments-là, et via refspecs, que deux dépôts Git peuvent être synchronisés les uns avec les autres. Une fois vos noms synchronisés, vous pouvez utiliser le même nom que celui utilisé par une personne avec la télécommande. Il y a cependant une magie spéciale ici sur fetch, et cela affecte à la fois les noms de branche et les noms de balise.

Vous devriez penser à {[31] } comme dirigeant votre Git pour appeler (ou peut-être message texte) un autre Git - la "télécommande"- et avoir une conversation avec elle. Au début de cette conversation, la télécommande répertorie toutes ses références: tout dans refs/heads/ et tout dans refs/tags/, ainsi que toutes les autres références qu'elle possède. Votre Git analyse ceux-ci et (en fonction de l'habituel fetch refspec) renomme leurs branches.

Jetons un coup d'oeil à la refspec normale pour la télécommande nommée origin:

$ git config --get-all remote.origin.fetch
+refs/heads/*:refs/remotes/origin/*
$ 

Cette refspec demande à votre Git de prendre chaque nom correspondant refs/heads/* - c'est-à-dire, chaque branche sur la télécommande-et changez son nom en refs/remotes/origin/*, c'est-à-dire, gardez 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/, plus précisément, refs/remotes/origin/).

C'est à travers cette refspec que les branches de origin deviennent vos branches de suivi à distance pour remote origin. Le nom de la branche devient le nom de la branche de suivi à distance, avec le nom de la télécommande, dans ce cas origin, inclus. Le signe +, à l'avant de la refspec définit l'indicateur "force", c'est-à-dire que votre branche de suivi à distance sera mise à jour pour correspondre au nom de la branche distante, indépendamment de ce qu'il faut pour la faire correspondre. (Sans +, les mises à jour de branche sont limitées aux modifications "avance rapide", et les mises à jour de balise sont simplement ignorées depuis la version 1.8.2 de Git-avant cela, les mêmes règles d'avance rapide s'appliquaient.)

Étiquettes

Mais qu'en est-il des tags? Il n'y a pas de refspec pour eux-du moins, pas par défaut. Vous pouvez en définir un, auquel cas la forme de le refspec est à vous; ou vous pouvez exécuter git fetch --tags. L'utilisation de --tags A pour effet d'ajouter refs/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écommande Edit, Jan 2017: à partir de git 2.10, les tests montrent que --tags met à jour de force vos balises à partir des balises de la télécommande, comme si le refspec lisait +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 distant origin a tag xyzzy, et vous ne le faites pas, et vous git fetch origin "refs/tags/*:refs/tags/*", Vous obtenez refs/tags/xyzzy ajouté à votre référentiel (pointant vers le même commit que sur la télécommande). Si vous utilisez +refs/tags/*:refs/tags/*, puis votre balise xyzzy, si vous en avez un, remplacé par l'un de origin. Autrement dit, le drapeau + force sur un refspec signifie "remplacer la valeur de ma référence par celle que mon Git obtient de leur Git".

Balises Automagiques pendant chercher

, Pour des raisons historiques,3 si vous n'utilisez pas l' --tags option, ni la --no-tags option, git fetch prend d'action spécial. Rappelez-vous que nous avons dit plus haut que la télécommande commence par afficher sur votre Git local toutes les de 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. alors, comme il commence à télécharger tous les objets commit, il doit gérer tout ce qu'il récupère, si l'un de ces commits 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.

Modifier, Jan 2017: les tests montrent que le comportement en Git 2.10 est maintenant: Si leur Git fournit un tag nommé T, et vous n'avez pas une balise nommée T, et la validation ID associé à T est un ancêtre de l'une de leurs branches que votre git fetch est l'examen, votre Git ajoute T à vos balises avec ou sans --tags. L'ajout de --tags fait que votre Git obtient tous les leurs balises, et force également la mise à jour.

Résultat net

, Vous pouvez 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 avoir à supprimer (ou renommer) certaines de vos balises, puis exécutez git fetch --tags, pour obtenir leurs balises. Puisque 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 avoir des problèmes avec les conflits.

Dans la plupart des cas normaux, cependant, un simple {[31] } fera le travail, apportant leurs commits et leurs balises correspondantes, et comme ils-quels qu'ils soient-marqueront les commits au moment où ils publient ces commits, 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 aucun nom de balise collisions non plus, vous n'aurez donc pas à vous soucier de supprimer ou de renommer les balises afin d'obtenir leurs balises.

Lorsque vous avez besoin de noms qualifiés

Je l'ai mentionné ci-dessus que vous pouvez omettre refs/ presque toujours, et refs/heads/ et refs/tags/ et donc, la plupart du temps. Mais quandne peut pas vous?

La réponse complète (ou presque complète de toute façon) se trouve dans la documentation gitrevisions . Git résoudra un nom en un ID de validation en utilisant la séquence en six étapes donnée dans le lien. Curieusement, les balises remplacent les branches: s'il y a une balise xyzzy et une branche xyzzy, et qu'elles pointent vers des commits différents, alors:

git rev-parse xyzzy

Vous donnera L'ID vers lequel la balise pointe. Cependant - et c'est ce qui manque à gitrevisions-git checkout préfère les noms de branche, donc git 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 ou refs/tags/xyzzy. (Notez que ce fonctionne avec git checkout, mais d'une manière peut-être inattendue: git checkout refs/heads/xyzzy provoque une caisse détachée plutôt qu'une caisse de branche. C'est pourquoi il vous suffit de noter que git checkout utilisera d'abord le nom court comme nom de branche: c'est ainsi que vous consultez la branche xyzzy même si la balise xyzzy existe. Si vous voulez vérifier la balise, vous pouvez utiliser refs/tags/xyzzy.)

Parce que (comme gitrevisions notes) Git va essayer refs/name, vous pouvez aussi simplement écrire tags/xyzzy pour identifier le commit marqué xyzzy. (Si quelqu'un a réussi à écrivez une référence valide nommée xyzzy dans $GIT_DIR, cependant, cela se résoudra comme $GIT_DIR/xyzzy. Mais normalement, seuls les différents noms *HEAD devraient être dans $GIT_DIR.)


1Okay, Okay, "pas juste pour être pédant". :-)

2Certains diront "pas très utile", et j'aurais tendance à être d'accord, en fait.

3fondamentalement, git fetch, et tout le concept de télécommandes et refspecs, était un peu un ajout tardif à Git, qui se passe autour de la le temps de Git 1.5. Avant cela, il y avait juste quelques cas spéciaux ad hoc, et la récupération de balises était l'un d'entre eux, donc il a obtenu des droits acquis via un code spécial.

4si cela vous aide, pensez au Git distant comme un flasher , dans le sens de l'argot.

136
répondu torek 2017-05-23 11:47:21