Tutorial completo de Git y GitHub: control de versiones de básico a avanzado
Guía completa para dominar Git y GitHub: desde conceptos fundamentales hasta técnicas avanzadas de colaboración en equipo. Comandos básicos y avanzados, gestión de ramas, pull requests, resolución de conflictos y buenas prácticas.
Control de versiones con Git y GitHub: por qué es imprescindible
Git es el sistema de control de versiones distribuido más usado en desarrollo de software. GitHub es la plataforma que añade la capa de colaboración remota. Juntos permiten registrar el historial completo de un proyecto, colaborar en equipo sin pisar el trabajo de los demás y recuperar cualquier estado anterior del código.
Este tutorial cubre el flujo completo: desde instalar Git hasta técnicas avanzadas como rebase interactivo, cherry-pick y resolución de conflictos. Cada sección incluye los comandos exactos listos para ejecutar.
Terminología esencial: lo que necesitas entender antes de escribir un comando
Git tiene su propio vocabulario. Entender estos términos antes de empezar evita la confusión habitual entre conceptos que parecen similares pero funcionan de forma muy diferente.
- Repository (Repositorio)
- Contenedor que almacena todo el código fuente y su historial completo de versiones. Puede ser local (en tu máquina) o remoto (en GitHub). Un repositorio local puede conectarse a uno o más repositorios remotos.
- Commit
- Instantánea del estado del proyecto en un momento específico. Cada commit tiene un hash único, un mensaje descriptivo, el autor y la fecha. El historial de commits es la línea del tiempo del proyecto.
- Branch (Rama)
- Línea independiente de desarrollo que permite trabajar en funcionalidades o correcciones sin afectar el código principal. Las ramas son baratas en Git — crearlas y eliminarlas es instantáneo.
- Merge
- Proceso de combinar los cambios de una rama en otra. Crea un commit de fusión que mantiene el historial exacto de ambas ramas. La alternativa es rebase, que reescribe el historial para crear una línea más limpia.
- Pull Request
- Solicitud en GitHub para revisar e integrar los cambios de una rama en otra. Es el mecanismo central de la colaboración en equipo: permite revisión de código, comentarios y aprobación antes de fusionar.
- Fork
- Copia personal de un repositorio de otro usuario en tu cuenta de GitHub. Permite contribuir a proyectos en los que no tienes permisos de escritura directa: trabajas en tu fork y envías un pull request al repositorio original.
- Estados de los archivos — Working Directory, Staging Area, Repository
- Los archivos pasan por tres estados: Working Directory (modificados localmente), Staging Area (preparados para el próximo commit con
git add) y Repository (confirmados en el historial congit commit). Entender este flujo es clave para usar Git correctamente.
Instalar y configurar Git: los tres pasos antes de empezar
Windows: choco install git o descargar desde git-scm.com. macOS: brew install git. Linux (Ubuntu/Debian): sudo apt update && sudo apt install git.
git config --global user.name "Tu Nombre" y git config --global user.email "tu@email.com". Esta identidad aparece en todos los commits. Verificar con git config --list.
Método 1 — Token: GitHub → Settings → Developer settings → Personal access tokens → Generate new token → Classic. Se usa como contraseña en el push. Método 2 — SSH: ssh-keygen -t ed25519 -C "email", añadir la clave pública en GitHub → Settings → SSH keys.
El flujo diario: init, add, commit, push, pull
mkdir mi-proyecto && cd mi-proyecto
git init
git status
git add . # añadir todos los archivos
git add archivo.txt # o uno específico
git commit -m "feat: primer commit del proyecto"
git log --oneline # ver historial compacto
git diff --staged # revisar antes de commit
git remote add origin https://github.com/usuario/repo.git
git remote -v # verificar remotos
git push -u origin main # primer push
git fetch origin # descargar sin integrar
git pull origin main # descargar e integrar
git push origin main # subir cambios locales
Branches, merge y rebase: la columna vertebral del flujo de trabajo
Las ramas son el mecanismo que permite trabajar en paralelo sin conflictos. La elección entre merge y rebase determina cómo queda el historial del proyecto.
git checkout -b nueva-funcionalidad crea y cambia en un paso. El comando moderno equivalente es git switch -c nueva-funcionalidad. Para ver todas las ramas: git branch -a.
Cambiar a la rama destino (git checkout main) y ejecutar git merge nombre-rama. Crea un commit de fusión que preserva el historial de ambas ramas. Recomendado para ramas compartidas.
git rebase main desde la rama feature reescribe los commits sobre el HEAD de main. El resultado es un historial lineal sin commits de merge. Solo usar en ramas no compartidas con otros.
git branch -a # ver todas las ramas
git checkout -b feature/login # crear y cambiar
git branch -d nombre-rama # eliminar (seguro)
git push origin --delete nombre # eliminar en remoto
git branch --merged # ver ramas ya fusionadas
Flujo colaborativo: fork, upstream y pull requests
El flujo estándar de contribución a proyectos de terceros: fork del repositorio, trabajo en rama, push y pull request al repositorio original.
- Fork y configurar upstream
- Hacer fork del repositorio en GitHub, clonarlo localmente y añadir el repositorio original como remoto upstream:
git remote add upstream https://github.com/usuario-original/proyecto.git. El upstream permite mantener el fork sincronizado con el proyecto original. - Mantener el fork actualizado
git fetch upstreamdescarga los cambios del repositorio original.git merge upstream/mainlos integra en tu rama local.git push origin mainactualiza tu fork en GitHub. Este proceso debe hacerse antes de crear cada nueva rama de trabajo.- Convenciones de nombrado de ramas
feature/descripcionpara nuevas funcionalidades,bugfix/descripcionpara corrección de errores,hotfix/descripcionpara correcciones urgentes en producción,release/versionpara preparación de releases.- Mensajes de commit con Conventional Commits
- Formato:
tipo: descripción breve. Tipos:feat(nueva funcionalidad),fix(corrección),docs(documentación),style(formato),refactor(refactorización),test(tests). Ejemplo:git commit -m "feat: agregar validación de email en registro".
Conflictos de merge: cómo identificarlos y resolverlos paso a paso
# 1. El merge falla con CONFLICT
git merge feature-branch
# 2. Ver qué archivos tienen conflicto
git status
# 3. El archivo muestra los marcadores:
# <<<<<<< HEAD
# código de la rama actual
# =======
# código de la rama que se fusiona
# >>>>>>> feature-branch
# 4. Editar el archivo: decidir qué código mantener,
# eliminar los marcadores <<<, === y >>>
# 5. Confirmar la resolución
git add archivo-resuelto.js
git commit -m "fix: resolver conflicto en archivo.js"
Stash, cherry-pick y rebase interactivo: el kit de herramientas del día a día
git stash guarda los cambios no confirmados temporalmente. git stash pop los recupera. git stash list muestra todos los stashes guardados. Útil para cambiar de rama sin perder trabajo en progreso.
git cherry-pick abc123 aplica un commit concreto de otra rama en la rama actual. Útil para llevar una corrección específica a producción sin mergear toda la rama de desarrollo. Si hay conflictos: resolver, git add . y git cherry-pick --continue.
git rebase -i HEAD~3 abre el editor con los últimos 3 commits para reordenarlos, combinarlos (squash), editar sus mensajes (reword) o eliminarlos (drop). Solo usar en commits no pusheados.
git reset --soft HEAD~1 deshace el commit manteniendo los cambios en staging. git reset --mixed HEAD~1 los deja en working directory. git reset --hard HEAD~1 los elimina completamente. Solo usar en commits no pusheados al remoto.
Cinco escenarios habituales: qué hacer exactamente en cada uno
- Olvidé hacer pull antes de modificar — "forgot to pull"
- Si aún no hay commit:
git stash,git pull origin main,git stash pop. Si ya hay commits locales:git pull origin main(crea merge commit) ogit rebase origin/main(historial más limpio). - Quiero deshacer el último commit
- Mantener los cambios:
git reset --soft HEAD~1. Descartar los cambios:git reset --hard HEAD~1. Si ya hiciste push:git revert HEAD(crea un commit que deshace los cambios sin reescribir el historial público). - Hice cambios en la rama equivocada
- Si no hay commit:
git stash,git checkout rama-correcta,git stash pop. Si ya hay commit: copiar el hash congit log --oneline, ejecutargit reset --hard HEAD~1en la rama incorrecta, cambiar a la rama correcta y aplicar congit cherry-pick hash. - Committé un archivo grande o sensible por error
- Del último commit:
git rm --cached archivo-grandeygit commit --amend. De todo el historial (avanzado):git filter-brancho la herramienta más modernagit filter-repo. Añadir el archivo al.gitignorepara evitar que vuelva a ocurrir. - Necesito sincronizar mi fork con el repositorio original
- Si no está configurado:
git remote add upstream https://github.com/original/repo.git. Luego:git fetch upstream,git checkout main,git merge upstream/main,git push origin main.
Cuatro reglas de oro: commits, ramas, .gitignore y tags
Cada commit debe representar un único cambio lógico completo. Usar Conventional Commits: feat:, fix:, docs:, refactor:. Revisar siempre con git diff --staged antes de confirmar.
Git Flow: main (producción), develop (desarrollo), feature/*, release/*, hotfix/*. GitHub Flow (más simple): solo main y ramas feature/* con PR directo a main.
Crear el .gitignore antes del primer git add .. Ignorar siempre: node_modules/, .env, .DS_Store, dist/, *.log, carpetas de IDE. Usar gitignore.io para generar plantillas por stack.
git tag -a v1.0.0 -m "Versión 1.0.0" crea un tag anotado. git push origin --tags lo sube a GitHub. Los tags anotados incluyen autor, fecha y mensaje — preferibles a los ligeros para releases.
Cheat sheet: los comandos más usados agrupados por categoría
# Configuración
git config --global user.name "Nombre"
git config --list
# Básicos
git init | git clone <url> | git status
git add <archivo> | git commit -m "msg"
git push origin <rama> | git pull origin <rama>
# Ramas
git branch -a | git checkout -b <rama>
git merge <rama> | git branch -d <rama>
# Remotos
git remote -v | git remote add origin <url>
git fetch origin | git push -u origin <rama>
# Historial
git log --oneline | git diff | git show <commit>
git blame archivo.txt
# Avanzados
git stash | git stash pop | git stash list
git cherry-pick <hash>
git rebase -i HEAD~3
git reset --soft HEAD~1
git revert HEAD
Documentación, herramientas y práctica interactiva
- Documentación oficial
- git-scm.com/doc — manual completo de Git con todos los comandos y opciones. docs.github.com — documentación de GitHub: Actions, Pages, API y todo el ecosistema.
- Práctica interactiva
- Learn Git Branching — visualizador interactivo de ramas y comandos, el mejor recurso para entender merge y rebase de forma gráfica. Git Immersion — tutorial guiado en la terminal.
- Herramientas GUI recomendadas
- VS Code con la extensión GitLens para integración nativa en el editor. GitHub Desktop para una interfaz oficial sin configuración. GitKraken para visualización avanzada de ramas y flujos complejos. SourceTree para proyectos con Bitbucket o GitHub.
Yel Martínez, Digital Strategist & Technologist — especialista en desarrollo web, SEO técnico y automatización. Ver el perfil en GitHub. Para proyectos de desarrollo, auditoría técnica o formación en herramientas de desarrollo: contacto.
