Git & GitHub
El control de versiones es la habilidad más importante que todo desarrollador web debe dominar. Git te permite rastrear cambios, colaborar con otros y revertir errores sin pánico. GitHub es la plataforma donde todo cobra vida: repositorios, pull requests, issues y documentación.
Conceptos básicos
Git es un sistema de control de versiones distribuido creado por Linus Torvalds en 2005. A diferencia de sistemas centralizados como SVN, cada desarrollador tiene una copia completa del repositorio con todo su historial de cambios. Esto significa que podés trabajar offline, commit localmente y sincronizar con el repositorio remoto cuando quieras.
GitHub es una plataforma en la nube que aloja repositorios Git y agrega funcionalidades colaborativas: interfaz web para visualizar código, sistema de issues para seguimiento de tareas, pull requests para revisar cambios antes de integrarlos, actions para automatizar flujos de trabajo, y mucho más. Es el hogar de millones de proyectos open-source y la herramienta estándar de la industria.
Para entender Git necesitas conocer sus cuatro conceptos fundamentales. Un repositorio (repo) es la carpeta de tu proyecto con todo el historial de versiones. Un commit es una "foto" del estado de tu proyecto en un momento dado, con un mensaje descriptivo de lo que cambió. Una branch (rama) es una línea de desarrollo independiente que te permite trabajar en una funcionalidad sin afectar el código principal. Un merge es la fusión de dos ramas, integrando los cambios de una branch en otra.
Repositorio
Carpeta de tu proyecto con todo el historial de cambios. Puede ser local (en tu PC) o remoto (en GitHub).
Commit
Una "foto" del estado de tu proyecto. Cada commit guarda los cambios hechos, quien los hizo, cuando y por que.
Branch
Línea de desarrollo independiente. La branch principal es main. Creas branches para trabajar en features sin afectar el código principal.
Merge & Clone
Merge fusiona los cambios de una branch en otra. Clone descarga una copia completa del repositorio remoto a tu PC.
Git vs GitHub
Git es el programa que corre en tu PC y gestiona el control de versiones localmente. GitHub es el servicio web que almacena tus repos en la nube y agrega herramientas colaborativas. No necesitas GitHub para usar Git, pero usar ambos juntos es el estándar de la industria. Existen alternativas como GitLab y Bitbucket, pero GitHub es el más popular.
Flujo de trabajo básico de Git
El flujo de trabajo con Git se basa en tres áreas o "zonas" donde vive tu código: el Working Directory (tu carpeta de proyecto, donde editas archivos), el Staging Área (un área temporal donde preparas los cambios para el próximo commit), y el Repository (la base de datos de Git con todo el historial de commits). Cada comando de Git mueve cambios entre estás tres zonas.
El ciclo básico es así: modifies archivos en tu Working Directory, usas git add para mover los cambios al Staging Área (es como decir "estos cambios quiero incluirlos en el commit"), y luego usas git commit para guardar esos cambios en el historial del repositorio local. Finalmente, git push envía los commits al repositorio remoto en GitHub. Este flujo se repite constantemente durante el desarrollo.
# ┌─────────────────────────────────────────────────┐
# │ El flujo basico de Git │
# └─────────────────────────────────────────────────┘
# 1. Working Directory → Staging Area
git add index.html # Agregar un archivo
git add css/ # Agregar una carpeta entera
git add . # Agregar TODOS los cambios
# 2. Staging Area → Repository (local)
git commit -m "feat: agregar landing page" # Crear un commit
# 3. Repository local → Repository remoto
git push origin main # Enviar commits al remoto
# 4. Repository remoto → Working Directory
git pull origin main # Bajar cambios del remoto
Las tres zonas de Git
Piensa en Git como un sistema de tres cajas: la Working Directory es tu escritorio donde editas, el Staging Área es una mesa donde pones los archivos que querés incluir en el commit, y el Repository es el archivador permanente. El comando git status te muestra en que zona están tus cambios en cada momento.
Configuración inicial
Antes de usar Git por primera vez, necesitas configurar tu identidad. Git asocia cada commit con un nombre y un email, lo que es fundamental para la trazabilidad en proyectos colaborativos. También podés configurar el editor por defecto, el nombre de la branch principal, y algunos aliases que te ahorran tiempo al escribir comandos largos.
# Configuracion obligatoria (una sola vez)
git config --global user.name "Tu Nombre"
git config --global user.email "tu@email.com"
# Branch principal como 'main' (en lugar de 'master')
git config --global init.defaultBranch main
# Editor por defecto
git config --global core.editor "code --wait"
# Verificar configuracion
git config --list
# Aliases utiles (opcionales)
git config --global alias.s "status"
git config --global alias.co "checkout"
git config --global alias.br "branch"
git config --global alias.ci "commit"
git config --global alias.st "status -sb"
GitHub CLI
Considera instalar GitHub CLI (gh) para interactuar con GitHub desde la terminal sin salir de tu flujo. Podés crear repos, abrir PRs, gestionar issues y mucho más. Se instala con brew install gh en macOS, apt install gh en Linux, o descargando el instalador de cli.github.com.
Comandos esenciales
Estos son los comandos que usaras en el 90% de tu trabajo diario con Git. Dominarlos significa poder manejar prácticamente cualquier situación de control de versiones. No necesitas memorizarlos todos de una vez; con la práctica se vuelven naturales y automatizados en tu flujo de trabajo.
Creando repositorios
Podés crear un repositorio Git de dos formas: inicializando una carpeta existente con git init o clonando un repositorio existente con git clone. Si estás empezando un proyecto desde cero, usa git init. Si vas a contribuir a un proyecto que ya existe en GitHub, usa git clone para descargarlo.
# Inicializar un repo nuevo en la carpeta actual
git init
# Clonar un repositorio remoto
git clone https://github.com/usuario/repo.git
# Clonar en una carpeta con nombre custom
git clone https://github.com/usuario/repo.git mi-carpeta
# Clonar solo el ultimo commit (mas rapido, sin historial)
git clone --depth 1 https://github.com/usuario/repo.git
Inspeccionando el estado
Los comandos de inspección son los que más vas a usar. git status te muestra que archivos fueron modificados, cuales están en el staging área y cuales no son rastreados por Git. git log muestra el historial de commits con detalles como autor, fecha y mensaje. git diff te muestra exactamente que líneas cambiaron, línea por línea.
# Estado actual del repo
git status
# Historial de commits (detallado)
git log
# Historial compacto (una linea por commit)
git log --oneline
# Historial con grafico de branches
git log --oneline --graph --all
# Ver cambios en archivos del Working Directory
git diff
# Ver cambios en el Staging Area
git diff --staged
# Ver cambios de un archivo especifico
git diff index.html
Agregando y confirmando cambios
git add es el comando que mueve archivos del Working Directory al Staging Área. Podés agregar archivos individuales, carpetas enteras, o usar el punto (.) para agregar todo. git commit crea un nuevo punto de guardado en el historial con los cambios que están en el staging área. El flag -m permite escribir el mensaje directamente en la línea de comandos, mientras que -a agrega automáticamente todos los archivos modificados (solo los que ya son rastreados).
# Agregar un archivo al staging
git add index.html
# Agregar todos los cambios
git add .
# Agregar interactivo (elige que cambios incluir)
git add -p
# Commit con mensaje
git commit -m "feat: agregar estructura del hero"
# Commit con staged + modificados (sin archivos nuevos)
git commit -am "fix: corregir color del boton"
# Modificar el ULTIMO commit (sin crear uno nuevo)
git commit --amend -m "mensaje corregido"
Sincronizando con el remoto
git push envía tus commits locales al repositorio remoto en GitHub. git pull hace lo opuesto: baja los cambios del remoto y los integra en tu branch local. Si hay conflictos (ambos modificaron las mismas líneas), Git te pedirá que los resuelvas manualmente. git fetch solo baja la información sin integrarla, útil para revisar que hay en el remoto antes de hacer merge.
# Enviar commits al remoto
git push origin main
# Enviar una nueva branch al remoto
git push -u origin feature/nombre
# Bajar e integrar cambios del remoto
git pull origin main
# Solo bajar cambios (sin integrar)
git fetch origin
# Ver diferencias con el remoto antes de pull
git fetch origin && git diff main origin/main
Siempre hacé pull antes de push
Si trabajas en equipo, siempre hacé git pull antes de git push. Esto evita conflictos y asegurarse de que estás integrando los cambios más recientes de tus compañeros. Si hay conflictos, Git te lo indicará y tendrás que resolverlos archivo por archivo antes de completar el merge.
Renombrar y mover archivos
Tarde o temprano vas a necesitar renombrar un archivo: quizás te equivocaste de nombre, o querés estandarizar la nomenclatura del proyecto. La primera tentación es ir a GitHub y hacerlo desde ahí, pero no podés renombrar archivos directamente desde la interfaz web de GitHub. Tenés que hacerlo desde tu terminal local.
El comando correcto es git mv, que le dice a Git que el archivo fue renombrado (no borrado y creado de nuevo). Esto es importante porque git mv preserva el historial del archivo: Git entiende que es el mismo archivo con otro nombre. Si en cambio borras el archivo y creás uno nuevo con el nombre deseado, Git los trata como dos archivos distintos y perdés la conexión con el historial anterior.
# Navegar a tu repositorio local
cd path/to/your/repository
# Renombrar un archivo (preserva el historial)
git mv old-image-name.png new-image-name.png
# Mover un archivo a otra carpeta
git mv index.html pages/index.html
# Renombrar y mover al mismo tiempo
git mv css/old-styles.css styles/main.css
# Commitear el cambio
git commit -m "rename: renombrar archivo de imagen"
# Subir al remoto (reemplaza 'main' por tu branch si es diferente)
git push origin main
No renombres desde el explorador de archivos
Si renombras un archivo desde tu explorador de archivos (Finder, Explorer, Nautilus) sin usar git mv, Git lo ve como una eliminación del archivo viejo y la creación de uno nuevo. Vas a tener que hacer git add del archivo nuevo y git rm del viejo manualmente, y el historial se corta. Si ya lo hiciste, no entra en pánico: podés corregirlo haciendo git add -A antes de commitear, o usando git mv para deshacer el desastre.
git mv también sirve para mover archivos entre carpetas, no solo para cambiarles el nombre. De hecho, renombrar y mover son la misma operación para Git: en ambos casos el archivo cambia de path. Podés combinar ambas cosas en un solo comando, como en el ejemplo de mover css/old-styles.css a styles/main.css.
Branching (Ramas)
Las branches son una de las características más poderosas de Git. Te permiten crear líneas de desarrollo paralelas: podés trabajar en una nueva funcionalidad, arreglar un bug o experimentar con una idea, todo sin afectar el código principal (main). Cuando el trabajo está listo, fusionas (merge) tu branch en main. Esto es la base del flujo de trabajo colaborativo.
La convención más común es crear una branch por cada funcionalidad o fix, con un nombre descriptivo. Por ejemplo: feature/login-modal, fix/header-responsive, docs/readme-update. Estos prefijos ayudan al equipo a entender el propósito de cada branch de un vistazo.
# Listar branches
git branch
# Crear una nueva branch
git branch feature/nombre
# Crear y cambiar a la nueva branch (en un paso)
git checkout -b feature/nombre
# Cambiar a una branch existente
git checkout main
# o con el comando mas nuevo:
git switch main
# Fusionar una branch en la actual
git merge feature/nombre
# Eliminar una branch ya fusionada
git branch -d feature/nombre
# Eliminar una branch del remoto
git push origin --delete feature/nombre
checkout vs switch
git switch fue introducido en Git 2.23 (2019) como una alternativa más segura a git checkout. Mientras que checkout hace muchas cosas (cambiar branch, crear branch, restaurar archivos), switch solo cambia de branch. Se recomienda usar switch para evitar errores. Ambos funcionan, pero switch es más explícito.
Resolviendo conflictos de merge
Los conflictos ocurren cuando Git no puede fusionar automáticamente dos versiones de un archivo porque las mismas líneas fueron modificadas en ambas branches. Cuando esto pasa, Git marca las secciones en conflicto dentro del archivo con separadores especiales. Tu trabajo como desarrollador es abrir el archivo, decidir que versión queda, y luego hacer commit del resultado.
<h1>Bienvenido a mi sitio</h1>
<p>Este es un parrafo de ejemplo.</p>
<!-- Git marca los conflictos asi: -->
<<<<<<< HEAD
<p>Version de la branch main.</p>
=======
<p>Version de la branch feature.</p>
>>>>>>> feature/nombre
<!-- Elegis una version, borras los marcadores y haces commit -->
Cuidado con git push --force
Nunca uses git push --force en branches compartidas (main, develop). Esto reescribe el historial y puede causar problemas graves para tus compañeros. Solo es aceptable en tu propia branch de trabajo (feature branch), y preferiblemente usa --force-with-lease que es más seguro porque verifica que nadie más haya subido cambios.
GitHub
GitHub es mucho más que un hosting de repositorios Git. Es una plataforma de desarrollo colaborativo con herramientas para gestionar proyectos, revisar código, rastrear bugs, documentar y automatizar flujos de trabajo. Entender estás herramientas te hará un desarrollador más completo y productivo, capaz de participar en proyectos open-source o trabajar en equipos de manera profesional.
Repositorios en GitHub
Un repositorio en GitHub es la versión "en la nube" de tu proyecto. Además del código, puede contener documentación (README.md), licencia (LICENSE), guía de contribución (CONTRIBUTING.md), issues, pull requests, y configuración de CI/CD. Cuando creas un repo público, cualquier persona puede verlo, clonarlo y contribuir. Los repos privados son solo para ti y los colaboradores que invites.
README.md
El README.md es la carta de presentación de tu proyecto. Es lo primero que ven las personas cuando visitan tu repo, y un buen README marca la diferencia entre un proyecto que parece serio y uno que parece abandonado. Debe incluir: nombre del proyecto con descripción breve, capturas de pantalla, instrucciones de instalación y uso, requisitos previos, estructura del proyecto, como contribuir, licencia, y créditos.
.gitignore
El archivo .gitignore le dice a Git que archivos y carpetas debe ignorar (no rastrear). Esto es fundamental para no subir archivos temporales, dependencias, credenciales o archivos generados automáticamente. Cada lenguaje y framework tiene sus propias convenciónes de .gitignore. Podés encontrar templates en github/gitignore.
# Dependencias
node_modules/
vendor/
# Archivos generados
dist/
build/
.min.js
.min.css
# Archivos de sistema
.DS_Store
Thumbs.db
# Variables de entorno (NUNCA subir credenciales)
.env
.env.local
# Logs
*.log
npm-debug.log*
Pull Requests (PRs)
Un Pull Request es una propuesta para fusionar cambios de una branch en otra, generalmente en main. Es la herramienta central de colaboración en GitHub: permite a otros revisar tu código, comentar líneas específicas, sugerir cambios, y aprobar o rechazar la integración. Un buen PR incluye un título claro, descripción detallada de los cambios, capturas si hay cambios visuales, y referencia al issue correspondiente.
# 1. Crear branch y trabajar
git checkout -b feature/hero-section
# 2. Hacer commits
git add .
git commit -m "feat: agregar hero section con gradiente"
# 3. Subir la branch al remoto
git push -u origin feature/hero-section
# 4. Crear Pull Request (via GitHub CLI)
gh pr create --title "feat: agregar hero section" \
--body "Agrega el hero section con gradiente y animaciones"
# 5. O crearlo desde la interfaz web de GitHub
Issues
Los Issues son la herramienta de seguimiento de tareas de GitHub. Sirven para reportar bugs, proponer nuevas funcionalidades, hacer preguntas, o documentar tareas pendientes. Cada issue tiene un título, descripción, etiquetas (labels), asignados, y estado (abierto/cerrado). La mejor práctica es vincular issues con commits y PRs usando #numero-issue en los mensajes de commit, así GitHub los cierra automáticamente al mergear.
Bug Report
Reportar un error: describe el problema, pasos para reproducirlo, comportamiento esperado vs actual, capturas de pantalla. Usa labels como bug y priority.
Feature Request
Proponer una funcionalidad: describe la idea, el caso de uso, posibles soluciones. Usa labels como enhancement y discussion.
Tareas
Organizar el trabajo: divide features en tareas pequeñas, asigna responsables, define milestones para agrupar issues por objetivo o sprint.
Cerrar issues automáticamente
Si incluyes Closes #42 o Fixes #42 en el cuerpo de un PR o en un mensaje de commit, GitHub cerrará automáticamente el issue #42 cuando el PR sea mergeado. Esto crea un vínculo directo entre tu código y la tarea que resuelve.
Convenciones de commit
Las convenciónes de commit son reglas para escribir mensajes de commit claros y consistentes. El estándar más popular es Conventional Commits, que usa un prefijo que indica el tipo de cambio seguido de una descripción breve. Esto no solo mejora la legibilidad del historial, sino que permite generar automáticamente un changelog, detectar breaking changes y filtrar commits por tipo.
# Formato: <tipo>(<scope>): <descripcion>
feat: agregar hero section con animacion
fix: corregir padding del sidebar en mobile
docs: actualizar README con instrucciones de deploy
style: aplicar formato a variables.css
refactor: simplificar logica del theme toggle
perf: lazy loading de imagenes en landing
test: agregar tests para common-loader
chore: actualizar dependencias
ci: configurar GitHub Actions
build: comprimir assets para produccion
| Prefijo | Significado | Cuando usarlo |
|---|---|---|
feat |
Nueva funcionalidad | Cuando agregas algo nuevo al proyecto |
fix |
Corrección de bug | Cuando arreglas algo que estaba roto |
docs |
Documentación | Cuando cambiás README, comentarios o docs |
style |
Estilo de código | Formato, sangría, puntos y coma (sin cambio de lógica) |
refactor |
Refactorización | Cambiás código sin cambiar comportamiento |
perf |
Performance | Optimizaciones de velocidad o memoria |
test |
Tests | Agregar o modificar tests |
chore |
Tareas de mantenimiento | Actualizar deps, limpiar archivos, configs |
Commit semver
Los prefijos feat y fix corresponden a MINOR y PATCH en Semantic Versioning (semver). Si un feat es un breaking change (rompe compatibilidad), se agrega ! al tipo: feat!: cambiar API de endpoints, lo que corresponde a MAJOR. Herramientas como standard-version o semantic-release pueden automatizar el versionado.
Comandos avanzados útiles
Más allá de los comandos básicos, Git tiene un arsenal de herramientas que te salvan de situaciónes complicadas. No necesitas memorizarlas todas hoy, pero saber que existen te dará confianza cuando las necesites. Estos son los más útiles para el día a día de un desarrollador web.
# ┌─────────────────────────────────────────────────┐
# │ Comandos de rescate │
# └─────────────────────────────────────────────────┘
# Deshacer cambios en Working Directory (no staged)
git checkout -- archivo.html
# o mas nuevo:
git restore archivo.html
# Sacar archivos del Staging Area
git restore --staged archivo.html
# Ver el contenido de un commit especifico
git show abc1234
# Ver quien modifico cada linea de un archivo
git blame archivo.html
# Crear un tag (para versiones)
git tag v1.0.0
git push origin v1.0.0
# Guardar cambios temporales (como un "pausa")
git stash
git stash pop # Restaurar los cambios guardados
git stash list # Ver stash guardados
# Limpiar archivos no rastreados
git clean -n # Preview de lo que se borraria
git clean -f # Borrar archivos no rastreados
git stash: tu amigo secreto
git stash es increíblemente útil cuando estás en medio de un trabajo, necesitas cambiar de branch urgentemente, pero no querés commitear código a medio hacer. git stash guarda tus cambios temporales y deja el working directory limpio. Cuando vuelves a tu branch, git stash pop restaura todo donde lo dejaste.
Fork & Contribuir a Open Source
Contribuir a open source es una de las mejores formas de aprender y crecer como desarrollador. El flujo típico es: encontrar un proyecto que te interese, hacer un fork (crear una copia del repo en tu cuenta de GitHub), clonar tu fork a tu PC, crear una branch para tu cambio, hacer commits, subir tu branch a tu fork, y luego abrir un Pull Request hacia el repo original. El maintainer revisará tus cambios y decidirá si los integra.
# 1. Fork el repo desde GitHub (boton "Fork" en la web)
# 2. Clonar TU fork a tu PC
git clone https://github.com/TU-USUARIO/proyecto.git
cd proyecto
# 3. Agregar el repo original como "upstream"
git remote add upstream https://github.com/usuario-original/proyecto.git
# 4. Crear branch para tu contribucion
git checkout -b fix/typo-readme
# 5. Hacer cambios y commits
git add .
git commit -m "docs: corregir typo en README"
# 6. Subir a TU fork
git push -u origin fix/typo-readme
# 7. Abrir PR desde tu fork al repo original
gh pr create --repo usuario-original/proyecto \
--title "docs: corregir typo en README" \
--body "Corrige un typo en la seccion de instalacion"
# 8. Mantener tu fork actualizado
git fetch upstream
git merge upstream/main
Buena suerte empezando
Para tu primera contribución open-source, busca repos que tengan labels como good first issue o help wanted. Son issues que los maintainers marcaron como amigables para principiantes. Leer el CONTRIBUTING.md del proyecto antes de empezar es siempre una buena idea, y no temas preguntar si algo no está claro.
Probá en MiniDevTools
Si querés experimentar con lo que vimos en esta sección, probá el Diff Viewer.