Fundamentos de Git
El modelo mental correcto (tres áreas, commits como instantáneas, ramas como punteros) hace que todo lo demás tenga sentido.
Al terminar vas a poder
- Configurar Git correctamente en una máquina nueva.
- Explicar las tres áreas: directorio de trabajo, staging y repositorio.
- Hacer commits atómicos, revisar el historial y escribir un
.gitignore.
Qué es Git
Un sistema de control de versiones distribuido creado por Linus Torvalds en 2005. Cada clon tiene el historial completo: podés trabajar, hacer commits y ver el historial sin conexión. GitLab, GitHub o un servidor propio son solo copias remotas acordadas como punto de encuentro.
El modelo mental
- Directorio de trabajo: los archivos como los ves en el editor.
- Staging (índice): la "bandeja" donde preparás exactamente lo que irá en el próximo commit.
- Repositorio: la base de datos de commits en
.git/.
Un commit es una instantánea completa del proyecto (no una diferencia), identificada por un hash SHA, con autor, fecha, mensaje y un puntero a su commit padre. Una rama es solo un puntero móvil a un commit. HEAD indica en qué rama (o commit) estás parado.
Configuración inicial
git config --global user.name "Juan Pérez"
git config --global user.email "juan@ejemplo.com.py"
git config --global init.defaultBranch main
git config --global core.editor "code --wait" # o nano, vim
git config --global pull.rebase true # historial lineal al hacer pull
git config --global fetch.prune true # limpia ramas remotas borradas
git config --global core.autocrlf input # Linux/macOS; en Windows: true
git config --global alias.lg "log --oneline --graph --decorate --all"
git config --list --show-origin # ver de dónde sale cada valor
Si usás un correo para el trabajo y otro personal, configurá el correo por repositorio (git config user.email … sin --global) o usá includeIf en ~/.gitconfig para aplicar una configuración según la carpeta:
[includeIf "gitdir:~/trabajo/"]
path = ~/.gitconfig-trabajoFlujo básico
mkdir turnero && cd turnero
git init # crea .git/ con la rama main
echo "# Turnero Clínico" > README.md
git status # README.md: sin seguimiento (untracked)
git add README.md # al staging
git commit -m "docs: agrega README inicial"
git log --oneline
# Ciclo diario
git status
git diff # cambios NO preparados
git diff --staged # cambios preparados para el commit
git add -p # preparar por fragmentos (muy recomendable)
git commit # abre el editor para un mensaje completo
Commits atómicos y buenos mensajes
Un commit = un cambio lógico. Si el mensaje necesita "y", probablemente son dos commits. git add -p permite separar en commits distintos cambios hechos en el mismo archivo.
feat(reservas): valida que no se superpongan turnos del mismo profesional
Antes se podía reservar dos turnos a la misma hora si las solicitudes
llegaban casi simultáneamente. Se agrega una restricción de exclusión en
PostgreSQL (tstzrange) y se devuelve 409 Conflict desde la API.
Closes #27
Reglas: asunto de ≤ 72 caracteres en modo imperativo ("agrega", no "agregué"), línea en blanco, cuerpo que explica por qué (el cómo está en el diff). En el módulo 19 vemos el estándar Conventional Commits.
Ver el historial
git log --oneline --graph --all # árbol de todas las ramas
git log -p archivo.java # historial con cambios de un archivo
git log --author="Ana" --since="2 weeks ago"
git log -S "calcularRecargo" # commits que agregaron o quitaron ese texto
git show a1b2c3d # detalle de un commit
git blame -L 40,60 src/Reserva.java # quién cambió cada línea y cuándo
.gitignore
# Dependencias y builds
node_modules/
target/
build/
dist/
__pycache__/
*.class
# Entorno y secretos: NUNCA al repositorio
.env
.env.*
!.env.example
*.pem
*.key
# IDE y sistema
.idea/
.vscode/
*.iml
.DS_Store
Thumbs.db
# Logs
*.log
logs/
Las URLs, contraseñas y tokens van en variables de entorno y un .env ignorado; al repositorio solo sube .env.example con los nombres de las variables y valores ficticios. Si un secreto llegó a un commit, rotarlo (cambiarlo) es obligatorio: borrarlo en un commit nuevo no lo saca del historial.
Si agregaste algo al .gitignore que ya estaba versionado, hay que dejar de seguirlo: git rm --cached archivo. Plantillas listas: github/gitignore.
- Configurá Git con todas las opciones de arriba y verificá con
git config --list --show-origin. - Creá el repositorio
turnerocon un README, un.gitignorey un.env.exampleque tengaDATABASE_URLySMS_API_URL. - Modificá dos partes distintas de un mismo archivo y hacé dos commits separados usando
git add -p. - Usá
git log -Spara encontrar el commit donde apareció una función.
Autoevaluación
1. ¿Qué comando pasa cambios del directorio de trabajo al staging?
2. ¿Qué muestra 'git diff --staged'?
3. Una rama en Git es…
4. Subiste una contraseña en un commit y luego la borraste en otro. ¿Qué tenés que hacer?
5. Un archivo ya versionado sigue apareciendo aunque lo agregaste al .gitignore. Solución: