Este repositorio está diseñado para experimentar con los conceptos clave de Git de forma práctica.
🔹 Haz un fork, clónalo y juega con las ramas.
🔹 Explora Git más allá de los comandos, entendiendo cómo funciona internamente.
📖 Basado en How to teach Git_ y Learn git concepts, not commands_.
- Conceptos Fundamentales
- Fork y Clon
- Tracked y Untracked
- El flujo de trabajo
- Añade un nuevo fichero al Repositorio
- Haciendo algunos cambios
- Trabajando con Ramas (Branches)
- Upstream, Origin y Remote
- Merge
- ¿Qué es HEAD?
- Fusionando ramas divergentes
- Generando confilctos
- Rebase
- ¿Cuándo usar rebase?
- Actualizando el Entorno de Desarrollo
- Fetch
- Pull
- Stash
- Pull con Conflictos
- Cherry-picking
Para entender Git, es clave familiarizarse con su terminología, y hacerlo en inglés, ya que todos los comandos están en ese idioma.
En este tutorial, no voy a traducir las palabras clave, así te resultará más fácil comprender los comandos y la documentación oficial.
✔️ Palabras Clave :
- Commit: Instantánea del proyecto en un momento específico.
- Branch: Puntero móvil que señala un commit en particular.
- HEAD: Indica tu posición actual en el historial de commits
✔️ Áreas Clave :
En Git trabajamos con cuatro áreas clave, tres en local y una en remoto:
- Working Directory: Carpeta donde editas y modificas los archivos.
- Staging Area: Zona donde preparas los cambios antes de hacer un commit.
- Local Repository: Almacén donde se guardan los commits en tu máquina.
- Remote Repository: Copia remota del repositorio local, accesible en un servidor
- Fork: Realiza un fork de este repositorio en tu cuenta de GitHub.
Esto creará una copia del repositorio en tu perfil.
>Encontrarás el botón para hacer fork en la parte superior derecha del repositorio.Una vez hecho el fork, vamos a clonar el repositorio desde tu perfil de GitHub a tu máquina local.
> git clone <url-de-tu-repositorio>Al ejecutar git clone, obtienes dos copias exactas del repositorio remoto en tu máquina local:
- Una en el Working Directory (donde trabajarás con los archivos).
- Otra en el Local Repository (donde se guardarán tus commits).
Además, git clone creará una carpeta nueva con el nombre del repositorio.
En tu Working Directory existen dos tipos de archivos: tracked y untracked.
- Los archivos tracked son aquellos que Git ya conoce porque han sido previamente añadidos al repositorio (ya han sido confirmados con un commit).
- Los archivos untracked son aquellos que Git no conoce porque nunca han sido añadidos al repositorio.
¡Así de fácil!
El flujo de trabajo en Git sigue este orden básico:
-
Modifica tu código en el Working Directory: Trabaja en los archivos que necesitas.
-
Añade los archivos modificados al Staging Area: Cuando termines de hacer cambios en un archivo, debes decirle a Git que lo prepare para el commit.
> git add .El punto (.) indica que añades todos los cambios realizados. Si prefieres añadir solo ciertos archivos, puedes especificar su nombre en lugar de .
- Haz un commit para guardar los cambios en tu Local Repository: Cuando estés listo para guardar tu progreso, haz un commit con un mensaje que describa lo que hiciste.
> git commit -m "tarea #1 completada"- Envía tus cambios al Remote Repository: Después de hacer el commit, es momento de subir esos cambios al repositorio remoto para que los demás puedan verlos o para guardarlos de forma segura.
> git pushEn este paso, Git sube los commits que hiciste desde tu repositorio local al repositorio remoto.
-
Crea un nuevo archivo en tu editor favorito. Recuerda que debe estar dentro de la carpeta del repositorio.
Este archivo ahora se encuentra en tu Working Directory y aún no está siendo rastreado por Git, es decir, es un archivo untracked.
-
Verifica el estado con
git status: Usa este comando para ver qué está pasando en tu entorno de desarrollo.Git te dirá qué archivos están siendo rastreados y cuáles no.
> git statusLa salida será algo similar a esto:
On branch main
Your branch is up to date with 'origin/main'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
nuevo_archivo.txt
nothing added to commit but untracked files present (use "git add" to track)Aquí, Git nos da información clave:
- Estamos en la rama main.
- Nuestra rama está actualizada con el repositorio remoto (origin/main).
- Tenemos archivos no rastreados (untracked).
- No hay archivos listos para hacer commit, pero sí archivos sin seguimiento.
- Añadir el archivo al Staging Area: Para que Git comience a rastrear el archivo, usamos el comando git add.
> git add .El punto (.) indica que queremos añadir todos los archivos modificados. Si solo deseas añadir un archivo en particular, puedes especificarlo de la siguiente manera:
git add nuevo_archivo.txt.
- Hacer un commit: Ahora que el archivo está en el Staging Area, lo pasamos al Local Repository con el comando git commit.
> git commit -m "Creado nuevo_archivo.txt"El mensaje entre comillas debe ser claro y descriptivo sobre lo que has hecho.
- Subir los cambios al Remote Repository: Una vez que el archivo está en tu Local Repository, es momento de subirlo al repositorio remoto para compartirlo o almacenarlo de forma segura en la nube.
> git pushAsegúrate de que estás conectado a un repositorio remoto. Si no lo has configurado aún, necesitarás usar git remote add para conectarlo.
Ahora que conocemos los conceptos básicos, vamos a dar un paso más.
Abre el archivo contributors.md y añade tu usuario de GitHub.
Cuando realices este cambio y ejecutes git status, verás que el archivo ha sido modificado.
> git status
On branch main
Your branch is ahead of 'origin/main' by 2 commits.
(use "git push" to publish your local commits)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: contributors.md
no changes added to commit (use "git add" and/or "git commit -a")En el mensaje de salida, podemos ver que:
- Estamos en la rama main.
- El repositorio local tiene dos commits más que el remoto.
- El archivo contributors.md ha sido modificado, pero aún no está listo para hacer commit.
Para ver las diferencias entre el archivo original y el modificado, podemos usar el comando git diff:
> git diff
diff --git a/contributors.md b/contributors.md
index e9598c3..3cf80b6 100644
--- a/contributors.md
+++ b/contributors.md
@@ -1,3 +1,3 @@
Add Your Github Username
---
-
+https://github.com/xj4v1xEl comando git diff nos muestra las líneas que han cambiado. En este caso, hemos añadido el enlace a nuestro perfil de GitHub.
Luego, para añadir este archivo al Staging Area, usamos el siguiente comando:
> git add .Si ahora ejecutas git diff nuevamente, no obtendrás ningún resultado. Esto es porque git diff solo muestra cambios que aún no han sido añadidos al Staging Area.
Sin embargo, si queremos ver los cambios que ya hemos añadido al Staging Area, usamos git diff --staged:
> git diff --staged
diff --git a/contributors.md b/contributors.md
index e9598c3..3cf80b6 100644
--- a/contributors.md
+++ b/contributors.md
@@ -1,3 +1,3 @@
Add Your Github Username
---
-
+https://github.com/xj4v1xUna vez que hemos añadido los cambios al Staging Area, podemos hacer un commit de esos cambios usando el siguiente comando:
> git commit -m "Añadido usuario xj4v1x a contributors.md"Cada commit que hacemos tiene un identificador único (un hash). Para ver el historial de commits, podemos usar el comando git log:
> git log
commit 78c857bf32df823ca7684afde54833c67dac7c00 (HEAD -> main)
Author: <your_user> <your_email>
Date: Fri Feb 7 21:44:27 2025 +0100
Añadido usuario xj4v1x a contributors.md(Para salir del log pulsa la tecla "q")
Finalmente, si quieres comparar dos commits específicos, puedes hacerlo utilizando sus respectivos hashes:
> git diff 78c857bf32df823ca7684afde54833c67dac7c00 d19163587537e335cf84aa65f209c2a91e472fa2
diff --git a/contributors.md b/contributors.md
+ index d37f8aa..79f82c8 100644
+ --- a/contributors.md
+ +++ b/contributors.md
+ @@ -1,2 +1,4 @@
+ ---
+ +https://github.com/xj4v1x
+ \ No newline at end of fileEl concepto de Rama o Branch es uno de los más poderosos y útiles de Git. Las ramas nos permiten trabajar en diferentes versiones de un proyecto sin interferir con la rama principal, como main o master.
Las ramas son como versiones paralelas de un proyecto. Son punteros que apuntan a un commit específico dentro del repositorio. La idea es que puedes hacer cambios en una rama sin afectar a la rama principal, y luego, si todo va bien, puedes combinar esos cambios en main o en otra rama.
- Crear una nueva rama: Para crear una nueva rama llamada develop desde la rama en la que estás (por ejemplo, main), ejecuta:
> git branch develop
> git checkout developO de forma más rápida con:
> git checkout -b developEsto crea una nueva rama llamada develop y automáticamente te cambia a ella.
Nota: Cuando creas una nueva rama, contiene exactamente el mismo contenido que la rama en la que estabas trabajando previamente.
-
Modificar archivos en la nueva rama: Ahora, realiza algún cambio en el archivo nuevo_archivo.txt. Este cambio puede ser una prueba o algo que no deseas que forme parte de la rama principal.
-
Añadir y hacer commit: Luego de hacer tus cambios, añades el archivo al Staging Area y haces un commit:
> git add .
> git commit -m "editado nuevo_archivo.txt"Ahora, tienes tu cambio registrado en la rama develop.
Cuando intentas hacer un git push a tu repositorio remoto, Git te mostrará un error similar al siguiente:
fatal: The current branch develop has no upstream branch.
To push the current branch and set the remote as upstream, use
> git push --set-upstream origin develop
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.Este error ocurre porque la rama develop no tiene una rama remota configurada para hacerle seguimiento (upstream branch). Git no sabe a qué rama remota debe subir tus cambios.
Solución:
Para resolver este problema, necesitamos configurar la rama remota origin como la rama de seguimiento para develop:
> git push --set-upstream origin developEste comando empuja la rama develop al repositorio remoto y la configura para que en el futuro los push se realicen automáticamente a esa rama.
En Git, upstream se refiere a la relación entre una rama local y una rama remota. Básicamente, indica de dónde obtiene y a dónde envía cambios una rama cuando ejecutas comandos como git pull o git push.
Origin es el nombre predeterminado que se le da al repositorio remoto cuando clonas un proyecto o añades un remoto por primera vez. Es simplemente un alias que apunta a la URL del repositorio remoto en GitHub o cualquier otro servicio de control de versiones.
Remote es un repositorio que está alojado en otro lugar (como GitHub). Se usa para sincronizar los cambios entre tu copia local y la versión en el servidor.
Cuando trabajas en equipo o quieres hacer copias de seguridad de tu código, Git usa remotos para enviar (push) y recibir (pull) cambios.
En resumen:
- upstream: Es el remoto que apunta al repositorio original, del cual hiciste el fork.
- origin: Es el remoto que apunta a tu fork (tu copia del repositorio en GitHub).
- remote: Cualquier repositorio remoto.
Así que podemos resolver el error anterior, haciendo
> git push --set-upstream origin develople estás diciendo a Git:
"Cuando haga git push desde la rama develop, envíalo automáticamente a origin/develop en mi fork."
Si ahora vas a GitHub y miras tu repositorio, verás que se ha creado una nueva rama llamada develop que incluye la modificación que has hecho a nuevo_archivo.txt.
En cambio si miras la rama main, te encontrarás el mismo archivo, pero sin esta modificación.
- Las ramas en Git son como versiones paralelas de tu proyecto.
- Puedes crear nuevas ramas con
git branchy cambiarte a ellas con gitcheckouto el comando abreviadogit checkout -b. - Después de hacer cambios en una nueva rama, debes hacer
commitypushpara compartir esos cambios con el repositorio remoto. - Si la rama remota aún no existe, debes configurar un "upstream" para poder hacer el push.
Cuando trabajas con ramas en Git, a menudo necesitarás fusionarlas para combinar los cambios de diferentes ramas.
Esto es lo que se conoce como un merge. Git facilita esta operación y te permite integrar los cambios de una rama en otra de manera sencilla.
Pasos para hacer un merge
- Volver a la rama principal: Para empezar, necesitas estar en la rama a la que deseas incorporar los cambios (en este caso, main). Si no estás en ella, puedes cambiarte a la rama main con el siguiente comando:
> git switch mainTambién podrías usar:
> git checkout main- Hacer el merge: Una vez en la rama main, puedes fusionar los cambios de la rama develop (o cualquier otra rama que quieras integrar). Para hacerlo, utiliza el comando
git merge:
> git merge developEsto hará que los cambios de la rama develop se integren en main. Si no hay conflictos entre las ramas, Git automáticamente realizará el merge y añadirá un nuevo commit de fusión.
¿Qué sucede después del merge?
- Si no hay conflictos: Git integrará los cambios sin problemas y te mostrará un mensaje similar a este:
Merge made by the 'recursive' strategy.En este caso, el merge ha sido exitoso sin ningún problema.
- Si hay conflictos: Si las mismas líneas de código se han editado de manera diferente en ambas ramas, Git no puede resolver automáticamente el conflicto y te pedirá que intervengas para resolverlo manualmente.
Antes del merge: Cuando te encuentras en la rama main antes de fusionarla con develop, los cambios de develop aún no se han integrado.
Después del merge: Una vez realizado el merge, los cambios de develop se han fusionado con la rama main.
- Cambiarte a la rama main con
git switch main. - Fusionar la rama develop con
git merge develop. - Si hay conflictos, resolverlos manualmente.
- Hacer commit si es necesario (Git hará el commit automáticamente si no hay conflictos).
Antes de entrar más en detalle con el merge, es importante hablar sobre un concepto esencial: HEAD.
HEAD es un puntero especial en Git que siempre señala el último commit de la rama en la que te encuentras trabajando. Es decir, HEAD apunta a la rama activa y marca el estado actual del proyecto en ese momento.
- HEAD apunta a la rama actual: Si estás en la rama main, HEAD señalará el último commit en esa rama.
- HEAD puede apuntar a un commit específico: Si haces checkout a un commit en lugar de una rama, HEAD se moverá a ese commit específico.
Cuando realizas un merge, HEAD se mueve automáticamente al último commit de la rama donde estás trabajando (en este caso, main). Esto es lo que ocurre:
- Antes del merge: HEAD está apuntando al último commit de la rama main.
- Durante el merge: Al hacer el merge de la rama develop, Git integrará los cambios en la rama main, y HEAD se actualizará para señalar el commit de fusión.
- Después del merge: HEAD apunta al nuevo commit, que refleja los cambios fusionados.
Si deseas ver dónde está apuntando HEAD en cualquier momento, puedes usar el comando git log. El commit más reciente tendrá una etiqueta HEAD junto con la rama en la que te encuentras:
> git log
commit 78c857bf32df823ca7684afde54833c67dac7c00 (HEAD -> main)Este es el commit de fusión después de un git merge.
Vamos a ir complicando un poco todo esto.
Ahora mismo HEAD está apuntando a la rama main, puedes comprobarlo ejecutando git branch, main te aparecerá en color verde y con un asterisco a su lado.
Edita y modifica nuevo_archivo.txt. Añádelo al Staging Area con git add . y realiza el commit:
> git add .
> git commit -m "modificado nuevo_archivo.txt"Ahora, cambia a la rama develop con:
> git switch developCrea un nuevo archivo, llámalo segundo_archivo.txt y escribe lo que quieras en él. Añádelo al Staging Area con:
> git add .Y realiza el commit:
> git commit -m "creado segundo_archivo.txt"Regresa de nuevo a la rama main:
> git switch mainY ejecuta:
> git merge developEsto intentará merge-ar las dos ramas, main y develop.
Si todo se ha hecho bien, Git no podrá hacer el merge de manera automática porque las ramas tienen cambios que no se pueden fusionar fácilmente, y en lugar de realizar el merge, te abrirá un editor de texto.
En el editor de la terminal sigue los siguiente pasos:
- Pulsa
ipara INSERT- Escribe el mensaje del merge (como cuando hacemos un commit)
- Presiona la tecla
ESC- Escribe (no verás nada, pero hazlo)
:wq(write&quit)- Presiona
ENTER
Con eso, habrás completado el proceso de fusión, y se habrá resuelto el conflicto entre las dos ramas.
Esto es un ejemplo clásico de cómo trabajar con ramas divergentes y manejar conflictos en Git.
Vamos a generar un conflicto en el proceso de fusión, para que veas cómo Git maneja estas situaciones.
Primero, crea una nueva rama llamada debug:
> git checkout -b debugEn esta nueva rama, edita la primera línea de nuevo_archivo.txt.
Haz todo lo necesario para el commit (con git add . y git commit -m "editada primera línea de nuevo_archivo.txt").
Regresa a la rama main:
> git switch mainY edita también la primera línea de nuevo_archivo.txt, pero escribe algo diferente.
Realiza el commit con:
> git add .
> git commit -m "editada primera línea de nuevo_archivo.txt"Ahora que ambos cambios están en diferentes ramas, intentemos fusionarlas. Ejecuta:
> git merge debugGit te mostrará un mensaje como este:
Auto-merging nuevo_archivo.txt
CONFLICT (content): Merge conflict in nuevo_archivo.txt
Automatic merge failed; fix conflicts and then commit the result.Esto indica que Git ha encontrado un conflicto en el archivo nuevo_archivo.txt y no pudo fusionarlo automáticamente.
Abre nuevo_archivo.txt en un editor de texto, como VSCode. Verás algo como esto:
<<<<<<< HEAD
Texto editado en la rama main.
=======
Texto editado en la rama debug.
>>>>>>> debugGit ha marcado el conflicto con los delimitadores <<<<<<<, =======, y >>>>>>>. Esto te indica qué cambios provienen de la rama main (antes de =======) y qué cambios provienen de la rama debug (después de =======).
Ahora te toca decidir qué cambios conservar. Puedes:
- Eliminar los delimitadores (<<<<<<<, =======, >>>>>>>) y dejar solo una de las versiones o fusionarlas manualmente.
- Una vez que hayas decidido, guarda el archivo.
Cuando hayas solucionado el conflicto, verás este mensaje en la terminal:
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)Finalmente, para terminar el proceso, ejecuta:
> git commitEsto completará el merge con los conflictos ya resueltos.
Si, en algún momento, decides que no quieres hacer el merge, puedes usar:
> git merge --abortEsto deshará el merge y dejará tu repositorio como estaba antes de intentar fusionar las ramas.
El rebase es otra manera de integrar cambios entre ramas, pero tiene un comportamiento distinto al del merge.
A diferencia de merge, que crea un nuevo commit para combinar las ramas, el rebase reescribe el historial de commits para hacer que los cambios parezcan haberse realizado directamente sobre la rama base.
Vamos a ver cómo funciona con un ejemplo:
Paso 1: Creando las ramas
Primero, sitúate en la rama main y crea una nueva rama llamada testing-rebase:
> git checkout main
> git checkout -b testing-rebasePaso 2: Realizando un cambio en testing-rebase
En testing-rebase, crea un nuevo archivo llamado rebase_test.txt y añade algo de texto.
Después de agregar el archivo, haz el commit:
> git add rebase_test.txt
> git commit -m "Añadido rebase_test.txt"Paso 3: Regresando a main
Ahora, cambia de nuevo a la rama main:
> git switch mainEn main, edita el archivo nuevo_archivo.txt y añade algo de texto. Haz el commit:
> git add nuevo_archivo.txt
> git commit -m "Modificado nuevo_archivo.txt"Paso 4: Realizando el Rebase
Ahora vuelve a la rama testing-rebase:
> git switch testing-rebaseY ejecuta el comando para hacer el rebase:
> git rebase mainVerás el siguiente mensaje si todo ha ido bien:
Successfully rebased and updated refs/heads/testing-rebase.La diferencia principal entre merge y rebase es que, con merge, Git crea un nuevo commit de combinación para unificar los cambios, mientras que con rebase, se reescribe el historial para que parezca que los cambios de la rama testing-rebase ocurrieron después de los cambios en main.
- Con merge: el commit de combinación aparece en el historial.
- Con rebase: los cambios de la rama testing-rebase se aplican directamente sobre el historial de main, sin crear un commit de combinación.
Aquí una imagen que muestra la diferencia entre ambos métodos:
Usando merge
Usando rebase
El rebase es útil para mantener un historial limpio y lineal, sin commits de merge innecesarios.
Es comúnmente usado antes de fusionar una rama de características (feature-branch) a main para asegurar que los cambios de la rama base estén aplicados sobre la rama de características.
🚨 Precaución al usar rebase
No es recomendable usar rebase cuando se trabaja con otros desarrolladores en la misma rama, porque al reescribir el historial de commits, podrías generar conflictos difíciles de resolver.
Ahora, vamos a simular que más personas están trabajando en el repositorio.
Esto es muy común cuando trabajamos en proyectos colaborativos, donde se realizan cambios constantemente.
Para ello, vamos a simular que otra persona (en este caso, seremos nosotros mismos) ha modificado el repositorio de forma remota.
Paso 1: Modificación desde GitHub
- Accede al repositorio en GitHub.
- Dirígete al archivo nuevo_archivo.txt.
- Realiza una modificación en este archivo, por ejemplo, añadiendo una línea o cambiando el contenido.
- Crea una nueva rama llamada fetch_test para realizar este cambio.
- Haz el commit de los cambios en esta nueva rama.
Paso 2: Actualizando el Repositorio Local
Una vez hayas realizado estos cambios en GitHub, necesitamos traer esos cambios a tu entorno de desarrollo local para mantener todo sincronizado.
- Abre la terminal en tu repositorio local.
- Ejecuta el siguiente comando para obtener los cambios remotos:
> git fetch originEste comando no fusiona los cambios de forma automática, solo descarga las actualizaciones del repositorio remoto.
Paso 3: Fusionando los Cambios
Ahora que has traído los cambios, puedes integrarlos en tu rama actual. Si estás trabajando en main y quieres traer los cambios de la rama fetch_test, deberías hacer lo siguiente:
- Cambia a la rama main (si no lo estás ya):
> git switch main- Haz un merge de los cambios desde fetch_test:
> git merge origin/fetch_testEsto integrará los cambios de la rama remota fetch_test en tu rama local main.
Resumen
git fetchsolo descarga los cambios del repositorio remoto.- Para integrar los cambios en tu rama actual, utiliza
git mergeogit rebase(dependiendo de lo que prefieras hacer).
Como mencionaba antes, cuando usas git push, estás enviando tus cambios locales al repositorio remoto para sincronizarlos.
Pero si queremos lo opuesto, es decir, obtener los cambios realizados por otros en el repositorio remoto, utilizamos git fetch.
¿Qué hace git fetch?
git fetch trae los cambios del repositorio remoto a tu repositorio local.
Sin embargo, no integra esos cambios en tu espacio de trabajo ni en el área de preparación (Staging Area). Simplemente los descarga y los pone a disposición para que puedas revisarlos e integrarlos manualmente cuando decidas hacerlo.
Ejecuta el siguiente comando para obtener los cambios más recientes desde el repositorio remoto:
> git fetchEste comando descargará todas las actualizaciones, incluidas las nuevas ramas creadas, pero no modificará tu directorio de trabajo ni las ramas locales.
Después de ejecutar git fetch, si deseas ver las diferencias entre tu rama local y la rama remota, puedes usar el siguiente comando para comparar:
> git diff main origin/mainEsto te permitirá revisar qué diferencias existen entre tu rama local main y la main remota antes de fusionarlas.
Después de hacer un fetch, los cambios remotos están disponibles en tu repositorio local, pero no se integrarán en tu espacio de trabajo o en el área de preparación.
Para hacerlo, puedes usar git merge o git rebase dependiendo de la estrategia que prefieras:
- Para fusionar la rama remota en tu rama actual:
> git merge origin/main- O si prefieres hacer un rebase:
> git rebase origin/mainResumen
git fetchtrae los cambios del repositorio remoto, pero no los integra en tu espacio de trabajo ni en tu área de preparación.- Después de
git fetch, puedes revisar las diferencias entre las ramas locales y remotas antes de fusionarlas o hacer un rebase.
Cuando estás trabajando con git pull, básicamente estás combinando dos operaciones: git fetch (para obtener los cambios del repositorio remoto) y git merge (para integrar esos cambios en tu rama local).
Sin embargo, git pull puede encontrar problemas si tienes cambios locales no confirmados que pueden entrar en conflicto con los cambios remotos.
Cuando tienes modificaciones en tus archivos locales que aún no has confirmado (no has hecho commit), y tratas de hacer un git pull, Git te mostrará un error similar al siguiente:
> git pull
Updating c6911bb..c6a925c
error: Your local changes to the following files would be overwritten by merge:
nuevo_archivo.txt
Please commit your changes or stash them before you merge.
Aborting
Este error significa que git ha detectado que tus archivos locales han sido modificados, y esos cambios entrarían en conflicto con los cambios que se están trayendo desde el repositorio remoto.
Git bloquea la operación para evitar sobrescribir tus cambios locales sin que tú lo desees.
- Confirma tus cambios locales (hacer commit)
Si quieres conservar tus cambios locales, primero debes confirmarlos antes de realizar el git pull. Usa los siguientes comandos:
> git add .
> git commit -m "Mis cambios locales"Después de hacer el commit, puedes hacer git pull sin problemas.
- Usa
git stashpara guardar temporalmente tus cambios
Si no quieres hacer commit de tus cambios locales todavía, pero necesitas obtener los cambios remotos, puedes guardar temporalmente tus cambios con git stash.
Esto guarda tus modificaciones no confirmadas en un "almacén temporal" y deja tu espacio de trabajo limpio.
Después de hacer el git pull, puedes recuperar tus cambios con git stash pop.
> git git stash
> git pull
> git stash pop- Rechazar tus cambios locales y sobrescribirlos con los remotos
Si prefieres descartar tus cambios locales y reemplazarlos completamente con los cambios del repositorio remoto, puedes restablecer tu espacio de trabajo con:
> git git reset --hard
> git pull Resumen
git pullintenta combinar los cambios remotos con tus cambios locales.- Si tienes cambios no confirmados en archivos que también han sido modificados en el repositorio remoto, Git bloqueará la operación.
- Para resolverlo, puedes:
- Confirmar tus cambios locales con
git commit. - Guardar temporalmente tus cambios con
git stashy luego hacergit pull. - Rechazar tus cambios locales con
git reset --hardsi no te importan los cambios locales.
- Confirmar tus cambios locales con
El comando git stash es súper útil cuando estás trabajando en algo y necesitas hacer una operación (como un git pull o cambiar de rama) sin perder los cambios que has realizado, pero que aún no están listos para ser confirmados (sin hacer commit).
Es como una "caja" donde puedes guardar temporalmente tu trabajo, de modo que tu espacio de trabajo quede limpio y puedas hacer otras tareas.
Una vez hayas terminado, puedes recuperar esos cambios y seguir trabajando en ellos.
Cómo usar git stash
- Guardar cambios con
git stash
Para guardar tus cambios no confirmados (en el Working Directory y el Staging Area), puedes ejecutar el siguiente comando:
> git stashEsto guardará tus cambios en un "almacén temporal" y dejará tu repositorio local como si no hubieras hecho ningún cambio aún. El comando te mostrará un mensaje similar a este:
Saved working directory and index state WIP on main: c6911bb img- Realizar el
git pull
Ahora que tu espacio de trabajo está limpio, puedes continuar con las operaciones que necesites hacer, como por ejemplo:
> git pullEsto traerá los cambios del repositorio remoto sin conflicto, ya que tu espacio de trabajo está limpio.
- Recuperar los cambios guardados con
git stash pop
Una vez que hayas completado lo que necesitabas hacer (como el git pull), puedes recuperar tus cambios guardados con:
> git stash popEsto recupera los cambios guardados y los aplica nuevamente a tu espacio de trabajo. Sin embargo, si los cambios remotos han modificado los mismos archivos que tú modificaste, es posible que se generen conflictos que deberás resolver manualmente.
- Abre los archivos con conflictos (por ejemplo, en VSCode) y resuelve las discrepancias.
- Una vez resueltos, añade los cambios con
git add .y haz un commit de los mismos.
- Confirmar los cambios
Cuando hayas resuelto los conflictos, agrega los archivos modificados y confirma los cambios con:
> git add .
> git commit -m "Resuelto conflicto después de stash"Resumen:
git stashguarda tus cambios locales temporalmente sin necesidad de hacer commit.- Puedes hacer otras operaciones (como
git pull,git merge, etc.) sin que tus cambios locales interfieran. - Para recuperar los cambios guardados, usa
git stash pop. - Si hay conflictos al recuperar los cambios, resuélvelos y haz un commit de las modificaciones.
Cuando hay cambios conflictivos tanto en el repositorio local como en el remoto, git pull se convierte en una operación algo más complicada.
Este caso es común cuando diferentes personas (o tú mismo) modifican los mismos archivos en ambas ubicaciones, y git no sabe cómo integrarlos automáticamente.
- Simulación de conflicto en GitHub:
- Regresa a GitHub y modifica nuevo_archivo.txt nuevamente (puedes cambiar la misma línea que modificaste antes o agregar algo distinto).
- Haz un commit de ese cambio.
- Traer los cambios con git fetch:
- Vuelve a tu terminal y ejecuta:
> git fetch - Esto traerá los cambios del repositorio remoto al repositorio local, pero sin integrarlos aún. Si ejecutas
git status, verás un mensaje como el siguiente:
> git status
On branch fetch_test
Your branch and 'origin/fetch_test' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" if you want to integrate the remote branch with yours)Este mensaje indica que tu rama local y la rama remota tienen diferentes commits y ahora hay que fusionarlos.
- Resolver el conflicto con git pull: Ahora tienes dos opciones para integrar los cambios:
- Usar
git pull(por defecto, con merge): Esto fusionará los cambios de la rama remota con tu rama local, generando un commit de merge.
> git pull Esto podría generar un conflicto si ambas ramas han modificado el mismo archivo, y tendrás que resolverlo manualmente.
- Usar
git pull --rebase: En lugar de hacer un merge, congit pull --rebase(git pull -r), los cambios remotos se integran en tu rama local de forma que parezca que tus cambios locales ocurrieron después de los cambios remotos. Este enfoque mantiene un historial más limpio y lineal sin commits de merge innecesarios.
> git pull --rebase- Resolver el conflicto: Si al ejecutar
git pull(ogit pull --rebase) surge un conflicto, Git te notificará que hay problemas al fusionar los archivos. Lo que tienes que hacer ahora es:
- Abrir el archivo con conflictos, en este caso nuevo_archivo.txt.
- Git marcará las secciones conflictivas de la siguiente forma:
<<<<<<< HEAD
(tu versión local del archivo)
=======
(la versión remota del archivo)
>>>>>>> (commit remoto)- Elige cómo resolver el conflicto: puedes conservar una de las versiones o combinar las dos.
- Elimina las marcas (<<<<<<<, =======, >>>>>>) después de haber resuelto el conflicto.
- Finalizar la operación: Una vez que hayas resuelto el conflicto:
- Añade los archivos modificados al área de staging:
> git add nuevo_archivo.txt- Si hiciste un merge, confirma el merge con:
> git commit -m "Resuelto conflicto entre la rama local y remota"- Si hiciste un rebase, continúa el rebase con:
> git rebase --continueEsto resolverá el conflicto y finalizará el proceso de integración.
Resumen:
git fetchsolo trae los cambios remotos sin integrarlos en tu espacio de trabajo.git pull(con o sin--rebase) es lo que realmente fusiona los cambios locales y remotos. El--rebasees preferible para mantener un historial limpio.- Si hay conflictos, tendrás que resolverlos manualmente.
- Una vez resuelto el conflicto, confirma los cambios.
El comando git cherry-pick es una herramienta muy útil cuando necesitas tomar un commit específico de otra rama y aplicarlo a la rama en la que estás trabajando, sin necesidad de fusionar toda la rama.
Esto te permite mantener el historial limpio y sólo incluir los cambios que realmente necesitas.
Cómo usar git cherry-pick
Supongamos que tienes dos ramas:
- main
- feature-branch
Y supongamos que en feature-branch hay un commit que quieres aplicar a main, pero no quieres fusionar toda la rama feature-branch con main.
- Identificar el commit que quieres traer:
Primero, tienes que encontrar el hash del commit que quieres traer. Puedes usar:
> git logEsto te mostrará todos los commits en la rama actual con sus hashes. Identifica el hash del commit que deseas aplicar.
- Ir a la rama de destino:
Cambia a la rama en la que quieres aplicar el commit, por ejemplo, main:
> git checkout main- Aplicar el commit con cherry-pick:
Ahora, aplica el commit de feature-branch a main usando el hash del commit que encontraste:
> git cherry-pick <commit-hash>Ejemplo:
> git cherry-pick abc1234Esto aplicará el commit abc1234 de feature-branch a main.
- Resolver conflictos (si los hay):
Si el commit que estás aplicando entra en conflicto con el contenido de la rama de destino, Git te notificará. Deberás resolver el conflicto de manera similar a como lo harías con un merge o rebase.
- Resuelve los conflictos en los archivos afectados.
- Añade los archivos resueltos al área de staging con:
> git add <archivo>- Continúa el proceso con:
> git cherry-pick --continueSi no hay conflictos, el commit se aplicará automáticamente.
- Confirmar el cherry-pick:
Si todo va bien, el commit se aplicará y se añadirá al historial de la rama de destino. No necesitas hacer un nuevo commit, ya que git cherry-pick lo hace automáticamente por ti.
- Aplicar un cambio específico de otra rama: Si estás trabajando en una rama y necesitas un cambio específico de otra rama sin querer traer toda su historia, puedes usar
git cherry-pick. - Corregir errores: Imagina que tienes un error en producción y el arreglo se encuentra en una rama de desarrollo. Puedes usar
git cherry-pickpara aplicar solo ese commit de corrección a la rama de producción. - Recuperar commits perdidos: Si accidentalmente borraste una rama pero el commit sigue en el historial (por ejemplo, en el repositorio remoto o en otras ramas), puedes usar
git cherry-pickpara recuperar ese commit.
Imagina que en tu rama feature-branch tienes este historial:
* abc1234 - Mejoras en el diseño de la interfaz
* def5678 - Añadida nueva funcionalidad
* ghi9876 - Corrección de un error críticoY en tu rama main tienes el siguiente historial:
* jkl3456 - Actualización de documentación
* mno6789 - Cambios menoresSi deseas aplicar el commit ghi9876 (la corrección de error crítico) de feature-branch a main, harías lo siguiente:
- Cambiar a main:
> git checkout main- Hacer el cherry-pick:
> git cherry-pick ghi9876Esto aplicará la corrección de ghi9876 a la rama main sin traer los demás commits de feature-branch.
- Control total sobre qué cambios se aplican de otras ramas.
- Mantiene el historial limpio si solo necesitas ciertos cambios sin toda la rama.
- Es muy útil para hotfixes (arreglos rápidos en producción).















