El comando Git pull en Git


Lección 39 / 53

El comando Git pull en Git

Git Guía Git Guía Git español

Al comienzo de esta sección, vimos cómo obtener contenido nuevo de un repositorio remoto mediante el comando git fetch. Ahora veamos con más detalle cómo devolver estos cambios a la propia working copy usando el comando git pull.

Fusionar cambios del repositorio remoto al repositorio local es una tarea común en los flujos de trabajo colaborativos basados ​​en Git. El comando git pull en Git a menudo se usa para obtener y descargar contenido de un repositorio remoto y actualizar inmediatamente la working copy del repositorio local para que coincida con ese contenido.

El comando git pull en Git es, en realidad, una combinación de otros dos comandos. 

En la primera fase de la operación, git pull realizará una búsqueda de git limitada solo a la rama a la que apunta la working copy. Una vez que se haya descargado el contenido, git pull ingresará a un flujo de reconciliación de commit que puede seguir dos métodos con efectos muy diferentes.

Entendámoslo mejor con un ejemplo:

Supongamos que hemos clonado un repository remoto cuando el último commit en su branch main era el indicado como “B”. Hemos hecho modificaciones y hemos guardado en local los commit “C”, “D” y “E”. Mientras tanto, alguien más ha creado y enviado al repository remoto otros commit, “F”, “G” y “H”

 

Stato iniziale esempio merge

Estado inicial ejemplo fusión

 

En esta situación, teniendo en cuenta que el repositorio remoto es el que alberga la historia "oficial" del proyecto, tendremos que recuperar los nuevos commits remotos e integrarlos con los locales. No obstante, también tendremos que indicar la estrategia preferida con la que hacerlo.

Git, de hecho, ofrece dos formas distintas de pull/merger de ramas divergentes, con rebase o con fusión.

NOTA: en versiones recientes de Git, git pulls en ramas divergentes falla a menos que especifique la estrategia deseada. Puede hacer esto a través de argumentos de comando, pero también se puede especificar la estrategia predeterminada a través de git config.

Pull con rebase

 

Stato iniziale esempio merge

Estado inicial ejemplo merge

 

El pull con rebase es el método que, en cierto sentido, respeta el contenido del repositorio remoto como "oficial" y considera los commits en el repositorio local como commits a aplicar sobre el historial actualizado del repositorio.

Ejecutando git pull --rebase sucede lo siguiente:

  • se reservan los commit locales (C-D-E) añadidos respecto al último origin/main recuperado
  • se ejecuta el fetch que recupera los nuevos commit desde el branch main del repository remoto origin
  • los nuevos commit remotos vengono se aplican a la “copia” local origin/main y se actualiza el branch locale main y la working copy
  • los commit locales C-D-E se “reaplican”, creando entonces nuevos commit C’-D’-E’, cada uno de los cuales contiene las mismas diferencias de los commit C-D-E

Recordamos, de hecho, que un commit es un snapshot completo del estado de un repositorio, por lo que habiendo cambiado el historial antes del commit C, el commit C' contendrá las mismas "diferencias" en comparación con la snapshot anterior, pero que sea un nuevo commit.

Es posible elegir esta estrategia como predeterminada mediante el comando git config pull.rebase true

Pull con merge

 

Stato iniziale esempio merge

Estado inicial ejemplo merge

 

El otro método es el de pull with merge que, en la situación descrita, da "precedencia" al repositorio local sobre el remoto, o al menos en la situación descrita podría crear una historia aparentemente inconsistente.

Al ejecutar git pull --no-rebase de hecho, ocurre lo siguiente:

  • se ejecuta el fetch que recupera los nuevos commit del branch main del repository remoto origin
  • se cogen los commit F-G-H recuperados del repository remoto y se crea un commit especial de “merge” (I) que aplica el completo diff al branch locale
  • se pide al usuario guardar tal commit.

Al final del pull con merge, aunque estamos en una situación que desde el punto de vista de Git ya no es "divergente" (de hecho, será posible hacer git pull para enviar al repositorio remoto), el la historia del proyecto es menos comprensible y lineal.

De hecho, si vemos el historial del proyecto con git log --graph  --oneline después de hacer el push, obtendremos algo como esto:

$ git log --graph  --oneline
*   ece860f (HEAD -> main, origin/main, origin/HEAD) I - Merge branch 'main' of https://server.com/repository.git
|\
| * 09817f7 H - remote commit three
| * 1e0e1d2 G - remote commit two
| * b7d7502 F - remote commit one
* | 4d49b1c E - local commit 3
* | 6453336 D - local commit 2
* | 24540dd C - local commit 1
|/
* 9cc4eee B - another commit
* f46646d A - initial commit

Ten en cuenta que, desde un punto de vista estrictamente cronológico del repositorio remoto, la historia se ha invertido, ya que en la historia los commit F-G-H estaban, en la práctica, ya presentes antes de que se enviaran los commit C-D-E, que, sin embargo, ahora siguen directamente los commit A-B.

Aunque, por tanto, el "merge" es una actividad a veces necesaria en la gestión de la sincronización de trabajos en Git, en caso de colaborar en una rama es recomendable optar por el modo rebase.

Es posible elegir esta estrategia como default con el comando git config pull.rebase false

Guía Git en español 1 ¿Qué es Git? 2 Nacimiento de Git 3 Principales características de Git 4 Línea de comando UI en Git 5 Cómo instalar Git 6 5 comandos Git para desarrolladores individuales 7 5 comandos Git para desarrollar en colaboración 8 Repository en Git 9 Commit en Git 10 Working Copy en Git 11 Staging Area en Git 12 Branch en Git 13 Remote en Git 14 Inicializar un nuevo repository con git init 15 Crear una copia de un repository remoto en Git con git clone 16 Configurar las opciones de Git con git config 17 El comando Git add en Git 18 El comando Git commit en Git 19 El comando Git diff en Git 20 El comando Git stash en Git 21 .gitignore : los archivos ignored en Git 22 El comando Git status en Git 23 El comando Git log en Git 24 El comando Git tag en Git 25 El comando Git blame en Git 26 El comando Git checkout en Git 27 El comando Git revert en Git 28 El comando Git reset en Git 29 El comando Git rm en Git 30 La opción Git commit –amend en Git 31 Git rebase –interactive en Git 32 Atajos para comandos frecuentes en Git 33 Repository compartido en Git 34 El modelo Fork & pull 35 El comando Git remote en Git 36 Los principales repository remote de Git: Github, Gitlab y Bitbucket 37 El comando Git fetch en Git 38 El comando Git push en Git 39 El comando Git pull en Git 40 El comando Git branch en Git 41 El comando Git checkout en Git 42 El comando Git merge en Git 43 Resolver un merge conflict en Git 44 Entender mejor el contenido de los commit durante un conflicto de merge en Git 45 Workflow Git centralizado 46 Workflow Git feature branching 47 Workflow Git trunk-based 48 Enfoque “forking” en Git 49 Gitflow en Git 50 Mensajes de commit en Git 51 Tagging & Versioning en Git 52 La opción merge en Git 53 La opción rebase en Git

© 2022 Aulab. Todos los derechos reservados • P.IVA: IT07647440721 • Política de privacidad