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:
- La rama en el repositorio remoto:
refs/heads/branchBdentro del otro repositorio
- Su sucursal de seguimiento remoto :
refs/remotes/remoteR/branchBen su repositorio
- 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.
git fetch origin an-other-branchalmacena 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 ).