origin - git push
¿Cómo puedo ''git fetch'' y ''git merge'' desde una Remote Tracking Branch(como ''git pull'') (5)
Seleccionar solo una rama: fetch
/ merge
frente a pull
La gente a menudo aconseja 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 dicho comando fetch realmente capturará todas las ramas del repositorio remoto, que no es lo que hace ese comando pull. Si tiene miles de sucursales en el repositorio remoto, pero no desea verlas todas, puede ejecutar este comando oscuro:
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, así que si realmente quieres evitar buscar todas las ramas, es mejor modificar tu .git/config
como se describe en ProGit.
¿Huh?
La mejor explicación de todo esto está 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 bifurcación remota, normalmente hay 3 ramas diferentes que debe tener en cuenta:
- La rama en el repositorio remoto:
refs/heads/branchB
dentro del otro repositorio - Su rama de seguimiento
refs/remotes/remoteR/branchB
en su repositorio - Su propia sucursal:
refs/heads/branchB
dentro de su repositorio
Las ramas de seguimiento remoto (en refs/remotes
) son de solo lectura. Usted no los modifica directamente. Modificas tu propia rama y luego presionas a la rama correspondiente en el repositorio remoto. El resultado no se refleja en sus refs/remotes
hasta después de un pull o fetch apropiado. Esa distinción me resultó difícil de entender en las páginas de manual de git, principalmente porque se dice que la rama local ( refs/heads/branchB
) "rastrea" la rama de seguimiento remoto cuando .git/config
define branch.branchB.remote = remoteR
.
Piense en ''refs'' como punteros C ++. Físicamente, son archivos que contienen compendios de SHA, pero básicamente solo son punteros en el árbol de commit. git fetch
agregará muchos nodos a su árbol de commits, 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
movería refs/remotes/branches/branchB
, y este último ciertamente no puede mover refs/heads/branchB
. Sin embargo, ambos mueven FETCH_HEAD
. (Puede cat
cualquiera de estos archivos dentro de .git/
para ver cuándo cambian). Y la git merge
se referirá a FETCH_HEAD
, mientras configura MERGE_ORIG
, etc.
He configurado algunas ramas de seguimiento remoto en git, pero parece que nunca puedo fusionarlas en la rama local una vez que las actualicé con ''git fetch''.
Por ejemplo, supongamos que tengo una rama remota llamada ''una-otra-rama''. Lo configuré localmente como una rama de rastreo usando
git branch --track an-other-branch origin/an-other-branch
Hasta aquí todo bien. Pero si esa rama se actualiza (generalmente yo moviendo la máquina y comprometiéndome desde esa máquina), y quiero actualizarla en la máquina original, me estoy metiendo en problemas con fetch / merge:
git fetch origin an-other-branch
git merge origin/an-other-branch
Cada vez que hago esto, recibo un mensaje ''Ya está actualizado'' y nada se funde.
Sin embargo, un
git pull origin an-other-branch
siempre lo actualiza como es de 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. ¿Debería mi ''git fetch'' seguido de ''git merge'' (como se muestra arriba) hacer exactamente lo mismo que un git pull? Obtendré un flujo de trabajo que muestra los resultados de un estado de git, etc.
¿Estás seguro de que estás en la an-other-branch
local cuando te fusionas?
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 intenta fusionar ya se han fusionado con la rama en la que se encuentra actualmente.
Más específicamente, significa que la rama que está tratando de fusionar es un padre de su rama actualSi se adelanta al repositorio remoto con una confirmación, es el repositorio remoto lo que está desactualizado, no usted.
Pero en tu caso, si funciona el git pull
, eso significa que no estás en la rama correcta.
Git pull es en realidad una herramienta combinada: ejecuta git fetch (obtener los cambios) y git merge (fusionándolos con tu copia actual)
¿Estás seguro de que estás en la rama correcta?
No busca una rama, obtiene un control remoto completo:
git fetch origin
git merge origin/an-other-branch
estos son los comandos:
git fetch origin
git merge origin/somebranch somebranch
si haces esto en la segunda línea:
git merge origin somebranch
intentará fusionar el maestro local en su rama actual.
La pregunta, como lo he entendido, es que ya fuiste a buscar localmente y ahora quieres fusionar tu sucursal con la última de la misma sucursal.