git pull --help
dit :
Dans son mode par défaut,
git pull
est un raccourci pourgit fetch
suivi pargit merge FETCH_HEAD
.
Qu'est-ce que c'est ? FETCH_HEAD
et ce qui est réellement fusionné pendant git pull
?
git pull --help
dit :
Dans son mode par défaut,
git pull
est un raccourci pourgit fetch
suivi pargit merge FETCH_HEAD
.
Qu'est-ce que c'est ? FETCH_HEAD
et ce qui est réellement fusionné pendant git pull
?
FETCH_HEAD
est un ref de courte durée, pour garder la trace de ce qui vient d'être récupéré du dépôt distant. git pull
invoque d'abord git fetch
dans les cas normaux, en récupérant une branche à distance ; FETCH_HEAD
pointe vers l'extrémité de cette branche (il stocke le SHA1 du commit, tout comme les branches). git pull
puis invoque git merge
, la fusion FETCH_HEAD
dans la branche actuelle.
Le résultat est exactement ce que vous attendez : le commit à l'extrémité de la branche distante appropriée est fusionné avec le commit à l'extrémité de votre branche actuelle.
C'est un peu comme faire git fetch
sans arguments (ou git remote update
), en mettant à jour toutes vos branches distantes, puis en exécutant git merge origin/<branch>
mais en utilisant FETCH_HEAD
en interne pour faire référence à n'importe quelle référence unique recherchée, au lieu de devoir nommer les choses.
@AdamDymitruk : Bien sûr. J'ai décrit le comportement par défaut, en me disant que si quelqu'un le modifiait, il saurait qu'il l'a modifié. (Pour être complet, le comportement est identique, en remplaçant merge FETCH_HEAD
avec rebase FETCH_HEAD
).
@Jefromi : désolé, je pense que vous avez tort : d'après ce que j'ai compris, git fetch
met à jour (fusionne) toutes les données d'objet du stockage à distance, et non seulement a brunch. Donc je ne comprends pas dans votre réponse comment git décide de l'extrémité de la branche à pointer. FETCH_HEAD
. Je ne trouve pas non plus FETCH_HEAD
dans la documentation git (la définition, pas les exemples). L'existence de FETCH_HEAD
ressemble plus à une solution de contournement, pour rendre git pull
travail en quelque sorte .
Le FETCH_HEAD est une référence à l'extrémité de la dernière extraction, que celle-ci ait été lancée directement à l'aide de la commande fetch ou dans le cadre d'une extraction. La valeur actuelle de FETCH_HEAD est stockée dans le fichier .git
dans un fichier nommé, vous l'avez deviné, FETCH_HEAD
.
Donc si j'émets :
git fetch https://github.com/ryanmaxwell/Fragaria
FETCH_HEAD peut contenir
3cfda7cfdcf9fb78b44d991f8470df56723658d3 https://github.com/ryanmaxwell/Fragaria
Si le repo distant est configuré comme une branche de suivi à distance, je peux faire suivre mon extraction d'une fusion de la branche de suivi. Si ce n'est pas le cas, je peux fusionner l'extrémité de la dernière récupération directement en utilisant FETCH_HEAD.
git merge FETCH_HEAD
Pour ajouter mes 5 cents. Ce qui m'a dérouté, c'est que mon FETCH_HEAD était derrière les derniers commits, même si je faisais un nouveau fetch qui retournait "no changes" (dans eclipse). Je pense que la raison est que tous les changements depuis mon dernier fetch sont de moi et ont été poussés vers le serveur par moi. Ainsi, une récupération ultérieure n'avait rien à faire, et n'a même pas mis à jour le FETCH_HEAD. Je ne suis pas sûr qu'il s'agisse d'un défaut de GIT ou de l'implémentation Git d'Eclipse.
Comme mentionné dans La réponse de Jonathan , FETCH_HEAD correspond au fichier .git/FETCH_HEAD
. Typiquement, le fichier ressemblera à ceci :
71f026561ddb57063681109aadd0de5bac26ada9 branch 'some-branch' of <remote URL>
669980e32769626587c5f3c45334fb81e5f44c34 not-for-merge branch 'some-other-branch' of <remote URL>
b858c89278ab1469c71340eef8cf38cc4ef03fed not-for-merge branch 'yet-some-other-branch' of <remote URL>
Notez comment toutes les branches sauf une sont marquées not-for-merge
. L'intrus est la branche qui a été extraite avant la récupération. En résumé : FETCH_HEAD correspond essentiellement à la version distante de la branche qui est actuellement extraite.
Je viens de découvrir et d'utiliser FETCH_HEAD
. Je voulais une copie locale d'un logiciel depuis un serveur et j'ai fait
git fetch gitserver release_1
gitserver
est le nom de ma machine qui stocke les dépôts git. release_1
est une balise pour une version du logiciel. A ma grande surprise, release_1
était alors introuvable sur ma machine locale. J'ai dû taper
git tag release_1 FETCH_HEAD
pour compléter la copie de la chaîne de commits étiquetés (release_1) depuis le dépôt distant vers le dépôt local. Fetch avait trouvé le tag distant, copié le commit sur ma machine locale, n'avait pas a créé une balise locale, mais a défini FETCH_HEAD
à la valeur du commit, afin que je puisse le trouver et l'utiliser. J'ai ensuite utilisé FETCH_HEAD
pour créer une balise locale qui corresponde à celle de la balise distante. C'est une illustration pratique de ce que FETCH_HEAD
et comment il peut être utilisé, et pourrait être utile à quelqu'un d'autre qui se demande pourquoi git fetch ne fait pas ce que vous attendez naïvement.
À mon avis, il est préférable de l'éviter à cette fin et une meilleure façon d'atteindre ce que j'essayais de faire est de
git fetch gitserver release_1:release_1
c'est-à-dire récupérer la version 1 et l'appeler localement. (C'est source:dest, voir https://git-scm.com/book/en/v2/Git-Internals-The-Refspec ; juste au cas où vous souhaiteriez lui donner un autre nom !)
Vous pouvez utiliser FETCH_HEAD
par moments cependant:-
git fetch gitserver bugfix1234
git cherry-pick FETCH_HEAD
pourrait être un bon moyen d'utiliser le correctif de bogue numéro 1234 de votre serveur Git, et de laisser le ramasse-miettes de Git se débarrasser de la copie du serveur une fois que le correctif a été sélectionné dans votre branche actuelle. (Je suppose qu'il y a un beau commit propre et étiqueté contenant l'intégralité du correctif sur le serveur).
Merci. J'ai modifié mon message original, écrit lorsque j'ai découvert FETCH_HEAD il y a quelques années, car il semblait encourager la copie d'une balise en utilisant FETCH_HEAD plutôt que la syntaxe source:dest pour les refspecs. J'espère avoir maintenant donné un meilleur exemple de l'utilisation de FETCH_HEAD.
@manjolds, que voulez-vous dire par " engagement de tête de ce qu'il a rapporté" ? Git récupère tout avec fetch.
@Alexey du manuel git : git-scm.com/docs/git-fetch : Les noms des références qui sont récupérées, ainsi que les noms des objets vers lesquels elles pointent, sont écrits dans .git/FETCH_HEAD.
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.
3 votes
Note : depuis git 1.8.4 (août 2013),
git fetch origin master
va effectivement mettre à jourorigin/master
pas seulementFETCH_HEAD
. Voir stackoverflow.com/a/20967347/63090 votes
Pour en savoir plus
git merge FETCH_HEAD
(depuis Git 2.5, Q2 2015), voir stackoverflow.com/a/30425991/6309