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/config
como 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:
- La rama en el repositorio remoto:
refs/heads/branchB
dentro del otro repositorio
- Su sucursal de seguimiento remoto :
refs/remotes/remoteR/branchB
en su repositorio
- Tu propia rama:
refs/heads/branchB
dentro 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/remotes
hasta 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/branchB
se dice que la rama local ( ) "rastrea" la rama de seguimiento remoto cuando se .git/config
define 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 fetch
agregará 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 cat
cualquiera de estos archivos .git/
para ver cuándo cambian). Y git merge
se referirá a FETCH_HEAD
, mientras se configura MERGE_ORIG
, etc.
git fetch origin an-other-branch
almacena la propina recuperadaFETCH_HEAD
, pero noorigin/an-other-branch
(es decir, la "rama de seguimiento remoto" habitual). Entonces, uno podría hacerlogit fetch origin an-other-branch && git merge FETCH_HEAD
, pero hacerlo como dice @Gareth es mejor (o simplemente use git pull ).