web-dev-qa-db-fra.com

"Git fetch --tags" inclut-il "git fetch"?

Une question simple et agréable - la fonction de "git fetch" est-elle un sous-ensemble strict de git fetch --tags?

C'est à dire. si je lance git fetch --tags, existe-t-il une raison de lancer immédiatement git fetch immédiatement après?

Qu'en est-il de git pull et git pull --tags? Même situation?

248
davidA

Remarque: à partir de git 1.9/2.0 (Q1 2014) , _git fetch --tags_ récupère les balises en plus de ce qui est récupéré par la même ligne de commande sans l'option.

Voir commit c5a84e9 par Michael Haggerty (mhagger) :

Auparavant, l'option "_--tags_" de fetch était considérée comme équivalente à la spécification du paramètre refspec.

_refs/tags/*:refs/tags/*
_

sur la ligne de commande; en particulier, la configuration _remote.<name>.refspec_ a été ignorée.

Mais il n’est pas très utile d’extraire des balises sans extraire d’autres références, alors que cela est très utile pour pouvoir extraire des balises en plus de Autres références.
Changez donc la sémantique de cette option pour faire la dernière.

Si un utilisateur souhaite extraire uniquement des balises , il est toujours possible de spécifier un refspec explicite:

_git fetch <remote> 'refs/tags/*:refs/tags/*'
_

Veuillez noter que la documentation antérieure au 1.8.0.3 était ambiguë concernant cet aspect du comportement "_fetch --tags_".
Valider f0cb2f1 (2012-12-14) _fetch --tags_ a fait correspondre la documentation à l'ancien comportement.
Cette validation modifie la documentation pour correspondre au nouveau comportement (voir Documentation/fetch-options.txt ).

Demander que toutes les balises soient extraites de la télécommande en plus de tout ce qui est extrait .


Depuis Git 2.5 (T2 2015) _git pull --tags_ est plus robuste:

Voir commit 19d122b par Paul Tan (pyokagan) , 13 mai 2015.
(Fusion par Junio ​​C Hamano - gitster - dans commit cc77b99 , 22 mai 2015)

pull: supprime _--tags_ erreur dans le cas d'absence de candidats à la fusion

Depuis 441ed41 ("_git pull --tags_": erreur avec un meilleur message., 2007-12-28, Git 1.5.4+), _git pull --tags_ afficherait un message d'erreur différent. si _git-fetch_ n'a renvoyé aucun candidat à la fusion:

_It doesn't make sense to pull all tags; you probably meant:
       git fetch --tags
_

En effet, à ce moment-là, _git-fetch --tags_ aurait priorité sur toutes les références de référence configurées, et il n'y aurait donc pas de candidats à la fusion. Le message d'erreur a donc été introduit pour éviter toute confusion.

Cependant, depuis c5a84e9 (_fetch --tags_: chercher des balises en plus de autres éléments, 2013-10-30, Git 1.9.0+) , _git fetch --tags_ irait chercher les balises en plus des références spécifiées.
Par conséquent, si aucune situation de fusion ne se produit, ce n'est pas parce que _--tags_ a été défini. En tant que tel, ce message d'erreur spécial est désormais sans importance.

Pour éviter toute confusion, supprimez ce message d'erreur.


Avec Git 2.11+ (Q4 2016) _git fetch_ est plus rapide.

Voir commit 5827a (13 octobre 2016) par Jeff King (peff) .
(Fusionné par Junio ​​C Hamano - gitster - dans commit 9fcd144 , 26 octobre 2016)

fetch: utilise "rapide" has_sha1_file pour les balises suivantes

Lorsque vous extrayez d'une télécommande contenant de nombreuses balises non pertinentes pour les branches que nous suivons, nous perdions beaucoup trop de cycles lorsque nous vérifions si l'objet pointé par une balise (que nous n'allons pas extraire!) Existe dans notre référentiel. trop attentivement.

Ce correctif enseigne à fetch d'utiliser HAS_SHA1_QUICK pour sacrifier la précision à la vitesse, dans les cas où nous pourrions être fous avec un remballage simultané.

Voici les résultats du script perf inclus, qui met en place une situation similaire à celle décrite ci-dessus:

_Test            HEAD^               HEAD
----------------------------------------------------------
5550.4: fetch   11.21(10.42+0.78)   0.08(0.04+0.02) -99.3%
_

Cela ne s'applique que dans une situation où:

  1. Vous avez beaucoup de packs côté client pour rendre reprepare_packed_git() onéreuse (la partie la plus coûteuse consiste à rechercher des doublons dans une liste non triée, qui est actuellement quadratique).
  2. Vous avez besoin d’un grand nombre de références de balises côté serveur pouvant être suivies automatiquement (c’est-à-dire que le client n’a pas). Chacun déclenche une relecture du répertoire du pack.
  3. Dans des circonstances normales, le client suivait automatiquement ces balises et après une extraction importante, (2) ne serait plus vrai.
    Mais si ces balises pointent vers une histoire déconnectée de ce que le client récupère sinon, elle ne suivra jamais automatiquement, et ces candidats l’affecteront à chaque extraction.

Git 2.21 (février 2019) semble avoir introduit une régression lorsque le config _remote.Origin.fetch_ est et non celui par défaut (_'+refs/heads/*:refs/remotes/Origin/*'_)

_fatal: multiple updates for ref 'refs/tags/v1.0.0' not allowed
_
160
VonC

Remarque: cette réponse n'est valable que pour Git v1.8 et les versions antérieures.

La plupart de cela a été dit dans les autres réponses et commentaires, mais voici une explication concise:

  • git fetch va chercher toutes les têtes de branches (ou toutes celles spécifiées par l'option remote.fetch config), toutes les commits nécessaires, ainsi que toutes les balises accessibles à partir de ces branches. Dans la plupart des cas, toutes les balises sont accessibles de cette manière.
  • git fetch --tags récupère toutes les balises, toutes les validations nécessaires. il ne va pas mettre à jour les têtes de branche, même si elles sont accessibles à partir des balises extraites.

Résumé: Si vous voulez vraiment être totalement à jour, en utilisant seulement chercher, vous devez faire les deux.

Ce n'est pas non plus deux fois plus lent, à moins que vous ne vouliez taper sur la ligne de commande, auquel cas les alias résolvent votre problème. Il n'y a pratiquement pas de frais généraux à faire les deux demandes, puisqu'elles demandent des informations différentes.

130
Cascabel

Je vais y répondre moi-même.

J'ai déterminé qu'il y a une différence. "git fetch --tags" peut contenir tous les tags, mais il n'apporte pas de nouveaux commits!

Il s’avère qu’il faut faire cela pour être totalement "à jour", c’est-à-dire reproduire un "tir git" sans la fusion:

$ git fetch --tags
$ git fetch

C'est dommage, car c'est deux fois plus lent. Si seulement "git fetch" avait une option pour faire ce qu'il fait normalement et apporter toutes les balises.

48
davidA

Le problème général ici est que git fetch va chercher +refs/heads/*:refs/remotes/$remote/*. Si l'un de ces commits a des balises, ces balises seront également récupérées. Cependant, s'il existe des balises qui ne sont pas accessibles par une branche de la télécommande, elles ne seront pas récupérées.

L'option --tags fait basculer le refspec sur +refs/tags/*:refs/tags/*. Vous pourriez demander à git fetch de saisir les deux. Je suis presque sûr de faire un git fetch && git fetch -t pour pouvoir utiliser la commande suivante:

git fetch Origin "+refs/heads/*:refs/remotes/Origin/*" "+refs/tags/*:refs/tags/*"

Et si vous voulez en faire la valeur par défaut pour ce référentiel, vous pouvez ajouter un deuxième refspec à la récupération par défaut:

git config --local --add remote.Origin.fetch "+refs/tags/*:refs/tags/*"

Cela ajoutera une seconde ligne fetch = dans le .git/config de cette télécommande.


J'ai passé un certain temps à chercher le moyen de gérer cela pour un projet. C'est ce que je suis venu avec.

git fetch -fup Origin "+refs/*:refs/*"

Dans mon cas, je voulais ces fonctionnalités

  • Prenez toutes les têtes et tous les tags de la télécommande, utilisez donc refspec refs/*:refs/*
  • Écraser les branches locales et les balises avec une avance non rapide + avant le refspec
  • Remplacer la branche actuellement extraite si nécessaire -u
  • Supprimer les branches et les étiquettes absentes de la télécommande -p
  • Et forcer pour être sûr -f
31
gnarf

Dans la plupart des situations, git fetch doit faire ce que vous voulez, à savoir "obtenir du nouveau du référentiel distant et le placer dans votre copie locale sans fusionner avec vos branches locales". git fetch --tags fait exactement cela, sauf qu'il ne reçoit rien sauf de nouveaux tags.

En ce sens, git fetch --tags n'est en aucun cas un sur-ensemble de git fetch. C'est en fait exactement le contraire.

git pull, bien sûr, n’est rien qu’un wrapper pour un git fetch <thisrefspec>; git merge. Il est recommandé de vous habituer à la manipulation manuelle de git fetching et de git mergeing avant de passer à git pull simplement parce que cela vous aide à comprendre ce que git pull fait en premier lieu.

Cela étant dit, la relation est exactement la même qu'avec git fetch. git pull est le sur-ensemble de git pull --tags.

10
Tim Visher
git fetch upstream --tags

fonctionne très bien, il n’obtiendra que de nouvelles balises et n’aura aucune autre base de code.

1
PAnand