¿Cómo 'git fetch' y 'git merge' desde una rama de seguimiento remoto (como 'git pull')

111

He configurado algunas ramas de seguimiento remoto en git, pero parece que nunca puedo fusionarlas en la rama local una vez que las he actualizado con 'git fetch'.

Por ejemplo, supongamos que tengo una rama remota llamada 'an-other-branch'. Lo configuré localmente como una rama de seguimiento usando

git branch --track an-other-branch origin/an-other-branch

Hasta aquí todo bien. Pero si esa rama se actualiza (generalmente moviendo la máquina y comprometiéndome desde esa máquina), y quiero actualizarla en la máquina original, tengo problemas con la búsqueda / fusión:

git fetch origin an-other-branch
git merge origin/an-other-branch

Siempre que hago esto, recibo un mensaje de 'Ya actualizado' y nada se fusiona.

Sin embargo, un

git pull origin an-other-branch

siempre lo actualiza como cabría esperar.

Además, ejecutando git diff

git diff origin/an-other-branch

muestra que hay diferencias, así que creo que tengo una sintaxis incorrecta.

¿Qué estoy haciendo mal?

EDITAR [2010-04-09]: Lo he comprobado un par de veces, y definitivamente no estoy en una rama diferente. ¿Mi 'git fetch' seguido de un 'git merge' (como se muestra arriba) debería hacer exactamente lo mismo que un git pull? Obtendré un flujo de trabajo que muestre los resultados de un estado de git, etc.

Kaybenleroll
fuente

Respuestas:

170

No busca una rama, busca un control remoto completo:

git fetch origin
git merge origin/an-other-branch
Gareth
fuente
8
Más detalles: git fetch origin an-other-branchalmacena la propina recuperada FETCH_HEAD, pero no origin/an-other-branch(es decir, la "rama de seguimiento remoto" habitual). Entonces, uno podría hacerlo git fetch origin an-other-branch && git merge FETCH_HEAD, pero hacerlo como dice @Gareth es mejor (o simplemente use git pull ).
Chris Johnsen
Entonces, si el origen tiene 1000 sucursales, ¿tendría una sucursal remota para todas ellas?
Gauthier
4
Por supuesto. Si agregué un repositorio remoto con 1000 ramas al mío, y pregunto qué ramas tiene el control remoto, será mejor que me dé las 1000
Gareth
se git merge origin/an-other-branchfusionará origin/an-other-branchcon todas las sucursales locales que están configuradas para rastrearlo? ¿Cómo puedo fusionarme en una sola sucursal local?
anfibio
1
Entonces, ¿qué hace git pull(sin argumentos)? ¿Qué rama se fusiona? ¿Fusiona la rama de seguimiento remoto correspondiente a la rama actual ?
The Red Pea
69

Seleccionando solo una rama: fetch/ merge vs. pull

La gente suele aconsejarle que separe "buscar" de "fusionar". Dicen en lugar de esto:

    git pull remoteR branchB

hacer esto:

    git fetch remoteR
    git merge remoteR branchB

Lo que no mencionan es que tal comando de recuperación en realidad recuperará todas las ramas del repositorio remoto, que no es lo que hace ese comando de extracción. Si tiene miles de ramas en el repositorio remoto, pero no desea verlas todas, puede ejecutar este comando poco conocido:

    git fetch remoteR refs/heads/branchB:refs/remotes/remoteR/branchB
    git branch -a  # to verify
    git branch -t branchB remoteR/branchB

Por supuesto, eso es ridículamente difícil de recordar, por lo que si realmente desea evitar buscar todas las ramas, es mejor modificar su .git/configcomo se describe en ProGit.

¿Eh?

La mejor explicación de todo esto se encuentra en el Capítulo 9-5 de ProGit, Git Internals - The Refspec ( o vía github ). Eso es increíblemente difícil de encontrar a través de Google.

Primero, necesitamos aclarar algo de terminología. Para el seguimiento de sucursales remotas, generalmente hay 3 sucursales diferentes que debe tener en cuenta:

  1. La rama en el repositorio remoto: refs/heads/branchBdentro del otro repositorio
  2. Su sucursal de seguimiento remoto : refs/remotes/remoteR/branchBen su repositorio
  3. Tu propia rama: refs/heads/branchBdentro de tu repositorio

Las ramas de seguimiento remoto (en refs/remotes) son de solo lectura. No los modifica directamente. Modifica su propia rama y luego empuja a la rama correspondiente en el repositorio remoto. El resultado no se refleja en su refs/remoteshasta después de una extracción o recuperación adecuada. Esa distinción me resultó difícil de entender a partir de las páginas de manual de git, principalmente porque refs/heads/branchBse dice que la rama local ( ) "rastrea" la rama de seguimiento remoto cuando se .git/configdefine branch.branchB.remote = remoteR.

Piense en 'refs' como punteros de C ++. Físicamente, son archivos que contienen resúmenes SHA, pero básicamente son solo indicadores del árbol de confirmación. git fetchagregará muchos nodos a su árbol de confirmación, pero la forma en que git decide qué punteros mover es un poco complicado.

Como se menciona en otra respuesta , ninguno

    git pull remoteR branchB

ni

    git fetch remoteR branchB

se movería refs/remotes/branches/branchB, y este último ciertamente no puede moverse refs/heads/branchB. Sin embargo, ambos se mueven FETCH_HEAD. (Puede ingresar catcualquiera de estos archivos .git/para ver cuándo cambian). Y git mergese referirá a FETCH_HEAD, mientras se configura MERGE_ORIG, etc.

cdunn2001
fuente
1
¿Sabe que su enlace a Git Internals es un enlace a esta misma pregunta?
Shahbaz
9

¿Está seguro de que está en el local an-other-branchcuando se fusiona?

git fetch origin an-other-branch
git checkout an-other-branch
git merge origin/an-other-branch

La otra explicación :

todos los cambios de la rama que está intentando fusionar ya se han fusionado con la rama en la que se encuentra actualmente.
Más específicamente, significa que la rama que está intentando fusionar es un padre de su rama actual

si está por delante del repositorio remoto por una confirmación, es el repositorio remoto el que está desactualizado, no usted.

Pero en su caso, si git pullfunciona, eso solo significa que no está en la rama correcta.

VonC
fuente
3

Git pull es en realidad una herramienta combinada: ejecuta git fetch (obteniendo los cambios) y git merge (fusionándolos con su copia actual)

¿Estás seguro de que estás en la rama correcta?

RDL
fuente
Creo que el OP está en diff. rama, me pasa.
Chaklader Asfak Arefe
1

estos son los comandos:

git fetch origin
git merge origin/somebranch somebranch

si hace esto en la segunda línea:

git merge origin somebranch

intentará fusionar el maestro local en su rama actual.

La pregunta, según tengo entendido, fue que ya lo buscó localmente y ahora desea fusionar su rama con la última de la misma rama.

usuario1524957
fuente