tag - tipos de etiquetas en git
¿Qué significa FETCH_HEAD en Git? (5)
Acabo de descubrir y utilicé FETCH_HEAD
. Quería una copia local de algún software de un servidor y lo hice
git fetch gitserver release_1
gitserver
es el nombre de mi máquina que almacena repositorios git. release_1
es una etiqueta para una versión del software. Para mi sorpresa, el release_1
no se encontraba en mi máquina local. Tuve que escribir
git tag release_1 FETCH_HEAD
para completar la copia de la cadena etiquetada de commits (release_1) desde el repositorio remoto al local. Fetch había encontrado la etiqueta remota, había copiado 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 coincidiera 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 evitarlo para ese propósito y una mejor manera de lograr lo que estaba tratando de hacer es
git fetch gitserver release_1:release_1
es decir, para obtener la versión_1 y llamarla release_1 localmente. (Es source: dest, mira https://git-scm.com/book/en/v2/Git-Internals-The-Refspec , ¡por si acaso quieres darle un nombre diferente!)
Es posible que desee utilizar FETCH_HEAD
a veces:
git fetch gitserver bugfix1234
git cherry-pick FETCH_HEAD
podría ser 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 corrección se haya seleccionado en su rama actual. (¡Estoy asumiendo que hay una buena confirmación etiquetada que contiene toda la corrección de errores en el servidor!)
git pull --help
dice:
En su modo predeterminado, git pull es la abreviatura de git fetch seguido de git merge FETCH_HEAD.
¿Qué es este FETCH_HEAD
, y lo que realmente se fusionó durante la git pull
?
Como se menciona en la respuesta de Jonathan , FETCH_HEAD corresponde al archivo .git/FETCH_HEAD
. Normalmente, el archivo se verá 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>
Tenga en cuenta que todas las ramas, excepto una, están marcadas como 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.
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 un pull. El valor actual de FETCH_HEAD se almacena en la carpeta .git
en un archivo llamado, lo has adivinado, FETCH_HEAD
.
Entonces si publico:
git fetch https://github.com/ryanmaxwell/Fragaria
FETCH_HEAD puede contener
3cfda7cfdcf9fb78b44d991f8470df56723658d3 https://github.com/ryanmaxwell/Fragaria
Si tengo el repo remoto configurado como una rama de seguimiento remoto, entonces puedo seguir mi búsqueda con una fusión de la rama de seguimiento. Si no, puedo fusionar la punta de la última búsqueda directamente usando FETCH_HEAD.
git merge FETCH_HEAD
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.
FETCH_HEAD
es una referencia efímera, para hacer un seguimiento de lo que acaba de obtenerse del repositorio remoto. git pull
primero invoca git fetch
, en casos normales busca una rama desde el 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
invoca a git merge
, fusionando FETCH_HEAD
en la rama actual.
El resultado es exactamente lo que esperarías: la confirmación en la punta de la rama remota apropiada se fusiona en la confirmación en la punta de tu rama actual.
Esto es un poco como hacer git fetch
sin argumentos (o git remote update
), actualizar todas sus sucursales remotas, luego ejecutar git merge origin/<branch>
, pero usar FETCH_HEAD
internamente para referirse a cualquier ref simple que se haya obtenido, en lugar de necesitar para nombrar cosas