2012-02-11 14 views
150

git pull --help dice:¿Qué significa FETCH_HEAD en Git?

En su modo predeterminado, git pull es la abreviatura de git fetch seguido por git fusionar FETCH_HEAD.

¿Qué es este FETCH_HEAD, y lo que es en realidad se fusionó durante git pull?

+2

Nota: desde git 1.8.4 (agosto de 2013), 'git fetch origin master' realmente actualizará' origin/master', no solo 'FETCH_HEAD'. Consulte http://stackoverflow.com/a/20967347/6309 – VonC

+0

Para obtener más información sobre 'git merge FETCH_HEAD' (desde Git 2.5, Q2 2015), consulte http://stackoverflow.com/a/30425991/6309 – VonC

Respuesta

150

FETCH_HEAD es una referencia efímera, para realizar un seguimiento de lo que acaba de obtenerse del repositorio remoto. git pull primero invoca git fetch, en casos normales recuperar una rama del control remoto; FETCH_HEAD apunta a la punta de esta rama (almacena el SHA1 de la confirmación, al igual que las ramas). git pull luego invoca git merge, fusionando FETCH_HEAD en la rama actual.

El resultado es exactamente lo que esperaría: la confirmación en la punta de la rama remota apropiada se fusiona en la confirmación en la punta de su rama actual.

Esto es un poco como hacer git fetch sin argumentos (o git remote update), la actualización de todas sus sucursales remotas, a continuación, ejecutar git merge origin/<branch>, pero utilizando FETCH_HEAD internamente en lugar de referirse a cualquier ref sola era descabellada, en lugar de tener que nombrar las cosas.

+1

Pull puede hacer una rebase en lugar de una fusión si la configuras de esa manera. –

+0

@ AdamDymitruk: Claro. Describí el comportamiento predeterminado, pensando que si alguien lo modificaba, sabrían que lo habían modificado. (Para completar, el comportamiento es idéntico, reemplazando 'fusionar FETCH_HEAD' con' rebase FETCH_HEAD'). – Cascabel

+5

@Jefromi: lo siento, creo que estás equivocado: por lo que yo entiendo, 'git fetch' actualiza (fusiona) todos los datos del objeto del almacenamiento remoto, no solo ** a ** brunch. Por lo tanto, no entiendo por su respuesta cómo decide git en la punta de qué rama señalar 'FETCH_HEAD'. Tampoco puedo encontrar 'FETCH_HEAD' en la documentación de git (la definición, no ejemplos). La existencia de 'FETCH_HEAD' me parece más como una solución, para hacer que' git pull' funcione _somehow_. – Alexey

1

git pull es la combinación de un fetch seguido de una fusión. Cuando git fetch sucede, anota la confirmación del encabezado de lo que se obtuvo en FETCH_HEAD (solo un archivo con ese nombre en .git) y estos commits se fusionan en el directorio de trabajo.

+3

@manjolds, ¿A qué te refieres con "_head commit_ of what it fetched"? Git busca todo con fetch. – Alexey

+0

@Alexey de git manual: https://git-scm.com/docs/git-fetch: * Los nombres de los refs que se obtienen, junto con los nombres de los objetos a los que apuntan, se escriben en .git/FETCH_HEAD * –

10

FETCH_HEAD es una referencia a la punta de la última búsqueda, ya sea que la recuperación se haya iniciado directamente utilizando el comando fetch o como parte de una extracción. El valor actual de FETCH_HEAD se almacena en la carpeta .git en un archivo llamado, lo adivinó, FETCH_HEAD.

Así que si yo emisión:

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

FETCH_HEAD puede contener

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

Si tengo el repositorio remoto configurado como una rama de seguimiento remoto entonces puedo seguir mi alcance con una combinación del seguimiento rama. Si no, puedo fusionar la punta de la última búsqueda directamente usando FETCH_HEAD.

git merge FETCH_HEAD 
4

Acabo de descubrir y utilicé FETCH_HEAD. Yo quería una copia local de algún tipo de software desde un servidor y lo hice

git fetch gitserver release_1 

gitserver es el nombre de mi máquina que almacena los repositorios Git. release_1 es una etiqueta para una versión del software. Para mi sorpresa, release_1 no se encontraba en mi máquina local. Tenía que escriba

git tag release_1 FETCH_HEAD 

para completar la copia de la cadena de etiquetado de confirmaciones (release_1) desde el repositorio remoto a la local.Fetch había encontrado la etiqueta remota, copiaba la confirmación en mi máquina local, no había creado una etiqueta local, pero había establecido FETCH_HEAD en el valor de la confirmación, para poder encontrarla y usarla. Luego usé FETCH_HEAD para crear una etiqueta local que coincidía con la etiqueta en el control remoto. Esa es una ilustración práctica de lo que es FETCH_HEAD y cómo se puede usar, y podría ser útil para otra persona que se pregunte por qué git fetch no hace lo que ingenuamente esperaría.

En mi opinión, es mejor evitar para ese propósito y una mejor manera de lograr lo que yo estaba tratando de hacer es

git fetch gitserver release_1:release_1 

es decir, a buscar release_1 y llamarlo release_1 localmente. (Es de código: dest, ver https://git-scm.com/book/en/v2/Git-Internals-The-Refspec; si acaso desea darle un nombre diferente!)

Es posible que desee utilizar FETCH_HEAD a veces sin embargo: -

git fetch gitserver bugfix1234 
git cherry-pick FETCH_HEAD 

podría ser una Una buena manera de usar el número de corrección de errores 1234 de su servidor Git, y dejar la recolección de basura de Git para deshacerse de la copia del servidor una vez que la solución haya sido seleccionada en su rama actual. (¡Estoy asumiendo que hay una confirmación etiquetada limpia que contiene la corrección de errores en el servidor!)

+0

Comentarios interesantes. +1 – VonC

+0

Gracias. Edité mi publicación original, escrita cuando descubrí por primera vez FETCH_HEAD hace un par de años, ya que parecía alentar la copia de una etiqueta usando FETCH_HEAD en lugar de la sintaxis source: dest para refspecs. Espero haber dado un mejor ejemplo de cómo se podría usar FETCH_HEAD. – user3070485

3

Como se menciona en Jonathan's answer, FETCH_HEAD corresponde al archivo .git/FETCH_HEAD. Normalmente, el archivo se vería así:

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> 

Nota cómo todas las ramas excepto uno están marcados not-for-merge. La extraña es la rama que se controló antes de la extracción. En resumen: FETCH_HEAD se corresponde esencialmente con la versión remota de la rama que está actualmente desprotegida.