5 Desarrollo y Git
El desarrollo moderno requiere herramientas potentes para control de versiones, gestión de repositorios y ejecución de código. Esta sección cubre las herramientas esenciales para cualquier desarrollador profesional.
5.1 git - Control de versiones distribuido
Git es el sistema de control de versiones más usado del mundo, fundamental para cualquier proyecto de desarrollo moderno.
5.1.1 Configuración inicial
# Configuración básica
git config --global user.name "Tu Nombre"
git config --global user.email "tu@email.com"
# Editor por defecto
git config --global core.editor "code --wait"
# Configuraciones útiles
git config --global init.defaultBranch main
git config --global pull.rebase false
git config --global push.default simple5.1.2 Workflow básico
5.1.2.1 Inicialización y clonado
# Inicializar nuevo repositorio
git init
git init mi-proyecto
# Clonar repositorio existente
git clone https://github.com/usuario/repo.git
git clone git@github.com:usuario/repo.git
# Clonar solo historia reciente (más rápido)
git clone --depth 1 https://github.com/usuario/repo.git5.1.2.2 Área de staging y commits
# Ver estado del repositorio
git status
git status -s # Formato corto
# Agregar archivos al staging
git add archivo.txt
git add . # Todos los archivos
git add *.py # Por patrón
git add -A # Incluir eliminados
# Commits
git commit -m "Mensaje descriptivo"
git commit -am "Agregar y commitear archivos modificados"
git commit --amend # Modificar último commit5.1.3 Branching y merging
5.1.3.1 Gestión de branches
# Listar branches
git branch # Locales
git branch -r # Remotos
git branch -a # Todos
# Crear y cambiar de branch
git branch nueva-feature
git checkout nueva-feature
# O en un comando:
git checkout -b nueva-feature
# Cambiar entre branches
git checkout main
git checkout - # Branch anterior
# Eliminar branch
git branch -d feature-completada
git branch -D feature-forzar-eliminar # Forzar5.1.3.2 Merge strategies
# Merge básico
git checkout main
git merge feature-branch
# Merge sin fast-forward (siempre crea commit de merge)
git merge --no-ff feature-branch
# Squash merge (combina todos los commits en uno)
git merge --squash feature-branch
git commit -m "Feature: descripción completa"
# Rebase (historia lineal)
git checkout feature-branch
git rebase main
git checkout main
git merge feature-branch # Fast-forward5.1.5 Casos de uso avanzados
5.1.5.1 Trabajo con remotes
# Configurar remotes
git remote add origin https://github.com/usuario/repo.git
git remote -v # Ver remotes configurados
# Fetch y pull
git fetch origin # Descargar cambios sin merge
git pull origin main # Fetch + merge
git pull --rebase origin main # Fetch + rebase
# Push
git push origin main
git push -u origin feature-branch # Primera vez
git push --force-with-lease origin main # Force seguro5.1.5.2 Stashing (guardado temporal)
# Guardar cambios temporalmente
git stash
git stash push -m "Trabajo en progreso"
# Ver stashes
git stash list
# Aplicar stash
git stash pop # Aplicar y eliminar
git stash apply # Aplicar sin eliminar
git stash apply stash@{1} # Stash específico
# Eliminar stashes
git stash drop stash@{0}
git stash clear # Todos5.1.5.3 Revertir cambios
# Descartar cambios no commiteados
git checkout -- archivo.txt
git restore archivo.txt # Git 2.23+
# Quitar de staging area
git reset HEAD archivo.txt
git restore --staged archivo.txt # Git 2.23+
# Revertir commits
git revert abc123 # Crear commit que deshace otro
git reset --soft HEAD~1 # Deshacer commit, mantener cambios
git reset --hard HEAD~1 # Deshacer commit y cambios (peligroso)5.1.6 Workflows de equipo
5.1.6.1 Feature branch workflow
# 1. Crear feature branch desde main actualizado
git checkout main
git pull origin main
git checkout -b feature/nueva-funcionalidad
# 2. Desarrollar y commitear
git add .
git commit -m "feat: implementar nueva funcionalidad"
# 3. Actualizar con cambios de main
git fetch origin
git rebase origin/main
# 4. Push de feature branch
git push -u origin feature/nueva-funcionalidad
# 5. Crear Pull Request en GitHub/GitLab
# 6. Después del merge, limpiar
git checkout main
git pull origin main
git branch -d feature/nueva-funcionalidad5.1.6.2 Git flow
# Branches principales: main, develop
# Branches de soporte: feature/, release/, hotfix/
# Iniciar feature
git checkout develop
git checkout -b feature/nueva-caracteristica
# Finalizar feature
git checkout develop
git merge --no-ff feature/nueva-caracteristica
git branch -d feature/nueva-caracteristica
# Release branch
git checkout -b release/1.2.0 develop
# Fix bugs, actualizar versión
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0 -m "Version 1.2.0"
git checkout develop
git merge --no-ff release/1.2.05.2 gh - GitHub CLI
La CLI oficial de GitHub permite gestionar repositorios, pull requests, issues y más desde terminal.
5.2.1 Autenticación
# Login interactivo
gh auth login
# Verificar autenticación
gh auth status
# Login con token
echo "ghp_xxxxxxxxxxxx" | gh auth login --with-token5.2.2 Gestión de repositorios
5.2.2.1 Crear y clonar
# Crear repositorio nuevo
gh repo create mi-proyecto
gh repo create mi-proyecto --public
gh repo create mi-proyecto --private --clone
# Clonar repositorio
gh repo clone usuario/repositorio
gh repo clone https://github.com/usuario/repo
# Ver información del repo
gh repo view
gh repo view usuario/repositorio5.2.2.2 Gestión básica
# Listar repositorios
gh repo list # Propios
gh repo list usuario # De un usuario
gh repo list --limit 50
# Fork de repositorio
gh repo fork usuario/repositorio
gh repo fork usuario/repositorio --clone
# Sincronizar fork
gh repo sync usuario/mi-fork5.2.3 Pull Requests
5.2.3.1 Crear y gestionar PRs
# Crear PR desde branch actual
gh pr create
gh pr create --title "Nueva feature" --body "Descripción detallada"
# Crear PR con template
gh pr create --template=.github/pull_request_template.md
# Listar PRs
gh pr list
gh pr list --state=open
gh pr list --author=@me
# Ver detalles de PR
gh pr view 123
gh pr view --web 123 # Abrir en navegador5.2.3.2 Review y merge
# Checkout PR localmente
gh pr checkout 123
# Aprobar PR
gh pr review 123 --approve
gh pr review 123 --approve --body "LGTM! 🚀"
# Solicitar cambios
gh pr review 123 --request-changes --body "Necesita documentación"
# Merge PR
gh pr merge 123
gh pr merge 123 --merge # Merge commit
gh pr merge 123 --squash # Squash merge
gh pr merge 123 --rebase # Rebase merge5.2.4 Issues
5.2.4.1 Gestión de issues
# Crear issue
gh issue create
gh issue create --title "Bug: error en login" --body "Descripción del bug"
# Listar issues
gh issue list
gh issue list --state=open --assignee=@me
gh issue list --label=bug
# Ver y editar issue
gh issue view 456
gh issue edit 456 --add-label=priority-high
gh issue close 4565.2.4.2 Plantillas y automation
# Crear issue con template
gh issue create --template=bug_report.md
# Asignar issue
gh issue edit 456 --assignee=usuario
# Comentar en issue
gh issue comment 456 --body "Trabajando en esto"5.2.5 Actions y CI/CD
# Ver workflows
gh workflow list
gh workflow view ci.yml
# Ver runs
gh run list
gh run view 123456
# Cancelar run
gh run cancel 123456
# Re-ejecutar workflow
gh run rerun 1234565.2.6 Casos de uso avanzados
5.2.6.1 Automatización con scripts
#!/bin/bash
# Script para crear PR automaticamente
# Verificar que estamos en un branch que no sea main
current_branch=$(git branch --show-current)
if [ "$current_branch" = "main" ]; then
echo "No puedes crear PR desde main"
exit 1
fi
# Push del branch actual
git push -u origin "$current_branch"
# Crear PR con información del branch
title=$(echo "$current_branch" | sed 's/-/ /g' | sed 's/feature\///g')
gh pr create --title "$title" --body "Resolves #issue_number"
echo "PR creado: $(gh pr view --json url --jq .url)"5.2.6.2 Release automation
#!/bin/bash
# Script para crear release automáticamente
version="$1"
if [ -z "$version" ]; then
echo "Uso: $0 <version>"
exit 1
fi
# Crear tag
git tag -a "v$version" -m "Version $version"
git push origin "v$version"
# Generar changelog automático
changelog=$(gh api repos/:owner/:repo/releases/generate-notes \
-f tag_name="v$version" \
--jq .body)
# Crear release
gh release create "v$version" \
--title "Release v$version" \
--notes "$changelog" \
--draft=false \
--prerelease=false
echo "Release v$version creado exitosamente!"5.3 node - JavaScript Runtime
Node.js permite ejecutar JavaScript fuera del navegador, siendo fundamental para desarrollo web moderno.
5.3.1 Gestión de versiones con nvm
# Instalar versión específica
nvm install 18.17.0
nvm install --lts # Última LTS
# Usar versión específica
nvm use 18.17.0
nvm use --lts
# Ver versiones instaladas
nvm list
nvm list-remote # Disponibles para instalar
# Establecer versión por defecto
nvm alias default 18.17.05.3.2 npm - Node Package Manager
5.3.2.1 Gestión de paquetes
# Inicializar proyecto
npm init
npm init -y # Con valores por defecto
# Instalar paquetes
npm install express
npm install -D jest # Como devDependency
npm install -g nodemon # Global
# Instalar desde package.json
npm install
npm ci # Para CI/CD (más rápido, determinístico)5.3.2.2 Scripts y automation
# En package.json
{
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest",
"build": "webpack --mode=production",
"lint": "eslint src/",
"format": "prettier --write src/"
}
}
# Ejecutar scripts
npm start
npm run dev
npm test
npm run build5.3.3 Desarrollo con Node.js
5.3.3.1 REPL y debugging
# REPL interactivo
node
# Ejecutar archivo
node app.js
# Debugging
node --inspect app.js
node --inspect-brk app.js # Pausar en primera línea
# Profiling
node --prof app.js
node --prof-process isolate-*.log5.3.3.2 Módulos y require
// CommonJS (Node.js tradicional)
const fs = require('fs');
const path = require('path');
const { promisify } = require('util');
// ES Modules (Node.js moderno)
import fs from 'fs/promises';
import path from 'path';
import { fileURLToPath } from 'url';5.3.4 Casos de uso prácticos
5.3.4.1 Script de automatización
#!/usr/bin/env node
// build-tool.js
const fs = require('fs/promises');
const path = require('path');
const { execSync } = require('child_process');
async function buildProject() {
console.log('🚀 Iniciando build...');
// Limpiar directorio dist
await fs.rmdir('./dist', { recursive: true }).catch(() => {});
await fs.mkdir('./dist', { recursive: true });
// Compilar TypeScript
console.log('📝 Compilando TypeScript...');
execSync('tsc --outDir dist');
// Copiar assets
console.log('📁 Copiando assets...');
await fs.cp('./src/assets', './dist/assets', { recursive: true });
// Generar package.json para producción
const pkg = JSON.parse(await fs.readFile('./package.json', 'utf8'));
const prodPkg = {
name: pkg.name,
version: pkg.version,
dependencies: pkg.dependencies,
main: 'index.js'
};
await fs.writeFile('./dist/package.json', JSON.stringify(prodPkg, null, 2));
console.log('✅ Build completado!');
}
buildProject().catch(console.error);5.3.4.2 API simple con Express
// server.js
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(helmet());
app.use(cors());
app.use(express.json());
// Logging middleware
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} ${req.method} ${req.path}`);
next();
});
// Routes
app.get('/api/health', (req, res) => {
res.json({ status: 'OK', timestamp: new Date().toISOString() });
});
app.get('/api/users', (req, res) => {
// Simulación de datos
res.json([
{ id: 1, name: 'Juan', email: 'juan@example.com' },
{ id: 2, name: 'María', email: 'maria@example.com' }
]);
});
// Error handling
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Something went wrong!' });
});
app.listen(PORT, () => {
console.log(`🚀 Server running on http://localhost:${PORT}`);
});5.4 Workflows integrados
5.4.1 Desarrollo Full-Stack
#!/bin/bash
# Script de desarrollo completo
# 1. Clonar y configurar proyecto
clone_and_setup() {
gh repo clone mi-org/mi-proyecto
cd mi-proyecto
# Instalar dependencias
npm install
# Configurar git hooks
npx husky install
# Crear branch de desarrollo
git checkout -b feature/nueva-funcionalidad
}
# 2. Desarrollo con live reload
dev_server() {
# Terminal 1: Backend
npm run dev:server &
# Terminal 2: Frontend
npm run dev:client &
# Terminal 3: Tests en watch mode
npm run test:watch &
wait
}
# 3. Pre-commit workflow
pre_commit() {
# Linting
npm run lint:fix
# Formateo
npm run format
# Tests
npm test
# Type checking
npm run type-check
if [ $? -eq 0 ]; then
echo "✅ Todo OK, procediendo con commit"
git add .
git commit -m "$1"
else
echo "❌ Errores encontrados, revisar antes de commit"
exit 1
fi
}
# 4. Deploy workflow
deploy() {
# Build de producción
npm run build
# Push y crear PR
git push -u origin "$(git branch --show-current)"
gh pr create --title "Deploy: $(date +%Y-%m-%d)" --body "Release automático"
# Esperar aprobación y merge
pr_number=$(gh pr view --json number --jq .number)
echo "PR #$pr_number creado. Esperando aprobación..."
}5.4.2 Git workflow avanzado
#!/bin/bash
# Workflow completo de Git con integración GitHub
git_workflow() {
local issue_number="$1"
local feature_name="$2"
if [ -z "$issue_number" ] || [ -z "$feature_name" ]; then
echo "Uso: git_workflow <issue_number> <feature_name>"
return 1
fi
# 1. Actualizar main
git checkout main
git pull origin main
# 2. Crear branch desde issue
branch_name="feature/${issue_number}-${feature_name}"
git checkout -b "$branch_name"
# 3. Configurar tracking
git push -u origin "$branch_name"
# 4. Asociar con issue
gh issue edit "$issue_number" --add-assignee @me
gh issue comment "$issue_number" --body "🚧 Trabajando en branch: $branch_name"
echo "✅ Branch $branch_name creado y asociado con issue #$issue_number"
echo "💡 Cuando termines, ejecuta: finish_feature $issue_number"
}
finish_feature() {
local issue_number="$1"
# 1. Push final
git push origin "$(git branch --show-current)"
# 2. Crear PR que cierre el issue
gh pr create \
--title "Resolve #$issue_number" \
--body "Closes #$issue_number" \
--reviewer team-leads
# 3. Comentar en issue
pr_url=$(gh pr view --json url --jq .url)
gh issue comment "$issue_number" --body "🎉 PR creado: $pr_url"
echo "✅ PR creado. Revisa en: $pr_url"
}
# Usar: git_workflow 123 user-authentication
Tips para desarrollo eficiente
- Configura aliases de Git para comandos frecuentes
- Usa
ghpara automatizar workflows de GitHub - Combina
git hooksconhuskypara validaciones automáticas - Mantén commits atómicos y mensajes descriptivos siguiendo Conventional Commits
Mejores prácticas
- Nunca hagas
push --forceen branches compartidos - Usa
--force-with-leaseen lugar de--forcecuando sea necesario - Mantén historial limpio con
rebaseinteractivo antes de merge - Configura firma GPG para commits verificados
En el próximo capítulo exploraremos herramientas de multimedia para procesamiento de video, audio e imágenes.