Si escribes código, administras servidores o trabajas con cualquier tipo de archivos de texto, Git es la herramienta que transformará tu forma de trabajar. Creado en 2005 por Linus Torvalds —el mismo creador de Linux— en apenas diez días de desarrollo febril, Git se ha convertido en el estándar absoluto del control de versiones: según las encuestas de Stack Overflow, más del 94 % de los desarrolladores profesionales lo utilizan a diario. Esta guía te llevará desde la instalación hasta los flujos de trabajo profesionales, con ejercicios prácticos en cada sección para que consolides lo aprendido en tu propia terminal Linux.
🔀 ¿Qué es Git?
Git es un sistema de control de versiones distribuido (DVCS, por sus siglas en inglés). Esa definición contiene dos ideas clave que conviene desgranar. Primero, «control de versiones»: Git registra cada cambio que se produce en los archivos de un proyecto, guardando una foto completa (snapshot) del estado del proyecto en cada punto que el usuario decide marcar. Esto permite retroceder a cualquier versión anterior, comparar diferencias entre dos momentos y entender quién cambió qué y por qué.
Segundo, «distribuido»: a diferencia de sistemas anteriores como CVS o Subversion, donde existía un único servidor central que almacenaba toda la historia, en Git cada desarrollador posee una copia completa del repositorio en su propia máquina. Esto tiene consecuencias enormes: se puede trabajar sin conexión a internet, las operaciones son extraordinariamente rápidas porque se ejecutan en local, y no existe un punto único de fallo. Si el servidor principal se cae, cualquier copia local contiene toda la historia del proyecto.
Git gestiona los datos de una manera radicalmente distinta a otros sistemas. En lugar de almacenar las diferencias entre versiones sucesivas de cada archivo (lo que se conoce como «deltas»), Git almacena snapshots completos. Cada vez que se confirma un cambio (commit), Git toma una foto del estado de todos los archivos. Si un archivo no ha cambiado, Git no lo duplica, sino que crea un enlace al archivo idéntico ya almacenado. Esta arquitectura, combinada con el uso intensivo de hashing SHA-1 para verificar la integridad de los datos, hace que Git sea extraordinariamente fiable y eficiente.
📜 Una historia de necesidad: de BitKeeper a Git
Para entender por qué existe Git, hay que remontarse a los orígenes del desarrollo colaborativo del kernel Linux. Durante la primera década del proyecto (1991-2002), Linus Torvalds gestionaba las contribuciones de cientos de desarrolladores de una manera sorprendentemente artesanal: los colaboradores enviaban sus parches por correo electrónico a una lista de distribución, y Linus los aplicaba manualmente a su copia del código fuente. No utilizaba ningún sistema de control de versiones porque, sencillamente, ninguno de los disponibles cumplía sus requisitos de velocidad y escalabilidad para un proyecto del tamaño del kernel.
En 2002, el proyecto Linux adoptó BitKeeper, un sistema de control de versiones propietario pero potente, que ofrecía licencias gratuitas para proyectos de código abierto. BitKeeper introdujo a los desarrolladores del kernel en las ventajas del control de versiones distribuido, y durante tres años la colaboración se volvió significativamente más eficiente. Sin embargo, la relación era tensa: una parte importante de la comunidad del software libre rechazaba que el proyecto insignia del código abierto dependiese de una herramienta propietaria.
La crisis estalló en abril de 2005. Andrew Tridgell, creador de Samba y del algoritmo rsync, intentó realizar ingeniería inversa de los protocolos de red de BitKeeper para crear una alternativa libre. Larry McVoy, director de BitMover (la empresa detrás de BitKeeper), había advertido repetidamente que revocaría las licencias gratuitas si alguien intentaba algo así, y cumplió su amenaza. De la noche a la mañana, los desarrolladores del kernel se quedaron sin su herramienta de trabajo.
Linus Torvalds evaluó las alternativas libres disponibles —Monotone, GNU Arch, Darcs, Bazaar— y ninguna satisfacía sus necesidades. Así que decidió construir su propia herramienta. Sus requisitos eran claros y ambiciosos: el sistema debía ser distribuido, debía ser extraordinariamente rápido (las operaciones de parcheado tenían que completarse en fracciones de segundo), debía poder manejar proyectos de gran escala (el kernel tenía ya millones de líneas de código), y debía garantizar la integridad absoluta de los datos mediante hashing criptográfico.
El 7 de abril de 2005, Linus realizó el primer commit de Git, un commit que fue registrado con la propia herramienta —Git era ya lo suficientemente funcional como para gestionarse a sí mismo. En apenas diez días había construido un prototipo operativo. El 16 de abril, solo nueve días después, Git ya se utilizaba para gestionar el desarrollo del kernel Linux. Torvalds mantuvo el proyecto durante apenas cuatro meses antes de transferir la responsabilidad a Junio C. Hamano, quien sigue siendo el mantenedor principal del proyecto veinte años después.
Lo que empezó como una solución urgente a un problema personal se transformó en una revolución. La fundación de GitHub en 2008 (ahora propiedad de Microsoft) aceleró la adopción masiva de Git al ofrecer alojamiento gratuito de repositorios con una interfaz web intuitiva. Hoy, Git es el sistema de control de versiones más utilizado en la historia de la informática.
⚙️ Instalar y configurar Git en Linux
Git viene preinstalado en muchas distribuciones Linux, pero conviene asegurarse de tener la versión más reciente. La instalación varía según la familia de tu distribución:
# Debian / Ubuntu / Linux Mint
sudo apt update
sudo apt install git
# Fedora / RHEL / CentOS (9+)
sudo dnf install git
# Arch Linux / Manjaro
sudo pacman -S git
# openSUSE
sudo zypper install git
# Verificar la versión instalada
git --version
# Ejemplo de salida: git version 2.43.0
Una vez instalado, el primer paso absolutamente imprescindible es configurar tu identidad. Git incluye esta información en cada commit que realices, y no se puede confirmar ningún cambio sin haberla establecido:
# Configuración global (se aplica a todos tus repositorios)
git config --global user.name "Tu Nombre Completo"
git config --global user.email "tu.email@ejemplo.com"
# Configurar el editor por defecto (nano, vim, code...)
git config --global core.editor "nano"
# Configurar el nombre de la rama por defecto (recomendado: main)
git config --global init.defaultBranch main
# Activar colores en la terminal para mejor legibilidad
git config --global color.ui auto
# Ver toda la configuración actual
git config --list
--system (todo el sistema, en /etc/gitconfig), --global (tu usuario, en ~/.gitconfig), y --local (solo el repositorio actual, en .git/config). Cada nivel sobreescribe al anterior, por lo que puedes tener una identidad diferente para proyectos personales y profesionales configurando --local en los repositorios que lo requieran.
Una configuración adicional muy recomendable en Linux es establecer el almacenamiento de credenciales para que no tengas que escribir tu usuario y contraseña de GitHub/GitLab en cada operación de push o pull:
# Almacenar credenciales en caché durante 1 hora (3600 segundos)
git config --global credential.helper 'cache --timeout=3600'
# O almacenarlas permanentemente en disco (menos seguro)
git config --global credential.helper store
# Opción recomendada: usar SSH en lugar de HTTPS
ssh-keygen -t ed25519 -C "tu.email@ejemplo.com"
# Luego añade la clave pública (~/.ssh/id_ed25519.pub) a GitHub/GitLab
🧠 Conceptos fundamentales: el modelo Git
Antes de empezar a ejecutar comandos, es crucial entender el modelo mental de Git. Git organiza el trabajo en tres áreas principales que todo archivo puede recorrer:
El Working Directory (directorio de trabajo) es simplemente la carpeta de tu proyecto. Aquí es donde editas archivos con tu editor favorito: VS Code, Vim, Nano o cualquier otro. Git observa esta carpeta y detecta qué archivos han cambiado, pero no registra esos cambios automáticamente.
El Staging Area (área de preparación, también llamada «index») es una zona intermedia donde seleccionas qué cambios formarán parte del próximo commit. Esta etapa intermedia es una de las características más potentes de Git: te permite preparar commits atómicos y limpios, eligiendo exactamente qué cambios incluir, incluso si has modificado muchos archivos a la vez.
El Repository (repositorio, la carpeta oculta .git/) almacena el historial completo del proyecto. Cada commit es una snapshot inmutable, identificada por un hash SHA-1 de 40 caracteres. Una vez que un commit está en el repositorio, es prácticamente permanente e inmutable: Git garantiza su integridad.
Además de estas tres áreas locales, existe el concepto de repositorio remoto: un servidor donde se almacena una copia del proyecto para colaborar con otros desarrolladores. Los comandos git push, git pull y git fetch sincronizan tu repositorio local con el remoto.
🚀 Tu primer repositorio paso a paso
Vamos a crear un repositorio desde cero y realizar las operaciones fundamentales. Abre tu terminal y sigue cada paso:
# 1. Crear un directorio para el proyecto
mkdir mi-proyecto-git
cd mi-proyecto-git
# 2. Inicializar un repositorio Git
git init
# Salida: Initialized empty Git repository in /home/usuario/mi-proyecto-git/.git/
# 3. Crear un archivo
echo "# Mi primer proyecto con Git" > README.md
echo "Este proyecto es un ejemplo para aprender Git en Linux." >> README.md
# 4. Ver el estado del repositorio
git status
# Verás: Untracked files: README.md (Git lo ve pero no lo rastrea aún)
# 5. Añadir el archivo al staging area
git add README.md
# O para añadir todos los archivos: git add .
# 6. Confirmar los cambios (crear un commit)
git commit -m "feat: crear README inicial del proyecto"
# Salida: [main (root-commit) a1b2c3d] feat: crear README inicial del proyecto
# 1 file changed, 2 insertions(+)
# 7. Ver el historial de commits
git log --oneline
# Salida: a1b2c3d feat: crear README inicial del proyecto
Acabas de realizar el flujo más básico de Git: editar → añadir al staging → confirmar con un commit. Este ciclo se repetirá miles de veces a lo largo de cualquier proyecto. Cada commit es un punto de restauración al que puedes volver en cualquier momento.
tipo: descripción. Los tipos comunes son feat (nueva funcionalidad), fix (corrección de bug), docs (documentación), refactor (reestructuración sin cambiar funcionalidad) y chore (tareas de mantenimiento).
Ampliemos el ejemplo con operaciones cotidianas adicionales:
# Crear más archivos
echo "console.log('Hola desde Git');" > app.js
echo "body { margin: 0; }" > estilos.css
# Ver qué ha cambiado (diferencias)
git diff
# Muestra las diferencias de archivos modificados respecto al último commit
# Añadir solo un archivo específico al staging
git add app.js
# Confirmar solo app.js (estilos.css queda fuera de este commit)
git commit -m "feat: añadir punto de entrada JavaScript"
# Ahora añadir y confirmar estilos.css
git add estilos.css
git commit -m "style: añadir hoja de estilos base"
# Ver el historial completo con gráfico
git log --oneline --graph --all
# * c3d4e5f style: añadir hoja de estilos base
# * b2c3d4e feat: añadir punto de entrada JavaScript
# * a1b2c3d feat: crear README inicial del proyecto
🌿 Ramas: el superpoder de Git
Las ramas son, probablemente, la característica más revolucionaria de Git y la razón principal de su éxito frente a sistemas anteriores. Una rama en Git es simplemente un puntero ligero a un commit específico. Crear una rama nueva no copia archivos ni consume espacio significativo: es una operación instantánea.
Las ramas permiten trabajar en funcionalidades nuevas, correcciones de bugs o experimentos en un entorno aislado, sin afectar al código estable de la rama principal. Cuando el trabajo en una rama está terminado y probado, se fusiona (merge) con la rama principal.
# Ver las ramas existentes (el * indica la rama activa)
git branch
# * main
# Crear una nueva rama y cambiar a ella
git checkout -b feature/login
# Equivalente moderno: git switch -c feature/login
# Ahora estás en la rama feature/login
git branch
# * feature/login
# main
# Hacer cambios en esta rama
echo "function login(user, pass) { /* TODO */ }" > login.js
git add login.js
git commit -m "feat: crear módulo de login (esqueleto)"
# Añadir más commits a la rama
echo "function validateEmail(email) { return email.includes('@'); }" >> login.js
git add login.js
git commit -m "feat: añadir validación de email al login"
# Volver a la rama principal
git checkout main
# Equivalente moderno: git switch main
# Observa: login.js NO existe en main. Los cambios están aislados
ls
# README.md app.js estilos.css
# Listar todas las ramas con información extra
git branch -v
# * main c3d4e5f style: añadir hoja de estilos base
# feature/login f7g8h9i feat: añadir validación de email al login
Las convenciones más habituales para nombrar ramas siguen un patrón de prefijo que indica el propósito: feature/nombre para nuevas funcionalidades, bugfix/nombre o fix/nombre para correcciones, hotfix/nombre para correcciones urgentes en producción, y release/version para preparar versiones de lanzamiento.
🔀 Fusiones, rebases y resolución de conflictos
Una vez que has completado el trabajo en una rama, necesitas integrar esos cambios en la rama principal. Git ofrece dos estrategias principales: merge y rebase.
Merge: fusión preservando la historia
# Asegurarse de estar en la rama destino (main)
git checkout main
# Fusionar la rama feature/login en main
git merge feature/login
# Si no hay conflictos: Fast-forward o Merge commit automático
# Ahora login.js existe también en main
ls
# README.md app.js estilos.css login.js
# Eliminar la rama ya fusionada (limpieza)
git branch -d feature/login
Si ambas ramas han modificado las mismas líneas del mismo archivo, Git no puede fusionar automáticamente y genera un conflicto. En ese caso, Git marca las secciones conflictivas en el archivo y es tu responsabilidad resolverlas:
# Ejemplo de archivo con conflicto
cat archivo_conflictivo.js
# <<<<<<< HEAD
# console.log("Versión de main");
# =======
# console.log("Versión de la rama feature");
# >>>>>>> feature/mi-cambio
# Para resolverlo:
# 1. Edita el archivo: elige qué versión conservar (o combina ambas)
# 2. Elimina los marcadores <<<<<<<, =======, >>>>>>>
# 3. Guarda el archivo
# Después de resolver:
git add archivo_conflictivo.js
git commit
# Git abre el editor con un mensaje de merge predeterminado
Rebase: reescribir la historia para un historial lineal
El rebase es la alternativa elegante al merge. En lugar de crear un commit de fusión, rebase toma los commits de tu rama y los «replanta» sobre la punta de la rama destino, como si siempre hubieras trabajado a partir de la última versión de main:
# Estando en tu rama de trabajo
git checkout feature/api
# Rebasar sobre main
git rebase main
# Cada commit de feature/api se reaplicará sobre el último commit de main
# Luego, volver a main y hacer fast-forward merge
git checkout main
git merge feature/api
# El resultado es un historial completamente lineal
git push). El rebase reescribe los hashes de los commits, y si otros desarrolladores ya están trabajando sobre esos commits, se producirá un caos de conflictos. Usa rebase solo para limpiar tu historia local antes de compartirla.
☁️ Repositorios remotos: GitHub, GitLab y más
Hasta ahora hemos trabajado exclusivamente en local. Para colaborar con otros desarrolladores o simplemente tener una copia de seguridad en la nube, necesitas un repositorio remoto. Las plataformas más populares son GitHub (propiedad de Microsoft), GitLab (disponible como servicio y autoalojable) y Bitbucket (de Atlassian, integrado con Jira).
# Conectar tu repositorio local con uno remoto (ejemplo con GitHub)
git remote add origin git@github.com:tu-usuario/mi-proyecto-git.git
# Verificar los remotos configurados
git remote -v
# origin git@github.com:tu-usuario/mi-proyecto-git.git (fetch)
# origin git@github.com:tu-usuario/mi-proyecto-git.git (push)
# Subir tu rama main al remoto por primera vez
git push -u origin main
# -u (--set-upstream) vincula tu rama local con la remota
# A partir de ahora, basta con: git push
# Descargar cambios del remoto
git pull
# Equivale a: git fetch + git merge
# Clonar un repositorio existente (la forma más habitual de empezar)
git clone git@github.com:torvalds/linux.git
# Descarga todo el repositorio con su historial completo
El flujo colaborativo típico con un repositorio remoto sigue este patrón: clonar el proyecto → crear una rama local para tu cambio → hacer commits → subir la rama al remoto con push → abrir un Pull Request (GitHub) o Merge Request (GitLab) → el equipo revisa el código → si se aprueba, se fusiona a la rama principal → actualizar tu copia local con pull.
Diferencias clave entre las plataformas
| Característica | GitHub | GitLab | Bitbucket |
|---|---|---|---|
| Propietario | Microsoft | GitLab Inc. | Atlassian |
| Repos privados gratis | ✅ Ilimitados | ✅ Ilimitados | ✅ Hasta 5 usuarios |
| CI/CD integrado | GitHub Actions | GitLab CI (nativo) | Bitbucket Pipelines |
| Autoalojable | GitHub Enterprise | ✅ GitLab CE (gratis) | Bitbucket Server |
| Integración principal | VS Code, Copilot | DevOps completo | Jira, Confluence |
| Comunidad open source | La más grande | Creciendo rápido | Menor |
🔄 Flujos de trabajo profesionales
En equipos de desarrollo profesional, no se trabaja directamente sobre la rama main. Se utilizan flujos de trabajo (workflows) que estructuran cómo se crean, revisan e integran los cambios. Los más extendidos son:
GitHub Flow (el más simple y popular)
Solo dos tipos de ramas: main (siempre desplegable en producción) y ramas de trabajo (feature branches). El flujo es: crear rama → hacer commits → abrir Pull Request → revisión del equipo → merge a main → desplegar. Su simplicidad lo hace ideal para proyectos web y aplicaciones con despliegue continuo.
GitFlow (el más estructurado)
Define cinco tipos de ramas: main (producción), develop (desarrollo), feature/* (nuevas funcionalidades), release/* (preparación de versiones) y hotfix/* (correcciones urgentes). Es más complejo pero ofrece mayor control sobre el ciclo de vida de las versiones. Ideal para proyectos con versiones numeradas (librerías, aplicaciones de escritorio).
Trunk-Based Development (el más ágil)
Todos los desarrolladores trabajan sobre una única rama principal (trunk o main), haciendo commits pequeños y frecuentes. Las ramas de trabajo, si existen, son de vida muy corta (máximo 1-2 días). Requiere buenas prácticas de testing automatizado y feature flags. Es el enfoque preferido por empresas como Google y Facebook.
🔧 Técnicas avanzadas
Una vez que dominas los fundamentos, estas técnicas te harán mucho más productivo en el día a día:
Stash: guardar cambios temporalmente
# Estás trabajando en algo pero necesitas cambiar de rama urgentemente
git stash
# Guarda tus cambios sin hacer commit y limpia el working directory
# Haz lo que necesites en otra rama...
git checkout main
# ...trabajo urgente...
# Vuelve y recupera tus cambios
git checkout feature/mi-trabajo
git stash pop
# Tus cambios están de vuelta exactamente como los dejaste
# Ver la lista de stashes guardados
git stash list
Log avanzado: explorar la historia como un profesional
# Historial gráfico compacto de todas las ramas
git log --oneline --graph --all --decorate
# Buscar quién escribió cada línea de un archivo
git blame archivo.js
# Buscar un commit que introdujo un texto específico
git log -S "función_buscada" --oneline
# Ver los cambios de un archivo a lo largo del tiempo
git log --follow -p -- ruta/al/archivo.js
# Crear un alias para log bonito
git config --global alias.lg "log --oneline --graph --all --decorate"
# Ahora puedes usar: git lg
.gitignore: excluir archivos del rastreo
# Crear un .gitignore en la raíz del proyecto
cat > .gitignore << 'EOF'
# Dependencias
node_modules/
vendor/
__pycache__/
*.pyc
# Archivos de entorno y secretos
.env
.env.local
*.key
*.pem
# Archivos del sistema operativo
.DS_Store
Thumbs.db
*~
# Directorios de build
dist/
build/
*.o
*.class
# Logs
*.log
EOF
git add .gitignore
git commit -m "chore: añadir .gitignore"
Tags: marcar versiones importantes
# Crear un tag anotado (recomendado para versiones de release)
git tag -a v1.0.0 -m "Primera versión estable"
# Listar tags
git tag
# Subir tags al remoto
git push origin --tags
# Ir a un tag específico (modo lectura, detached HEAD)
git checkout v1.0.0
✏️ Ejercicios resueltos
Ejercicio 1: Crear un repositorio con historial ramificado
Enunciado: Crea un repositorio con un archivo index.html. Haz un commit inicial. Luego crea una rama feature/navbar, añade un archivo navbar.html, haz un commit. Vuelve a main, crea otra rama feature/footer, añade footer.html y haz un commit. Finalmente, fusiona ambas ramas en main.
Ver solución
# Preparación
mkdir ejercicio-ramas && cd ejercicio-ramas
git init
# Commit inicial
echo "<html><body>Hola</body></html>" > index.html
git add index.html
git commit -m "feat: crear página principal"
# Rama navbar
git checkout -b feature/navbar
echo "<nav>Inicio | Acerca | Contacto</nav>" > navbar.html
git add navbar.html
git commit -m "feat: crear barra de navegación"
# Rama footer (desde main)
git checkout main
git checkout -b feature/footer
echo "<footer>© 2026 Mi Web</footer>" > footer.html
git add footer.html
git commit -m "feat: crear pie de página"
# Fusionar ambas en main
git checkout main
git merge feature/navbar
git merge feature/footer
# Verificar
git log --oneline --graph --all
ls
# footer.html index.html navbar.html
# Limpieza
git branch -d feature/navbar feature/footer
Ejercicio 2: Resolver un conflicto de merge
Enunciado: Crea un repositorio con un archivo config.txt que contenga puerto=3000. Haz un commit. Crea una rama feature/dev y cambia el puerto a 8080. Vuelve a main y cambia el puerto a 5000. Intenta fusionar y resuelve el conflicto eligiendo el puerto 8080.
Ver solución
mkdir ejercicio-conflicto && cd ejercicio-conflicto
git init
# Base
echo "puerto=3000" > config.txt
git add config.txt
git commit -m "config: puerto inicial 3000"
# Rama dev: cambiar a 8080
git checkout -b feature/dev
echo "puerto=8080" > config.txt
git add config.txt
git commit -m "config: puerto dev 8080"
# Main: cambiar a 5000
git checkout main
echo "puerto=5000" > config.txt
git add config.txt
git commit -m "config: puerto producción 5000"
# Intentar fusionar → CONFLICTO
git merge feature/dev
# Auto-merging config.txt
# CONFLICT (content): Merge conflict in config.txt
# Resolver: elegir puerto 8080
echo "puerto=8080" > config.txt
git add config.txt
git commit -m "merge: resolver conflicto, usar puerto 8080"
cat config.txt
# puerto=8080 ✓
Ejercicio 3: Trabajar con un repositorio remoto
Enunciado: Clona un repositorio público de ejemplo, crea una rama local, haz un cambio, y prepara el comando de push (sin ejecutarlo, solo para practicar la sintaxis).
Ver solución
# Clonar un repositorio público de ejemplo
git clone https://github.com/octocat/Hello-World.git
cd Hello-World
# Ver las ramas remotas
git branch -a
# Crear una rama local
git checkout -b mi-contribucion
# Hacer un cambio
echo "Hola desde mi fork" >> README
# Preparar el commit
git add README
git commit -m "docs: añadir saludo en español"
# El comando para subir sería (no ejecutar sin fork propio):
# git push origin mi-contribucion
# Luego abrir Pull Request en GitHub
# Ver el log con las ramas remotas
git log --oneline --graph --all -10
⚠️ Errores frecuentes y buenas prácticas
Después de años trabajando con equipos de desarrollo, estos son los errores más comunes con Git y cómo evitarlos:
Hacer commits gigantes con mensaje «cambios varios». Cada commit debería representar una unidad lógica de cambio. Si has modificado diez archivos por tres razones distintas, haz tres commits separados usando git add selectivo.
Trabajar directamente sobre main. Incluso en proyectos personales, crea ramas para cada funcionalidad o corrección. Es un hábito que te ahorrará dolores de cabeza y te preparará para el trabajo en equipo.
No usar .gitignore desde el inicio. Añadir el .gitignore debe ser uno de tus primeros commits. Una vez que un archivo queda registrado en el historial de Git, eliminarlo es complejo. Nunca versiones archivos .env, claves privadas, carpetas node_modules/, ni archivos de compilación.
Hacer git push --force en ramas compartidas. El force push reescribe la historia del remoto y puede destruir el trabajo de otros compañeros. Si necesitas forzar un push, usa git push --force-with-lease, que solo funciona si nadie ha subido cambios nuevos desde tu último fetch.
No hacer git pull antes de empezar a trabajar. Siempre actualiza tu rama local antes de empezar una sesión de trabajo. Un git pull al inicio del día previene la mayoría de conflictos.
Entrar en pánico ante un conflicto. Los conflictos son normales y esperables. No significan que algo se haya roto. Son simplemente Git pidiéndote que tomes una decisión sobre dos cambios incompatibles. Léelos con calma, elige la versión correcta (o combina ambas), y resuelve.
git reflog es tu red de seguridad. Muestra un registro de todas las operaciones que has realizado con HEAD, incluyendo commits descartados, resets y rebases. Puedes usar git reset --hard HEAD@{n} para volver a cualquier punto del reflog.
❓ Preguntas frecuentes sobre Git en Linux: guía completa de control de versiones desde cero
Las dudas más comunes respondidas de forma clara y directa.
💬 Foro de discusión
¿Tienes dudas sobre Git en Linux: guía completa de control de versiones desde cero? Comparte tu pregunta con la comunidad.
Todavía no hay mensajes. ¡Sé el primero en participar!