web-dev-qa-db-fra.com

Que signifie FETCH_HEAD dans Git?

git pull --help dit:

Dans son mode par défaut, git pull est un raccourci pour git fetch suivi de git merge FETCH_HEAD.

Qu'est-ce que c'est FETCH_HEAD et qu'est-ce qui est réellement fusionné durant git pull?

186
Misha Moroshko

FETCH_HEAD est une référence de courte durée, pour garder une trace de ce qui vient d'être récupéré du référentiel distant. git pull appelle d'abord git fetch, dans les cas normaux, récupérant une branche de la télécommande; FETCH_HEAD pointe vers le bout de cette branche (il stocke le SHA1 du commit, comme le font les branches). git pull appelle ensuite git merge en fusionnant FETCH_HEAD dans la branche actuelle.

Le résultat est exactement ce que vous attendez: le commit à la pointe de la branche distante appropriée est fusionné dans la validation à la pointe de votre branche actuelle.

C’est un peu comme faire git fetch sans arguments (ou git remote update), mettre à jour toutes vos branches distantes, puis exécuter git merge Origin/<branch>, mais utiliser FETCH_HEAD en interne pour faire référence à ref était recherché, au lieu d'avoir à nommer des choses.

186
Cascabel

FETCH_HEAD est une référence à la pointe 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 dossier .git dans un fichier nommé, vous l'avez deviné, FETCH_HEAD.

Donc si je publie:

git fetch https://github.com/ryanmaxwell/Fragaria

FETCH_HEAD peut contenir

3cfda7cfdcf9fb78b44d991f8470df56723658d3        https://github.com/ryanmaxwell/Fragaria

Si le référentiel distant est configuré en tant que branche de suivi à distance, je peux suivre mon extraction avec une fusion de la branche de suivi. Si je ne le fais pas, je peux fusionner la pointe de la dernière extraction directement à l'aide de FETCH_HEAD.

git merge FETCH_HEAD
14
Jonathan Mitchell

Comme mentionné dans 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 que toutes les branches sauf une sont marquées not-for-merge. L'intrus est la branche qui a été extraite avant l'extraction. En résumé: FETCH_HEAD correspond essentiellement à la version distante de la branche actuellement extraite.

9
Carsten Führmann

Je viens de découvrir et d'utiliser FETCH_HEAD. Je voulais une copie locale d'un logiciel à partir d'un serveur et je l'ai fait

git fetch gitserver release_1

gitserver est le nom de ma machine qui stocke les référentiels git. release_1 est une étiquette pour une version du logiciel. À ma grande surprise, release_1 était alors introuvable sur ma machine locale. Je devais taper

 git tag release_1 FETCH_HEAD 

pour terminer la copie de la chaîne de commits étiquetés (release_1) du référentiel distant vers le répertoire local un. Fetch avait trouvé la balise distante, copié la validation sur ma machine locale, n'avait pas créé une balise locale, mais avait défini FETCH_HEAD sur valeur du commit, pour que je puisse le trouver et l’utiliser. J'ai ensuite utilisé FETCH_HEAD pour créer une balise locale qui correspond à celle de la télécommande. C’est une illustration pratique de ce que FETCH_HEAD est et de la façon dont il peut être utilisé, et pourrait être utile à quelqu'un d’autre qui se demande pourquoi git fetch ne fait pas ce que vous attendiez naïvement.

À mon avis, il vaut mieux l’éviter à cette fin et une meilleure façon de réaliser ce que j’essayais de faire est de:

git fetch gitserver release_1:release_1

c'est-à-dire d'aller chercher release_1 et de l'appeler release_1 localement. (C'est source: dest, voir https://git-scm.com/book/fr/v2/Git-Internals-The-Refspec ; juste au cas où vous voudriez lui donner un nom différent!)

Vous voudrez peut-être utiliser FETCH_HEAD parfois: -

git fetch gitserver bugfix1234
git cherry-pick FETCH_HEAD

cela pourrait être une bonne façon d’utiliser le correctif 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é sur votre branche actuelle. (Je suppose qu’il existe un commit propre et bien étiqueté de Nice contenant l’ensemble du correctif sur le serveur!)

8
Ivan

git pull est la combinaison d'un fetch suivi d'une fusion. Lorsque git fetch a lieu, il note le commit principal de ce qu'il a récupéré dans FETCH_HEAD (juste un fichier portant ce nom dans .git). Ces commits sont ensuite fusionnés dans votre répertoire de travail.

3
manojlds