Git es un sistema de control de versiones distribuido. Fue creado en 2005 por Linus Torvalds (el mismo que creó Linux) para gestionar el desarrollo del kernel de Linux.
En términos simples: Git guarda un historial completo de todos los cambios que ocurren en tu proyecto. Puedes:
- Volver a cualquier versión anterior de tu código
- Trabajar en paralelo en múltiples funcionalidades sin interferir
- Colaborar con otros desarrolladores de forma ordenada
- Saber quién cambió qué, cuándo y por qué
Git ≠ GitHub. Git es la herramienta local que corre en tu máquina. GitHub, GitLab y Bitbucket son plataformas en la nube que alojan repositorios Git y añaden herramientas de colaboración.

Conceptos clave
Antes de entrar a los comandos, conviene tener claros estos términos:
| Término | Significado |
|---|---|
| Repositorio (repo) | Carpeta del proyecto rastreada por Git, incluyendo todo su historial |
| Commit | Una «foto» del estado del proyecto en un momento dado |
| Branch (rama) | Una línea de desarrollo independiente |
| HEAD | El punto actual donde estás trabajando en el historial |
| Staging area | Zona intermedia donde preparas los cambios antes de hacer commit |
| Remote | Un repositorio alojado en un servidor (GitHub, GitLab, etc.) |
| Clone | Copia local de un repositorio remoto |
| Fork | Copia de un repositorio en tu cuenta de GitHub para modificarlo independientemente |
| Merge | Unir los cambios de una rama a otra |
| Rebase | Reescribir el historial de commits sobre una nueva base |
| Conflict | Situación donde dos cambios incompatibles se encuentran al hacer merge |
Instalación y configuración
Instalación
Windows: Descarga desde git-scm.com. Incluye Git Bash.
macOS:
# Con Homebrew (recomendado)
brew install git
# O simplemente ejecuta git en la terminal y macOS te pedirá instalarlo
git --version
Linux (Debian/Ubuntu):
sudo apt update && sudo apt install git
Configuración inicial
Se hace una sola vez por máquina:
# Identidad
git config --global user.name "Tu Nombre"
git config --global user.email "tu@email.com"
# Editor por defecto (VS Code, Vim, Nano, etc.)
git config --global core.editor "code --wait" # VS Code
git config --global core.editor "nano" # Nano
# Nombre de la rama principal
git config --global init.defaultBranch main
# Colores en la terminal
git config --global color.ui auto
# Ver toda la configuración
git config --list
Configuración por proyecto
Si necesitas usar credenciales distintas en un proyecto específico (por ejemplo, trabajo vs. personal), omite --global:
git config user.email "trabajo@empresa.com"
Iniciar un repositorio
Proyecto nuevo
mkdir mi-proyecto
cd mi-proyecto
git init
Esto crea una carpeta oculta .git/ que contiene todo el historial. No la borres.
Proyecto existente en remoto
git clone https://github.com/usuario/repositorio.git
# Clonar en una carpeta con nombre distinto
git clone https://github.com/usuario/repositorio.git mi-carpeta
# Clonar solo una rama específica
git clone -b nombre-rama https://github.com/usuario/repositorio.git
El ciclo de vida de los archivos
Los archivos en Git tienen cuatro estados posibles:
Untracked → Staged → Committed
↑ ↑
(nuevo) (git add) (git commit)
↑
Modified (archivo ya rastreado pero con cambios)
- Untracked: archivo nuevo que Git no conoce todavía
- Modified: archivo que Git conoce y que ha sido modificado
- Staged: cambio preparado para el próximo commit
- Committed: cambio guardado permanentemente en el historial
Comandos esenciales
Verificar estado
git status # Estado completo
git status -s # Estado resumido (short)
Agregar al staging area
git add archivo.txt # Un archivo
git add carpeta/ # Una carpeta completa
git add . # Todo lo modificado y nuevo
git add -p # Interactivo: elegir qué partes de cada archivo agregar
Hacer un commit
git commit -m "Mensaje descriptivo"
# Agregar al staging y hacer commit en un paso (solo archivos ya rastreados)
git commit -am "Mensaje"
# Abrir el editor para un mensaje más largo
git commit
# Modificar el último commit (antes de hacer push)
git commit --amend -m "Mensaje corregido"
git commit --amend --no-edit # Mismo mensaje, solo añade los cambios en staging
Ver el historial
git log # Historial completo
git log --oneline # Una línea por commit
git log --oneline --graph # Con visualización de ramas
git log -5 # Últimos 5 commits
git log --author="Nombre" # Filtrar por autor
git log --since="2 weeks ago" # Filtrar por fecha
git log -- archivo.txt # Historial de un archivo
Ver diferencias
git diff # Cambios no staged
git diff --staged # Cambios en staging vs. último commit
git diff rama1 rama2 # Diferencia entre dos ramas
git diff abc123 def456 # Diferencia entre dos commits (usar sus hashes)
Ramas (Branches)
Las ramas permiten trabajar en paralelo sin afectar el código principal.
Gestión básica
git branch # Listar ramas locales
git branch -a # Listar locales y remotas
git branch nueva-rama # Crear rama
git switch nueva-rama # Cambiar a esa rama (forma moderna)
git checkout nueva-rama # Cambiar de rama (forma clásica, aún válida)
git switch -c nueva-rama # Crear y cambiar en un paso
git checkout -b nueva-rama # Equivalente clásico
git branch -d rama # Eliminar rama (segura, solo si fue mergeada)
git branch -D rama # Eliminar rama forzado
git branch -m nuevo-nombre # Renombrar la rama actual
Ver información de ramas
git branch -v # Ver el último commit de cada rama
git branch --merged # Ramas ya fusionadas con la actual
git branch --no-merged # Ramas sin fusionar
Fusionar cambios: Merge y Rebase
Merge
Toma los cambios de una rama y los une a la rama actual. Preserva el historial completo.
# Estando en main, traer los cambios de feature
git switch main
git merge feature/login
# Merge sin fast-forward (siempre crea un commit de merge)
git merge --no-ff feature/login
# Cancelar un merge con conflictos
git merge --abort
Resolver conflictos de merge:
Cuando Git no puede fusionar automáticamente, marca los archivos así:
<<<<<<< HEAD
código de tu rama actual
=======
código de la otra rama
>>>>>>> feature/login
Debes editar el archivo manualmente, quedarte con lo correcto, y luego:
git add archivo-con-conflicto.txt
git commit
Rebase
Mueve o «replanta» una rama sobre otra. Produce un historial más limpio y lineal.
# Estando en feature, rebasear sobre main
git switch feature/login
git rebase main
# Interactivo: reescribir, combinar o reordenar commits
git rebase -i HEAD~3 # Últimos 3 commits
En el rebase interactivo puedes usar:
pick— mantener el commit tal cualreword— cambiar el mensajesquash— combinar con el commit anteriordrop— eliminar el commit
⚠️ Regla de oro: nunca hagas rebase de ramas que ya están en el remoto y otras personas están usando. Reescribir el historial compartido genera problemas serios.

