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?
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 (voirDocumentation/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 fusionDepuis 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 suivantesLorsque 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ù:
- 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).- 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.
- 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
_
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.
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.
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
refs/*:refs/*
+
avant le refspec-u
-p
-f
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 fetch
ing et de git merge
ing 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
.
git fetch upstream --tags
fonctionne très bien, il n’obtiendra que de nouvelles balises et n’aura aucune autre base de code.