Git y GitHub desde cero: control de versiones sin miedo
Arnold Wender · · 12 min de lectura
Ver todo: Programación“¿Por qué mi código de ayer ya no funciona y no sé qué cambié?”
Si alguna vez guardaste versiones con nombres como proyecto-final.zip, proyecto-final-v2.zip, proyecto-final-ESTEESELVERDADERO.zip, entiendes el problema. Git existe exactamente para resolver eso — y lo hace de una forma que, una vez que entiendes el modelo mental, no querrás trabajar sin él.
Este artículo no es una lista de comandos para copiar y pegar. Es una explicación de por qué Git funciona como funciona, para que los comandos tengan sentido y no sean magia negra.
Lo esencial antes de empezar
- Git es local primero — trabajas en tu máquina sin necesidad de internet; GitHub es donde compartes ese trabajo con otros o con el mundo
- Un commit es una fotografía del estado de tus archivos en un momento concreto, no solo un “guardado”
- Las ramas son baratas — crear una rama en Git es casi instantáneo y no duplica archivos; úsalas sin miedo
mergeyrebasehacen lo mismo de formas distintas —mergepreserva la historia completa,rebasela reescribe en lineal- Password authentication en GitHub murió en 2021 — hoy usas SSH o tokens fine-grained; no hay opción intermedia
- Git 2.54 (abril 2026) es la versión estable actual; Git 3.0 con SHA-256 por defecto llega a finales de 2026
Para recursos del ecosistema completo de desarrollo, visita Programación en Geekshop.
El problema que Git resuelve (y por qué importa entenderlo)
Antes de abrir la terminal, entiende esto: Git no es una herramienta de respaldo. Es un sistema de control de versiones distribuido. La diferencia es enorme.
Un respaldo guarda el estado actual de tus archivos. Git guarda la historia completa de todos los cambios, quién los hizo, cuándo, y por qué — con la posibilidad de volver a cualquier punto de esa historia, comparar estados, ramificarte para experimentar sin romper nada, y fusionar el trabajo de múltiples personas sin que se pisen.
Ese “distribuido” significa que cada persona que tiene el repositorio tiene una copia completa de toda la historia. No hay un servidor central que, si se cae, te deja sin nada. GitHub, GitLab y Bitbucket son plataformas de alojamiento remoto — convenientes, pero no obligatorias para que Git funcione.
EL MODELO MENTAL
Snapshots, no diferencias
La mayoría de la gente asume que Git guarda los cambios entre versiones (un “diff”). Técnicamente lo comprime así, pero el modelo mental correcto es diferente: Git guarda snapshots completos del estado de tus archivos en cada commit.
Cuando haces git commit, Git toma una fotografía de todos los archivos que le indicaste y la almacena con un identificador único (un hash SHA-1, próximamente SHA-256 por defecto en Git 3.0). Ese hash depende del contenido, del autor, de la fecha y del commit anterior — lo que hace prácticamente imposible modificar la historia sin que Git lo detecte.
Esto tiene una consecuencia importante: los commits son inmutables. No editas un commit existente; creas uno nuevo. Cuando haces git commit --amend, en realidad estás reemplazando el último commit por uno nuevo con diferente hash. El original sigue existiendo hasta que el garbage collector lo limpia.
Instalación y configuración inicial
Git 2.54.0 es la versión estable actual (lanzada en abril de 2026). Instálala desde git-scm.com o via tu gestor de paquetes:
# macOS con Homebrew
brew install git
# Ubuntu / Debian
sudo apt update && sudo apt install git
# Fedora / RHEL
sudo dnf install git
# Verifica la versión instalada
git --version
Lo primero que debes hacer después de instalar es presentarte:
git config --global user.name "Tu Nombre"
git config --global user.email "tu@email.com"
# Nombra la rama principal "main" (el estándar actual)
git config --global init.defaultBranch main
# Editor para mensajes de commit (cambia nano por vim, code, etc.)
git config --global core.editor nano
Esta configuración se guarda en ~/.gitconfig y aplica a todos tus repositorios. Para un proyecto específico, omite --global.
El flujo básico: init, add, commit
EL FLUJO FUNDAMENTAL
Working directory → Staging → Repositorio
Git maneja tres zonas que todo principiante confunde:
Working directory: tu carpeta normal, los archivos que ves y editas. Git los observa pero no hace nada automáticamente.
Staging area (índice): una zona intermedia donde preparas exactamente qué va en el próximo commit. Con git add <archivo> mueves cambios al staging. Esto te permite hacer commits quirúrgicos: cambias diez archivos pero solo commiteas tres que forman una unidad lógica.
Repositorio (.git): donde viven los commits. Una vez que haces git commit, el snapshot queda grabado en la historia permanente del proyecto.
# Inicializar un repo nuevo
git init mi-proyecto
cd mi-proyecto
# Ver el estado actual (tu comando más usado)
git status
# Rastrear un archivo nuevo o agregar cambios al staging
git add archivo.py
# Agregar todos los cambios del directorio actual
git add .
# Hacer el commit (siempre con un mensaje descriptivo)
git commit -m "Agrega función de autenticación con JWT"
# Ver el historial de commits
git log --oneline Ramas: experimenta sin romper nada
Las ramas son el superpoder de Git que más tarda en “hacer clic” para los principiantes. Una rama no es una copia del proyecto; es simplemente un puntero que apunta a un commit específico. Crear una rama es literalmente crear un archivo de texto con un hash dentro. Por eso es instantáneo.
# Ver todas las ramas locales
git branch
# Crear una rama nueva y moverse a ella
git checkout -b feature/login-oauth
# Forma moderna (Git 2.23+): switch en lugar de checkout
git switch -c feature/login-oauth
# Moverse entre ramas existentes
git switch main
# Listar ramas incluyendo las remotas
git branch -a
El flujo estándar en equipos es el GitHub Flow: trabajas en una rama por feature, cuando está lista abres un Pull Request en GitHub para revisión, y después de aprobarse se hace merge a main.
Una rama de Git no duplica archivos ni consume espacio significativo. Es solo un puntero. Créalas sin pensarlo dos veces para cualquier cosa que no sea trivial.
Merge vs Rebase: la pregunta que siempre confunde
Ambos integran cambios de una rama a otra. La diferencia es cómo queda el historial.
| Estrategia | Historial | Cuándo usarla |
|---|---|---|
git merge |
Preserva todos los commits, agrega un “merge commit” | Ramas compartidas con otros, historial fiel de qué pasó |
git merge --squash |
Aplana todos los commits en uno antes de fusionar | PRs pequeños, historial más limpio en main |
git rebase |
Reescribe los commits encima de la rama destino, historial lineal | Ramas locales que aún no has compartido, para mantener historial limpio |
git cherry-pick |
Trae un commit específico de otra rama | Cuando solo necesitas uno o dos commits, no la rama entera |
# Situación: estás en feature/login, quieres traer cambios de main
git switch feature/login
# Opción 1: merge (preserva historia)
git merge main
# Opción 2: rebase (reescribe tu rama encima de main)
git rebase main
# Después del rebase, si ya habías subido la rama, necesitas force push
git push --force-with-lease origin feature/login
Conectar con GitHub: autenticación en 2026
GitHub eliminó la autenticación por contraseña para operaciones Git en agosto de 2021. En 2026 tienes dos opciones reales:
SSH (recomendado para uso diario en tu máquina):
# Generar un par de llaves SSH (usa ed25519, más seguro que RSA)
ssh-keygen -t ed25519 -C "tu@email.com"
# Copiar la llave pública al portapapeles (macOS)
pbcopy < ~/.ssh/id_ed25519.pub
# En Linux
cat ~/.ssh/id_ed25519.pub
Luego ve a GitHub → Settings → SSH and GPG keys → New SSH key y pega la llave pública.
Fine-grained Personal Access Token (para scripts, CI/CD, herramientas):
Ve a GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens. GitHub recomienda los fine-grained tokens sobre los clásicos porque permiten restringir exactamente a qué repositorios y permisos tiene acceso el token.
El flujo remoto: push, pull, fetch y clone
# Clonar un repositorio existente de GitHub
git clone git@github.com:usuario/repositorio.git
# Conectar un repo local a uno remoto (después de git init)
git remote add origin git@github.com:usuario/mi-proyecto.git
# Subir cambios al remoto (primera vez, establece el tracking)
git push -u origin main
# Subir cambios después del primer push
git push
# Descargar cambios del remoto sin integrarlos
git fetch origin
# Descargar E integrar cambios (fetch + merge)
git pull
# Ver el estado de los remotos configurados
git remote -v
La diferencia entre fetch y pull importa: fetch es seguro, solo actualiza tu información sobre el remoto. pull hace el fetch y además integra los cambios — que puede generar conflictos si tienes trabajo local. Si dudas, haz fetch primero y revisa con git log origin/main antes de integrar.
COLABORACIÓN
Pull Requests: la revisión de código como flujo de trabajo
Un Pull Request (PR) en GitHub es una solicitud para integrar una rama a otra, con una interfaz para discutir los cambios línea por línea antes de hacer el merge.
El flujo típico en un equipo o proyecto open source:
- Haces fork del repositorio (si no tienes acceso directo) o creas una rama
- Haces tus cambios en commits descriptivos
- Subes la rama a GitHub con
git push -u origin feature/mi-feature - En GitHub, abres un Pull Request de tu rama hacia
main - Los revisores hacen comentarios, tú respondes con más commits
- Cuando hay aprobación, se hace merge
Los PRs son también donde entran las GitHub Actions: pruebas automáticas que deben pasar antes de que el PR pueda mergearse, revisión de estilo de código, cobertura, etc.
Tabla de comandos esenciales de referencia
| Comando | Qué hace |
|---|---|
git init |
Inicializa un repositorio Git en el directorio actual |
git clone <url> |
Clona un repositorio remoto completo (con toda su historia) |
git status |
Muestra el estado actual: archivos modificados, en staging, sin rastrear |
git add <archivo> |
Mueve cambios al staging area |
git add -p |
Staging interactivo por bloques (útil para commits quirúrgicos) |
git commit -m "mensaje" |
Crea un commit con el contenido del staging |
git log --oneline |
Historial de commits compacto |
git diff |
Cambios en working directory (sin stagear) |
git diff --staged |
Cambios que ya están en staging |
git stash |
Guarda temporalmente cambios sin commitear |
git stash pop |
Restaura el último stash |
git reset HEAD~1 |
Deshace el último commit, mantiene los cambios en working directory |
git revert <hash> |
Crea un nuevo commit que deshace los cambios de uno anterior (seguro en ramas compartidas) |
Errores comunes (y cómo no cometer los clásicos)
Siguientes pasos: cuando ya dominas lo básico
Una vez que el flujo básico — init, add, commit, push, branch, merge — es reflejo muscular, el siguiente nivel lógico es configurar bien tu entorno: aliases de Git en tu .gitconfig, un prompt que te muestra la rama actual, y las herramientas CLI que hacen el flujo diario más rápido. Todo eso lo cubre configurar tu terminal y dotfiles.
Si todavía estás eligiendo en qué lenguaje vas a usar Git principalmente, la guía sobre qué lenguaje de programación aprender primero te da el contexto para esa decisión sin el hype usual.
FAQ
¿Cuál es la diferencia entre Git y GitHub?
Git es el software de control de versiones que corre en tu máquina — libre, local, sin necesitar internet. GitHub es una plataforma web que aloja repositorios Git y añade capas de colaboración: Pull Requests, Issues, Actions, Codespaces, etc. Puedes usar Git sin GitHub perfectamente; muchos equipos usan GitLab o Bitbucket, o incluso su propio servidor. Lo que no puedes es usar GitHub sin Git.
¿Debo aprender la línea de comandos o puedo usar la interfaz gráfica?
Aprende la terminal primero. No porque las GUIs (GitHub Desktop, GitKraken, la integración de VS Code) sean malas — son útiles y las vas a usar — sino porque la terminal te da visibilidad completa de lo que Git está haciendo. Cuando algo falla, entender los comandos es la única forma de diagnosticar el problema. Una vez que los comandos base son reflejo, las GUIs te ahorran tiempo en operaciones visuales como revisar diffs o resolver conflictos.
¿Qué hago si rompí algo y quiero volver atrás?
Depende de dónde rompiste:
- Cambios sin commitear:
git checkout -- <archivo>ogit restore <archivo>los descarta - Último commit que aún no subiste:
git reset HEAD~1deshace el commit pero mantiene los cambios - Commit que ya subiste:
git revert <hash>crea un nuevo commit que deshace los cambios; esto es seguro para ramas compartidas - Commit que ya subiste y necesitas quitar del historial:
git reset --hard <hash>+git push --force-with-lease— peligroso en ramas compartidas, comunicar antes
¿Para qué sirven los tags en Git?
Un tag es un puntero con nombre a un commit específico — a diferencia de una rama, no se mueve. Se usan para marcar versiones de lanzamiento: git tag -a v1.0.0 -m "Primera versión estable". Los tags se suben por separado: git push origin --tags. GitHub los lista en la sección Releases del repositorio y permite descargar snapshots del código en ese punto.
¿Rebase interactivo para qué sirve?
git rebase -i HEAD~3 te abre un editor donde puedes reordenar, editar, fusionar (squash) o eliminar los últimos 3 commits antes de subirlos. Es la herramienta para limpiar una serie de commits de trabajo (muchos “wip” y “fix typo”) en un historial coherente antes de abrir un PR. Solo úsalo con commits que aún no has subido al remoto.
Fuentes
Las versiones y el roadmap de Git se apoyan en la fuente oficial del proyecto:
- Git — Proyecto Git (versión estable actual y transición a SHA-256 / Git 3.0)