Repositorios remotos
Configurar remotos
git remote add origin https://github.com/usuario/repo.git
git remote -v # Ver remotos configurados
git remote rename origin upstream # Renombrar un remoto
git remote remove origin # Eliminar un remoto
git remote set-url origin nueva-url # Cambiar la URL
Subir y bajar cambios
# Subir cambios
git push origin main
git push -u origin main # -u establece el upstream (solo la primera vez)
git push # Después de -u, basta con esto
# Subir una nueva rama al remoto
git push origin nueva-rama
# Subir y eliminar rama en remoto
git push origin --delete rama-remota
# Forzar push (peligroso, úsalo con cuidado)
git push --force-with-lease # Más seguro que --force
# Traer cambios
git fetch origin # Descarga cambios pero NO los aplica
git pull origin main # Descarga y aplica (fetch + merge)
git pull --rebase # Descarga y aplica con rebase en lugar de merge
Seguir ramas remotas
# Crear una rama local que sigue a una remota
git switch -t origin/feature/login
# Ver qué ramas locales siguen a cuáles remotas
git branch -vv
Deshacer cambios
Esta es una de las partes más importantes y más confusas de Git.
Antes del staging (working directory)
# Descartar cambios de un archivo (volver al último commit)
git restore archivo.txt # Forma moderna
git checkout -- archivo.txt # Forma clásica
# Descartar todos los cambios no staged
git restore .
En el staging area
# Sacar un archivo del staging sin perder los cambios
git restore --staged archivo.txt
git reset HEAD archivo.txt # Equivalente clásico
Deshacer commits
# Deshacer el último commit, mantener cambios en staging
git reset --soft HEAD~1
# Deshacer el último commit, mantener cambios en working directory
git reset --mixed HEAD~1 # Es el comportamiento por defecto de git reset
# Deshacer el último commit Y borrar los cambios (DESTRUCTIVO)
git reset --hard HEAD~1
# Deshacer usando el hash de un commit específico
git reset --hard abc1234
Revertir un commit (forma segura para ramas compartidas)
A diferencia de reset, revert no borra el historial. Crea un nuevo commit que deshace los cambios:
git revert abc1234 # Revierte ese commit
git revert HEAD # Revierte el último commit
git revert HEAD~3..HEAD # Revierte un rango de commits
Recuperar commits «perdidos»
git reflog es tu red de seguridad. Guarda todos los movimientos de HEAD aunque hayas hecho reset:
git reflog
# Encuentra el hash del estado que quieres recuperar, luego:
git reset --hard abc1234
Stash: cambios temporales
Stash guarda tus cambios actuales en una pila temporal para que puedas cambiar de contexto sin hacer un commit incompleto.
git stash # Guardar cambios (rastreados)
git stash -u # Incluir archivos untracked
git stash push -m "descripción" # Guardar con nombre
git stash list # Ver todos los stashes
git stash pop # Aplicar el último y eliminarlo de la pila
git stash apply stash@{2} # Aplicar uno específico sin eliminarlo
git stash drop stash@{0} # Eliminar un stash específico
git stash clear # Eliminar todos los stashes
# Crear una rama desde un stash
git stash branch nombre-rama stash@{0}
Tags y versiones
Los tags marcan puntos específicos del historial, como versiones de releases.
# Tag ligero (solo un marcador)
git tag v1.0.0
# Tag anotado (recomendado: incluye autor, fecha y mensaje)
git tag -a v1.0.0 -m "Primera versión estable"
# Taggear un commit anterior
git tag -a v0.9.0 abc1234
git tag # Listar todos los tags
git show v1.0.0 # Ver detalles del tag
git push origin v1.0.0 # Subir un tag al remoto
git push origin --tags # Subir todos los tags
git tag -d v1.0.0 # Eliminar tag local
git push origin --delete v1.0.0 # Eliminar tag remoto
El archivo .gitignore
.gitignore le dice a Git qué archivos y carpetas debe ignorar. Se coloca en la raíz del proyecto.
# Dependencias
node_modules/
vendor/
# Archivos de entorno y secretos
.env
.env.local
*.pem
secrets.json
# Builds y compilados
dist/
build/
*.o
*.class
*.pyc
__pycache__/
# Archivos del sistema operativo
.DS_Store
Thumbs.db
desktop.ini
# IDEs y editores
.vscode/
.idea/
*.swp
*.swo
# Logs
*.log
logs/
# Ignorar todo en una carpeta excepto un archivo
carpeta/*
!carpeta/.gitkeep
Comandos útiles con gitignore:
# Ver qué archivos están siendo ignorados
git status --ignored
# Ignorar un archivo ya rastreado (primero agréguelo al .gitignore)
git rm --cached archivo.txt
# Limpiar archivos no rastreados e ignorados
git clean -fd # Elimina archivos y carpetas no rastreados
git clean -fdx # También elimina los ignorados (peligroso)
git clean -n # Simulación: muestra qué se eliminaría
Git log avanzado
# Historial gráfico y decorado
git log --oneline --graph --decorate --all
# Buscar en los mensajes de commit
git log --grep="login"
# Buscar commits que introdujeron o eliminaron una cadena de texto
git log -S "nombre-de-función"
# Ver qué cambió en cada commit
git log -p
# Estadísticas resumidas por commit
git log --stat
# Formato personalizado
git log --pretty=format:"%h - %an, %ar : %s"
# %h = hash corto | %an = autor | %ar = fecha relativa | %s = mensaje
Blame: quién cambió qué
git blame archivo.txt # Línea por línea, con autor y commit
git blame -L 10,25 archivo.txt # Solo las líneas 10 a 25
Bisect: encontrar el commit que introdujo un bug
git bisect start
git bisect bad # El estado actual tiene el bug
git bisect good v1.0.0 # Esta versión estaba bien
# Git irá a la mitad del historial; tú pruebas y marcas:
git bisect good # o
git bisect bad
# Git repite hasta encontrar el commit culpable
git bisect reset # Salir del modo bisect
Alias útiles
Los alias te ahorran tiempo al reducir comandos largos a abreviaciones:
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --global alias.unstage "restore --staged"
git config --global alias.last "log -1 HEAD"
git config --global alias.undo "reset --soft HEAD~1"
Uso:
git lg # En lugar de git log --oneline --graph --decorate --all
git undo # En lugar de git reset --soft HEAD~1
Flujos de trabajo (Workflows)
Git Flow
El más estructurado. Ideal para proyectos con releases programadas.
main ─────────────────────────────────●─────────────
↑ (release)
develop ──●──────────────────────────────●────────────
↑ ↑
feature/x └──●──●──●──┘ (merged to develop)
hotfix └──●──┘ (merged a main y develop)
main: siempre en produccióndevelop: integración continuafeature/*: nuevas funcionalidadesrelease/*: preparación de versiónhotfix/*: correcciones urgentes en producción
GitHub Flow
Más simple. Ideal para despliegue continuo.
main ──────────────────────────────●──
↑
feature/x ──●──●──●── (Pull Request) ──┘
- Crea una rama desde
main - Haz commits
- Abre un Pull Request
- Recibe revisión de código
- Merge a
main→ despliegue automático
Trunk-Based Development
Todos trabajan directamente en main con feature flags para ocultar trabajo en progreso. Ramas de vida muy corta (menos de un día).
Buenas prácticas
Mensajes de commit
Sigue el estándar de Conventional Commits:
tipo(alcance opcional): descripción corta en imperativo
Cuerpo opcional con más detalle.
Footer opcional: BREAKING CHANGE, closes #123
Tipos comunes:
| Tipo | Cuándo usarlo |
|---|---|
feat | Nueva funcionalidad |
fix | Corrección de bug |
docs | Solo documentación |
style | Formato, puntos y comas (sin cambio de lógica) |
refactor | Refactorización sin nueva funcionalidad ni fix |
test | Agregar o corregir tests |
chore | Tareas de mantenimiento, dependencias |
perf | Mejora de rendimiento |
Ejemplos:
feat(auth): agregar inicio de sesión con Google
fix(api): corregir timeout en peticiones lentas
docs: actualizar instrucciones de instalación
Commits
- Commit frecuente: un commit = un cambio lógico. No acumules días de trabajo en un solo commit.
- Commits atómicos: cada commit debe funcionar de forma independiente.
- No commitear archivos generados: builds, dependencias, archivos compilados van en
.gitignore. - Nunca commitear secretos: claves de API, contraseñas, tokens. Usa variables de entorno.
Ramas
- Nombres descriptivos en minúsculas con guiones:
feature/formulario-contacto,fix/error-login-mobile. - Ramas de vida corta: cuanto más dure una rama, más difícil será el merge.
- Actualiza tu rama regularmente con
git pullogit rebasepara evitar conflictos grandes.
Colaboración
- Siempre revisa los cambios antes de hacer push:
git diffygit log. - Usa Pull Requests / Merge Requests para revisión de código antes de mergear a ramas principales.
- Nunca hagas
git push --forceen ramas compartidas (usa--force-with-leasesi es absolutamente necesario).
Cheatsheet completo
Configuración
git config --global user.name "Nombre"
git config --global user.email "email"
git config --list
Repositorio
git init # Iniciar repo
git clone <url> # Clonar repo
Estado y diferencias
git status / git status -s
git diff / git diff --staged
git log --oneline --graph
git blame <archivo>
Staging y commits
git add . / git add -p
git commit -m "msg"
git commit --amend
git commit -am "msg"
Ramas
git branch / git branch -a
git switch -c <rama> / git checkout -b <rama>
git branch -d <rama>
git merge <rama>
git rebase <rama>
git rebase -i HEAD~N
Remotos
git remote add origin <url>
git push -u origin main
git push / git pull
git fetch origin
git push origin --delete <rama>
Deshacer
git restore <archivo> # Descartar cambios
git restore --staged <archivo> # Sacar del staging
git reset --soft HEAD~1 # Deshacer commit, mantener staging
git reset --mixed HEAD~1 # Deshacer commit, mantener working dir
git reset --hard HEAD~1 # Deshacer commit y cambios (DESTRUCTIVO)
git revert <hash> # Nuevo commit que deshace otro (seguro)
git reflog # Historial de todo movimiento de HEAD
Stash
git stash / git stash -u
git stash list
git stash pop / git stash apply stash@{N}
git stash drop / git stash clear
Tags
git tag -a v1.0.0 -m "msg"
git push origin --tags
git tag -d v1.0.0
Utilidades
git clean -fd # Eliminar archivos no rastreados
git cherry-pick <hash> # Aplicar un commit específico a la rama actual
git bisect start/good/bad/reset # Encontrar commit con bug
git shortlog -sn # Ranking de commits por autor
Documentación oficial: git-scm.com/doc — El libro «Pro Git» está disponible gratis online y es la referencia más completa que existe.