Guía Definitiva de Control de Versiones
Publicado el 24 de noviembre de 2025
Guía Definitiva de Control de Versiones
El control de versiones no es opcional. Es fundamental. He visto desarrolladores perder días o semanas de trabajo por no usar Git correctamente. He visto equipos luchando con conflictos de merge porque no siguen un flujo de trabajo consistente.
En este artículo, compartiré el flujo de trabajo profesional con Git que te ayudará a trabajar de manera segura, colaborativa y eficiente.
¿Por qué Git es esencial?
Git no es solo para guardar código. Es para:
- Historial: Ver qué cambió y cuándo
- Colaboración: Múltiples desarrolladores trabajando sin conflictos
- Seguridad: Nunca perder código
- Experimentos: Probar cosas sin miedo
- Rollback: Revertir cambios problemáticos
Configuración inicial
Configurar Git
# Configurar nombre y email
git config --global user.name "Tu Nombre"
git config --global user.email "tu@email.com"
# Editor preferido
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "vim" # Vim
# Colores
git config --global color.ui true
# Ver configuración
git config --list
Crear repositorio
# Inicializar repositorio local
git init
# O clonar existente
git clone https://github.com/user/repo.git
Flujo de trabajo básico
1. Verificar estado
# Ver estado del repositorio
git status
# Ver cambios detallados
git diff
# Ver cambios en archivos específicos
git diff file.txt
2. Agregar cambios
# Agregar archivo específico
git add file.txt
# Agregar todos los cambios
git add .
# Agregar interactivo (recomendado)
git add -p
# Ver qué se agregó
git status
3. Hacer commit
# Commit con mensaje
git commit -m "feat: agregar autenticación de usuarios"
# Commit con descripción
git commit -m "feat: agregar autenticación
- Implementar login con email/password
- Agregar validación de tokens JWT
- Crear middleware de autenticación"
# Agregar y commit en uno
git commit -am "fix: corregir bug en cálculo de precios"
4. Ver historial
# Ver commits
git log
# Ver commits en una línea
git log --oneline
# Ver commits con gráfico
git log --graph --oneline --all
# Ver cambios en commit específico
git show <commit-hash>
Convenciones de commits
Usa mensajes de commit claros y descriptivos. Recomiendo Conventional Commits:
# Formato: tipo(scope): descripción
# Tipos comunes:
feat: nueva funcionalidad
fix: corrección de bug
docs: documentación
style: formato (sin cambios de código)
refactor: refactorización
test: pruebas
chore: tareas de mantenimiento
# Ejemplos:
git commit -m "feat(auth): agregar login con Google OAuth"
git commit -m "fix(payment): corregir cálculo de impuestos"
git commit -m "docs(readme): actualizar instrucciones de instalación"
git commit -m "refactor(api): simplificar lógica de validación"
Ramas (Branches)
Las ramas son fundamentales para trabajar en equipo y organizar el trabajo.
Crear y cambiar ramas
# Crear rama
git branch feature/nueva-funcionalidad
# Cambiar a rama
git checkout feature/nueva-funcionalidad
# Crear y cambiar en uno
git checkout -b feature/nueva-funcionalidad
# Ver ramas
git branch
# Ver ramas remotas
git branch -r
# Ver todas las ramas
git branch -a
Flujo de trabajo con ramas
# 1. Trabajar en main/master (solo código estable)
git checkout main
# 2. Crear rama para nueva funcionalidad
git checkout -b feature/autenticacion
# 3. Hacer cambios y commits
git add .
git commit -m "feat: implementar login"
# 4. Actualizar main
git checkout main
git pull origin main
# 5. Mergear cambios
git checkout feature/autenticacion
git merge main # O rebase (ver más abajo)
# 6. Push y crear Pull Request
git push origin feature/autenticacion
Merge vs. Rebase
Merge
# Mergear rama a main
git checkout main
git merge feature/nueva-funcionalidad
# Merge con mensaje
git merge feature/nueva-funcionalidad -m "Merge feature/nueva-funcionalidad"
Ventajas: Preserva historial completo Desventajas: Puede crear historial complejo
Rebase
# Rebase rama sobre main
git checkout feature/nueva-funcionalidad
git rebase main
# Rebase interactivo (para limpiar commits)
git rebase -i main
Ventajas: Historial lineal y limpio Desventajas: Reescribe historial (no usar en ramas compartidas)
Cuándo usar cada uno
- Merge: Para ramas compartidas, mantener historial completo
- Rebase: Para ramas locales, mantener historial limpio
Trabajando con remotos
Agregar remoto
# Agregar remoto
git remote add origin https://github.com/user/repo.git
# Ver remotos
git remote -v
# Cambiar URL de remoto
git remote set-url origin https://github.com/user/new-repo.git
Push y Pull
# Push a remoto
git push origin main
# Push rama nueva
git push -u origin feature/nueva-funcionalidad
# Pull cambios
git pull origin main
# Fetch (sin merge)
git fetch origin
# Ver diferencias antes de pull
git fetch origin
git log HEAD..origin/main
Resolver conflictos
Los conflictos son inevitables cuando trabajas en equipo.
Cuando ocurre un conflicto
# Intentar merge/pull
git merge feature/otra-rama
# Git te dirá:
# Auto-merging file.txt
# CONFLICT (content): Merge conflict in file.txt
Resolver conflicto
# 1. Ver archivos con conflicto
git status
# 2. Abrir archivo y buscar marcadores:
<<<<<<< HEAD
código de tu rama actual
=======
código de la rama que estás mergeando
>>>>>>> feature/otra-rama
# 3. Editar archivo, eliminar marcadores, dejar código correcto
# 4. Marcar como resuelto
git add file.txt
# 5. Completar merge
git commit
Herramientas para conflictos
# Usar herramienta de merge
git mergetool
# Configurar herramienta
git config --global merge.tool vimdiff
git config --global merge.tool code # VS Code
Comandos avanzados
Stash - Guardar cambios temporalmente
# Guardar cambios sin commit
git stash
# Guardar con mensaje
git stash save "WIP: trabajo en progreso"
# Ver stashes
git stash list
# Aplicar stash
git stash apply
# Aplicar y eliminar
git stash pop
# Eliminar stash
git stash drop
Reset - Deshacer cambios
# Deshacer cambios en working directory (mantener staged)
git reset --soft HEAD~1
# Deshacer cambios en staging (mantener working directory)
git reset HEAD~1
git reset --mixed HEAD~1
# Deshacer todo (⚠️ CUIDADO: pierdes cambios)
git reset --hard HEAD~1
# Resetear a commit específico
git reset --hard <commit-hash>
Revert - Revertir commits
# Revertir commit (crea nuevo commit)
git revert <commit-hash>
# Revertir último commit
git revert HEAD
Diferencia con reset: revert crea un nuevo commit, reset elimina commits.
Cherry-pick - Aplicar commit específico
# Aplicar commit de otra rama
git cherry-pick <commit-hash>
# Aplicar múltiples commits
git cherry-pick <commit1> <commit2>
Flujo de trabajo profesional
Git Flow
# Ramas principales:
# - main/master: producción
# - develop: desarrollo
# - feature/*: nuevas funcionalidades
# - release/*: preparación de release
# - hotfix/*: correcciones urgentes
# Crear feature
git checkout develop
git pull origin develop
git checkout -b feature/nueva-funcionalidad
# Trabajar y hacer commits
git add .
git commit -m "feat: implementar funcionalidad"
# Terminar feature
git checkout develop
git merge feature/nueva-funcionalidad
git push origin develop
GitHub Flow (más simple)
# Ramas:
# - main: producción
# - feature/*: nuevas funcionalidades
# Crear feature desde main
git checkout main
git pull origin main
git checkout -b feature/nueva-funcionalidad
# Trabajar y hacer commits
git add .
git commit -m "feat: implementar funcionalidad"
git push origin feature/nueva-funcionalidad
# Crear Pull Request en GitHub/GitLab
# Después de aprobación, mergear a main
Buenas prácticas
1. Commits pequeños y frecuentes
# ❌ Mal: Un commit enorme
git commit -m "feat: agregar todo"
# ✅ Bien: Commits pequeños y específicos
git commit -m "feat: agregar modelo de usuario"
git commit -m "feat: agregar endpoint de registro"
git commit -m "test: agregar tests de registro"
2. No commitees archivos generados
# Crear .gitignore
echo "node_modules/" >> .gitignore
echo ".env" >> .gitignore
echo "dist/" >> .gitignore
echo "*.log" >> .gitignore
3. Pull antes de Push
# Siempre actualizar antes de push
git checkout main
git pull origin main
git checkout feature/nueva-funcionalidad
git merge main # O rebase
git push origin feature/nueva-funcionalidad
4. Revisa antes de commitear
# Ver qué se va a commitear
git status
git diff --staged
# Ver historial antes de push
git log origin/main..HEAD
5. Usa tags para releases
# Crear tag
git tag v1.0.0
# Tag con mensaje
git tag -a v1.0.0 -m "Release version 1.0.0"
# Push tags
git push origin v1.0.0
git push --tags
Comandos útiles
Ver diferencias
# Diferencias entre ramas
git diff main..feature/nueva-funcionalidad
# Diferencias en archivo específico
git diff main..feature/nueva-funcionalidad -- file.txt
# Estadísticas de cambios
git diff --stat main..feature/nueva-funcionalidad
Buscar en historial
# Buscar texto en commits
git log -S "texto" --source --all
# Buscar en mensajes de commit
git log --grep="bug"
# Buscar por autor
git log --author="Sebastian"
Limpiar repositorio
# Ver archivos no rastreados
git clean -n
# Eliminar archivos no rastreados
git clean -f
# Eliminar directorios también
git clean -fd
Flujo de trabajo recomendado
Este es un flujo de trabajo probado que funciona bien para la mayoría de proyectos:
# 1. Actualizar main
git checkout main
git pull origin main
# 2. Crear feature branch
git checkout -b feature/nueva-funcionalidad
# 3. Trabajar y hacer commits pequeños
git add .
git commit -m "feat: paso 1 de implementación"
git add .
git commit -m "feat: paso 2 de implementación"
# 4. Push y crear PR
git push -u origin feature/nueva-funcionalidad
# 5. Después de aprobación, mergear
git checkout main
git pull origin main
git merge feature/nueva-funcionalidad
git push origin main
# 6. Eliminar rama local
git branch -d feature/nueva-funcionalidad
Errores comunes y cómo evitarlos
1. Commit en main/master
# Si accidentalmente commitaste en main:
git reset HEAD~1 # Deshacer commit (mantener cambios)
git checkout -b feature/nueva-funcionalidad
git add .
git commit -m "feat: nueva funcionalidad"
2. Push force en rama compartida
# ❌ NUNCA hacer esto en ramas compartidas:
git push --force origin main
# ✅ Si necesitas forzar (solo en tu rama):
git push --force-with-lease origin feature/mi-rama
3. Perder cambios
# Recuperar cambios perdidos
git reflog # Ver historial de acciones
git checkout <commit-hash> # Ir a commit específico
git checkout -b recovery-branch # Crear rama de recuperación
Mi perspectiva personal
Git no es opcional. Es esencial. Este flujo de trabajo te ayudará a:
- Trabajar de manera segura y colaborativa
- Nunca perder código
- Resolver conflictos eficientemente
- Mantener historial limpio y comprensible
He visto proyectos sin control de versiones que perdían días o semanas de trabajo. He visto equipos luchando con conflictos de merge porque no siguen un flujo de trabajo consistente.
Este flujo de trabajo ha sido probado en proyectos de todos los tamaños. Funciona para equipos pequeños y grandes, para proyectos simples y complejos.
No necesitas memorizar todos los comandos. Empieza con los básicos (status, add, commit, push, pull) y gradualmente agrega más comandos a tu repertorio.
La clave es ser consistente. Usa el mismo flujo en todos tus proyectos. Con el tiempo, se convertirá en segunda naturaleza, y nunca más perderás código.