Versionamiento con Git: Fundamentos, Ramas, Conflictos de Fusión y Flujos de Trabajo
Git es el sistema de control de versiones distribuido más utilizado en desarrollo de software. Permite colaboración eficiente, seguimiento de cambios y gestión segura del código.
Fundamentos de Git
¿Qué es Git?
Git es un sistema de control de versiones distribuido (DVCS) diseñado para simplificar la colaboración en proyectos de software.
Conceptos Clave
# Inicializar un repositorio Git
git init
# Clonar un repositorio
git clone https://github.com/user/repository.git
# Ver el estado
git status
# Agregar cambios
git add datei.txt
git add .
# Confirmar cambios
git commit -m "Descripción del cambio"
# Subir cambios
git push origin main
# Descargar cambios
git pull origin main
Arquitectura de Git
# Áreas de trabajo en Git
# Working Directory → Staging Area → Local Repository → Remote Repository
# Working Directory (Directorio de trabajo)
echo "Nuevo contenido" > datei.txt
# Staging Area (Área de preparación)
git add datei.txt
# Local Repository (Repositorio local)
git commit -m "Confirmar cambio"
# Remote Repository (Repositorio remoto)
git push origin main
Configuración de Git
Configuración Inicial
# Configurar nombre de usuario y correo
git config --global user.name "Max Mustermann"
git config --global user.email "max@example.com"
# Establecer el editor predeterminado
git config --global core.editor "vim"
# Nombre de rama predeterminado (main en lugar de master)
git config --global init.defaultBranch main
# Ver la configuración
git config --list
# Configuración específica para un repositorio
git config user.email "work@example.com"
Alias de Git
# Crear alias útiles
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'
git config --global alias.visual '!gitk'
# Usar alias
git st # git status
git co main # git checkout main
git br # git branch
git ci -m "Mensaje" # git commit -m "Mensaje"
Ramas en Git
Fundamentos de Ramas
Las ramas permiten desarrollar características en paralelo sin afectar el código principal.
# Crear una nueva rama
git branch feature-login
# Cambiar a una rama
git checkout feature-login
# Crear y cambiar a una rama (combinado)
git checkout -b feature-login
# Ver todas las ramas
git branch
git branch -a # incluir ramas remotas
# Eliminar una rama
git branch -d feature-login # solo si está fusionada
git branch -D feature-login # forzar eliminación
# Eliminar una rama remota
git push origin --delete feature-login
Estrategias de Ramas
# Flujo de trabajo con ramas de características
# 1. Crear nueva rama de característica desde main
git checkout main
git pull origin main
git checkout -b feature-user-authentication
# 2. Trabajar en la característica
git add .
git commit -m "Implement user authentication"
git push origin feature-user-authentication
# 3. Crear una solicitud de extracción y fusionar
# 4. Eliminar la rama después de fusionar
git checkout main
git pull origin main
git branch -d feature-user-authentication
Gestión de Ramas
# Comparar ramas
git diff main feature-branch
git log main..feature-branch
# Fusionar una rama (merge)
git checkout main
git merge feature-branch
# Fusionar una rama (rebase)
git checkout feature-branch
git rebase main
# Cherry-pick (aplicar commits específicos)
git checkout main
git cherry-pick <commit-hash>
# Stash (guardar cambios temporales)
git stash
git stash list
git stash pop
git stash apply
git stash drop
Conflictos de Fusión
¿Qué son los Conflictos de Fusión?
Los conflictos de fusión ocurren cuando Git no puede decidir automáticamente qué versión de un archivo debe conservarse.
Situaciones Típicas de Conflicto
# Ejemplo: Dos desarrolladores modifican la misma línea
# Desarrollador A (rama feature-a)
echo "console.log('Hello from Feature A');" > app.js
git add app.js
git commit -m "Add feature A logging"
# Desarrollador B (rama main)
echo "console.log('Hello from Main');" > app.js
git add app.js
git commit -m "Add main logging"
# Intentar fusionar
git checkout main
git merge feature-a
# CONFLICT: Merge conflict in app.js
Resolución de Conflictos
# 1. Ver el conflicto
git status
# 2. Abrir el archivo y editar
# Git marca los conflictos con <<<<<<<, =======, >>>>>>>
# app.js después del conflicto:
# <<<<<<< HEAD
# console.log('Hello from Main');
# =======
# console.log('Hello from Feature A');
# >>>>>>> feature-a
# 3. Resolver manualmente
# console.log('Hello from Main and Feature A');
# 4. Guardar el archivo y marcar como resuelto
git add app.js
git commit -m "Resolve merge conflict in app.js"
# Alternativa: Abortar la fusión
git merge --abort
Resolución Avanzada de Conflictos
# Usar herramientas de fusión
git mergetool
# Definir estrategias de conflicto
git merge -X theirs feature-branch # preferir su versión
git merge -X ours feature-branch # preferir nuestra versión
# Fusión Octopus (varias ramas a la vez)
git merge branch1 branch2 branch3
# Fusión Subtree (integrar un proyecto externo)
git subtree add --prefix=external-repo https://github.com/user/repo.git main
Flujos de Trabajo con Git
1. Flujo de Trabajo Centralizado
# Flujo más simple
# Todos trabajan directamente en main
# 1. Cambios locales
git add .
git commit -m "Add new feature"
# 2. Subir cambios
git push origin main
# 3. Resolver conflictos si existen
git pull origin main
# Resolver conflictos
git push origin main
2. Flujo de Trabajo con Ramas de Características
# Cada característica obtiene su propia rama
# 1. Crear rama de característica
git checkout main
git pull origin main
git checkout -b feature-user-profile
# 2. Trabajar en la característica
git add .
git commit -m "Add user profile page"
git push origin feature-user-profile
# 3. Crear una solicitud de extracción
# Mediante la interfaz de GitHub/GitLab o CLI
# 4. Revisión y fusión
# Revisión de código por parte del equipo
# Fusionar en main después de la aprobación
# 5. Limpiar ramas
git checkout main
git pull origin main
git branch -d feature-user-profile
3. Flujo de Trabajo Gitflow
# Gitflow con ramas main, develop, feature, release, hotfix
# 1. Inicializar rama develop
git checkout main
git checkout -b develop
git push origin develop
# 2. Rama de característica desde develop
git checkout develop
git checkout -b feature-shopping-cart
# 3. Fusionar característica en develop
git checkout develop
git merge feature-shopping-cart
git push origin develop
# 4. Crear rama de lanzamiento
git checkout develop
git checkout -b release/v1.0.0
# 5. Fusionar lanzamiento en main y develop
git checkout main
git merge release/v1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0"
git push origin main --tags
git checkout develop
git merge release/v1.0.0
git push origin develop
# 6. Hotfix desde main
git checkout main
git checkout -b hotfix/critical-bug
# Arreglar el error
git checkout main
git merge hotfix/critical-bug
git checkout develop
git merge hotfix/critical-bug
4. Forking Workflow
# Para proyectos de código abierto o contribuciones externas
# 1. Hacer fork del repositorio (a través de GitHub/GitLab UI)
# 2. Clonar tu propio repositorio
git clone https://github.com/yourusername/project.git
cd project
# 3. Añadir el remote upstream
git remote add upstream https://github.com/original/project.git
# 4. Crear una rama de feature
git checkout -b feature-new-functionality
# 5. Hacer commit de los cambios
git add .
git commit -m "Add new functionality"
# 6. Push al repositorio personal
git push origin feature-new-functionality
# 7. Pull Request al repositorio original
# 8. Actualizar upstream regularmente
git fetch upstream
git checkout main
git merge upstream/main
Técnicas avanzadas de Git
Rebase e Interactive Rebase
# Rebase simple
git checkout feature-branch
git rebase main
# Interactive Rebase (reordenar/editar commits)
git rebase -i HEAD~3
# Opciones de Interactive Rebase:
# pick: Incluir el commit sin cambios
# reword: Cambiar el mensaje del commit
# edit: Modificar el commit
# squash: Combinar con el commit anterior
# fixup: Combinar con el commit anterior (sin mensaje)
# drop: Eliminar el commit
# Ejemplo de Interactive Rebase
# pick 1234567 Add feature A
# squash 2345678 Add feature B
# reword 3456789 Fix typo
# Forzar un rebase (cuidado)
git push --force-with-lease origin feature-branch
Git Hooks
# Hooks ubicados en .git/hooks/
# Pre-commit Hook (antes de cada commit)
#!/bin/sh
# .git/hooks/pre-commit
echo "Running pre-commit checks..."
npm run lint
npm run test
# Pre-push Hook (antes de cada push)
#!/bin/sh
# .git/hooks/pre-push
echo "Running pre-push tests..."
npm run test:coverage
# Activar hooks (hacer ejecutables)
chmod +x .git/hooks/pre-commit
chmod +x .git/hooks/pre-push
# Configurar hooks globalmente
git config --global init.templatedir '~/.git-templates'
Git Submodules
# Añadir un submodule
git submodule add https://github.com/user/library.git libs/library
# Inicializar submodules
git submodule init
git submodule update
# Clonar con submodules
git clone --recurse-submodules https://github.com/user/project.git
# Actualizar submodules
git submodule update --remote
# Eliminar un submodule
git rm --cached libs/library
rm -rf libs/library
git commit -m "Remove submodule"
Buenas prácticas
Mensajes de commit
# Buenos mensajes de commit
feat: Add user authentication system
fix: Resolve memory leak in data processing
docs: Update API documentation
style: Format code according to style guide
refactor: Simplify database connection logic
test: Add unit tests for user service
chore: Update dependencies
# Estructura: <type>(<scope>): <description>
# Tipos: feat, fix, docs, style, refactor, test, chore
# Mensaje de commit detallado
feat(auth): Add OAuth2 integration
- Add Google OAuth provider
- Implement token refresh mechanism
- Add user profile synchronization
Closes #123
Convenciones de nombres de ramas
# Buenos nombres de rama
feature/user-authentication
bugfix/memory-leak-fix
hotfix/critical-security-patch
release/v1.2.0
docs/update-api-documentation
refactor/database-connection-pool
test/add-unit-tests
# Nombres de rama incorrectos
fix-stuff
new-feature
branch-1
temp
Estructura del repositorio
# .gitignore
# Compiled files
*.class
*.jar
*.war
*.ear
# IDE files
.idea/
.vscode/
*.swp
*.swo
# Dependencies
node_modules/
target/
build/
# Logs
*.log
logs/
# Environment files
.env
.env.local
# .gitattributes
# Text files
*.txt text
*.md text
*.js text
*.java text
# Binary files
*.jpg binary
*.png binary
*.pdf binary
# Line endings
* text=auto eol=lf
Solución de problemas
Problemas frecuentes
# 1. Commit en la rama equivocada
git checkout correct-branch
git cherry-pick <wrong-commit-hash>
git checkout wrong-branch
git reset --hard HEAD~1
# 2. Recuperar commits perdidos
git reflog
git checkout -b recovery <commit-hash>
# 3. Deshacer cambios no deseados
git reset --hard HEAD
git reset --hard HEAD~1 # Eliminar el último commit
git clean -fd # Eliminar archivos sin seguimiento
# 4. Problemas con el repositorio remoto
git remote -v
git remote set-url origin https://github.com/user/new-repo.git
# 5. Recuperar después de un force push
git reflog
git reset --hard HEAD@{1}
git push --force-with-lease origin main
Optimización del rendimiento
# Optimizar repositorio
git gc --prune=now
# Encontrar archivos grandes
git rev-list --objects --all | git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | sed -n 's/^blob //p' | sort --numeric-sort --key=2 | tail -10
# Git LFS para archivos grandes
git lfs install
git lfs track "*.psd"
git lfs track "*.zip"
git add .gitattributes
git commit -m "Track large files with Git LFS"
Git en la práctica
Integración CI/CD
# .github/workflows/ci.yml
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Run tests
run: npm test
- name: Run linting
run: npm run lint
- name: Build project
run: npm run build
Git para colaboración en equipo
# Directrices de equipo
# 1. Usar ramas de feature
# 2. Pull Requests para revisión de código
# 3. Tests automáticos en cada push
# 4. Protected Branches para main y develop
# 5. Rebase regular en lugar de merge
# Ejemplo de configuración de protected Branch
# A través de GitHub/GitLab:
# - Require pull request reviews before merging
# - Require status checks to pass before merging
# - Require branches to be up to date before merging
# - Include administrators as reviewers
Conceptos relevantes para la prueba
Comandos Git importantes
| Comando | Descripción | Uso |
|---|---|---|
git init | Inicializar repositorio | Empezar nuevo proyecto |
git clone | Clonar repositorio | Copiar proyecto existente |
git add | Añadir cambios al staging | Preparar cambios |
git commit | Hacer commit de cambios | Guardar cambios locales |
git push | Subir cambios | Sincronizar con remoto |
git pull | Descargar cambios | Obtener cambios remotos |
git branch | Gestionar ramas | Crear líneas de desarrollo |
git merge | Fusionar ramas | Integrar cambios |
git rebase | Cambiar base de rama | Crear historial lineal |
Tareas típicas en pruebas
- Explicar workflows de Git
- Resolver conflictos de merge
- Implementar estrategias de branching
- Usar comandos avanzados de Git
- Configurar CI/CD con Git
Resumen
Git es fundamental para el desarrollo de software moderno:
- Sistema distribuido: Cada desarrollador tiene una copia completa
- Ramas: Desarrollo paralelo sin conflictos
- Merge: Integración inteligente de cambios
- Workflows: Colaboración estructurada en equipo
Recomendación de libro
Invierte en tus conocimientos de Git con este manual exhaustivo para desarrolladores y equipos DevOps. El libro no solo cubre los fundamentos, sino también técnicas avanzadas y una referencia práctica de comandos Git para usar en el día a día.
Git: Projektverwaltung für Entwickler und DevOps-Teams. Inkl. Praxistipps und Git-KommandoreferenzEste libro es ideal para:
- Principiantes que quieren aprender Git desde cero
- Desarrolladores experimentados que desean profundizar en sus conocimientos
- Equipos DevOps que quieren implementar workflows efectivos
- Quienes necesitan una referencia completa de Git
- CI/CD: automatización de compilación y despliegue
Un buen manejo de Git requiere disciplina, reglas claras y mantenimiento regular del repositorio.

