2012-07-13 28 views
7

Tengo un repositorio local que se extrae de uno remoto. Correr git pull, así como git fetch; git merge FETCH_HEAD utilizado para llevar a cabo exactamente la misma acción, como se espera de la description of git pull:FETCH_HEAD referencia no se actualiza correctamente después de "git fetch"

DESCRIPCIÓN

incorpora cambios de un repositorio remoto en la rama actual. En su modo predeterminado, git pull es la abreviatura de git fetch seguido de git merge FETCH_HEAD.

la actualidad, y de forma inesperada, corriendo git fetch detuvo la actualización de la referencia FETCH_HEAD correctamente. FETCH_HEAD ahora está pegado a una confirmación anterior. Al ejecutar git fetch, se descargan todos los cambios en las ramas de seguimiento remoto, pero FETCH_HEAD no se modifica independientemente de la rama en la que se ejecuta.

# currently in branchone 
> git fetch 

# branchone is up to date since... 
> git rev-parse branchone 
593539e8a98ba5980d4b645db3b0f506bb9b6a2c 

# ...its in the same commit as the remote branch 
> git rev-parse origin/branchone 
593539e8a98ba5980d4b645db3b0f506bb9b6a2c 

# however FETCH_HEAD shows something different 
> git rev-parse FETCH_HEAD 
37301df96597ac037f8e7e846fea6fc7df77bea5 

git pull sigue realizando la tarea correcta. Sin embargo, ejecutar git fetch; git merge FETCH_HEAD hará algo diferente ya que FETCH_HEAD apunta a una confirmación incorrecta.

¿Hay alguna configuración o problema que podría estar jugando con el comportamiento git fetch?

Respuesta

7

Al ejecutar git fetch sin ninguna opción, se buscarán todas las referencias en los controles remotos y se escribirán en el archivo .git/FETCH_HEAD. El contenido del archivo usualy es como la siguiente:

37301df96597ac037f8e7e846fea6fc7df77bea5 branch 'master' of github.com:user/repo 
593539e8a98ba5980d4b645db3b0f506bb9b6a2c not-for-merge branch 'branchOne' of github.com:user/repo 

Cuando usted tiene un archivo como este en el directorio .git, se puede utilizar como referencia siempre que el primero que en ese archivo es o bien un 40 número hexadecimal del personaje, o un número hexadecimal más corto que realmente coincide con una confirmación existente.

# This file can be used as a reference 
> cat .git/MAGIC_HEAD 
deadbeefdeadbeefdeadbeefdeadbeefdeadbeef lorem ipsum 
the rest does not really matter 
refrigerator 

# And thus it will be interpreted by many git commands like this 
> git rev-parse MAGIC_HEAD 
deadbeefdeadbeefdeadbeefdeadbeefdeadbeef 

Sabiendo esto, podemos ver que después de ejecutar git fetch la referencia FETCH_HEAD resolverá a es cualquier cosa que esté en esa primera línea

# Assuming the already mentioned contents of .git/FETCH_HEAD 
> git rev-parse FETCH_HEAD 
37301df96597ac037f8e7e846fea6fc7df77bea5 

parece que el orden de los contenidos de .git/FETCH_HEAD no está garantizada para contener primero la referencia para la rama actual.

Al intentarlo en diferentes repositorios, parece que en algunos la primera línea es siempre la rama actual, y por lo tanto git fetch; git merge FETCH_HEAD funciona como se esperaba. En otros repositorios, sin embargo, el contenido de .git/FETCH_HEAD se ordenará de forma diferente y, a menudo, la primera línea será una referencia a la confirmación remota de una rama diferente, por lo que la referencia FETCH_HEAD es incorrecta.

Por qué se comporta de manera diferente es un misterio para mí.

Como solución, si se usa git fetch remote_name branch_name, solo se busca esta bifurcación específica y solo aparecerá esa línea en el contenido de .git/FETCH_HEAD, haciendo que la referencia FETCH_HEAD sea siempre correcta.

# Will only fetch branchone 
> git fetch origin branchone 

# FETCH_HEAD will contain only a single line 
> cat .git/FETCH_HEAD 
593539e8a98ba5980d4b645db3b0f506bb9b6a2c branch 'branchOne' of github.com:user/repo 
0

Simplemente intente forzar su cabeza para que apunte al último compromiso/empuje que se haya realizado.

Uso esto en su repositorio Git:

git reset --hard [email protected]{1} 

Con la esperanza de que esto puede resolver su problema, teniendo a un punto en el que solía funcionar perfectamente como antes.

+0

Lamentablemente no. Incluso reseting el repositorio de edad muy avanzada revisiones cambia nada en el comportamiento de 'git fetch' y' FETCH_HEAD'. – LopSae

+0

Otra cosa que puedes intentar es eliminar todo el repositorio local y clonarlo de nuevo. De lo contrario, te ayudaré más. Estoy tratando de medir qué es lo que te pasa repositorio local .. – aliasgar

+0

En un nuevo repositorio, el comportamiento es el mismo. La confirmación a la que apunta 'FETCH_HEAD' es la primera que aparece en el archivo' .git/FETCH_HEAD'. Parece que este comportamiento es el esperado, pero Todavía me queda la duda de wh y anteriormente haciendo 'git fetch; git merge FETCH_HEAD' funcionó perfectamente en cualquier rama. – LopSae

0

Después de ejecutar git fetch (sin argumentos), FETCH_HEAD sólo incluirá una referencia válida para la fusión (es decir, no marcado como sin fines de fusión) si la corriente de rama local (es decir HEAD) es una rama de seguimiento.

La solución es o bien hacer la rama actual una rama de seguimiento (ver How do you make an existing Git branch track a remote branch?) o especificar un control remoto y una rama a buscar (es decir git fetch origin branch

+0

Las ramas en las que estaba trabajando donde todas las ramas ya están rastreando una rama remota. Después de que trajo a mi atención esta pregunta nuevamente, rehice mi respuesta para explicar mejor por qué la referencia 'FETCH_HEAD' no se actualiza correctamente. Tal vez tenga alguna relevancia lo que mencionas, y la primera línea en '.git/FETCH_HEAD' solo está garantizada bajo alguna otra circunstancia de la que no tenga conocimiento. – LopSae

Cuestiones relacionadas