9/6/2025 • DevOps • 11 min de lectura

Git I: fundamentos y flujo diario para trabajar con criterio

Primera parte de una guía profesional de Git: modelo mental, configuración, repositorios, staging area, commits, remotos y flujo diario.

#git#version-control#devops#workflow

Git no es una carpeta con historial ni una forma elegante de subir código a GitHub. Git es un sistema distribuido de control de versiones: guarda la evolución de un proyecto, permite trabajar en paralelo, comparar estados, recuperar cambios y colaborar sin depender de una única copia central.

Esta primera parte está pensada para alguien que empieza desde cero, pero no quiere quedarse en lo superficial. El objetivo no es memorizar comandos: es entender qué está pasando cuando los ejecutas.

Al terminar deberías poder crear un repositorio, hacer commits limpios, revisar tus cambios, subirlos a un remoto y leer el historial con suficiente criterio para no trabajar a ciegas.

Qué problema resuelve Git

Sin Git, un proyecto suele acabar así:

app-final.zip
app-final-bueno.zip
app-final-bueno-ahora-si.zip
app-produccion.zip
app-produccion-copy.zip

Eso no escala. No sabes qué cambió, quién lo cambió, por qué lo cambió ni cómo volver a un estado anterior.

Git resuelve tres problemas:

Git no evita que cometas errores. Lo que hace es darte herramientas para detectarlos, entenderlos y corregirlos.

Git no es GitHub

Esta distinción importa:

Puedes usar Git sin GitHub:

git init
git add .
git commit -m "initial commit"

Y puedes tener un repositorio Git alojado en muchas plataformas. Git es el motor; GitHub es una de las plataformas.

Conceptos básicos de Git

Git tiene varias zonas. Si entiendes estas zonas, casi todos los comandos dejan de parecer mágicos.

working tree  ->  staging area  ->  repository local  ->  remote
  editas          preparas          confirmas             compartes

Working tree

Es tu directorio de trabajo: los archivos reales que editas con tu editor.

Cuando modificas src/app.js, ese cambio vive primero en el working tree.

Staging area

También se llama index. Es una zona intermedia donde eliges exactamente qué cambios entrarán en el próximo commit.

Esto es una de las mejores ideas de Git: no estás obligado a commitear todo lo que has tocado.

Puedes tocar tres archivos y preparar solo uno:

git add src/app.js

O preparar solo partes de un archivo:

git add -p

Repository local

Es la base de datos Git que vive en .git/. Ahí se guardan commits, ramas, tags, referencias y objetos.

Cuando haces commit, el cambio pasa del staging area al repositorio local.

git commit -m "fix: valida email antes de guardar usuario"

Remote

Es una copia del repositorio en otra ubicación: GitHub, GitLab, Bitbucket, un servidor interno o incluso otro directorio.

El remoto habitual se llama origin, pero no hay nada especial en ese nombre. Es una convención.

git remote -v

Commit

Un commit es un snapshot del proyecto en un momento concreto. Tiene:

Ver el último commit:

git show HEAD

HEAD apunta a dónde estás ahora.

Normalmente apunta a la rama actual:

HEAD -> main -> último commit

Cuando cambias de rama, HEAD cambia. Cuando haces un commit, la rama avanza y HEAD sigue apuntando a esa rama.

Branch

Una rama es un puntero móvil a un commit.

No pienses en una rama como una copia completa del proyecto. Piensa en ella como una etiqueta que se mueve cuando haces commits.

git branch

Historial

El historial no es una lista plana de archivos. Es un grafo de commits.

Verlo de forma compacta:

git log --oneline --graph --decorate --all

Este comando debería estar entre los primeros que aprendes, porque te enseña la forma real del repositorio.

Configuración inicial profesional

Configura tu identidad:

git config --global user.name "Tu Nombre"
git config --global user.email "tu.email@example.com"

Define main como rama inicial:

git config --global init.defaultBranch main

Configura tu editor:

git config --global core.editor "code --wait"

Ver configuración:

git config --list

Ver de dónde sale cada valor:

git config --list --show-origin

Git tiene configuración por niveles:

La configuración local gana a la global. Esto es útil si en un repositorio de trabajo necesitas un email corporativo y en tus proyectos personales otro.

git config user.email "tu.email@empresa.com"

SSH vs HTTPS

Para trabajar con remotos, normalmente usarás SSH o HTTPS.

URL HTTPS:

https://github.com/usuario/proyecto.git

URL SSH:

git@github.com:usuario/proyecto.git

En equipos profesionales, SSH suele ser más cómodo:

Generar una clave SSH:

ssh-keygen -t ed25519 -C "tu.email@example.com"

Probar conexión con GitHub:

ssh -T git@github.com

Si trabajas con varias cuentas, define hosts separados en ~/.ssh/config.

Host github-personal
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_personal

Host github-work
  HostName github.com
  User git
  IdentityFile ~/.ssh/id_ed25519_work

Entonces el remoto puede ser:

git remote add origin git@github-work:empresa/proyecto.git

Crear un repositorio desde cero

Crea el proyecto:

mkdir tienda-api
cd tienda-api
git init -b main

Comprueba estado:

git status

Crea un README:

printf "# Tienda API\n" > README.md

Crea .gitignore:

cat > .gitignore <<'EOF'
node_modules/
.env
.DS_Store
dist/
coverage/
*.log
EOF

Prepara los archivos:

git add README.md .gitignore

Revisa qué vas a commitear:

git diff --staged

Crea el primer commit:

git commit -m "chore: inicializa repositorio"

Conectar con un remoto

Crea un repositorio vacío en GitHub, GitLab o Bitbucket. Después:

git remote add origin git@github.com:usuario/tienda-api.git

Verifica:

git remote -v

Sube main y guarda la relación con el remoto:

git push -u origin main

La opción -u configura el upstream de la rama. A partir de ese momento, en esa rama puedes usar:

git push
git pull

sin repetir origin main.

El flujo diario

El flujo básico de trabajo es:

git status
git diff
git add
git diff --staged
git commit
git push

No lo acortes demasiado al principio. La parte importante no es escribir menos comandos, sino revisar mejor.

git status

Tu primer reflejo debería ser:

git status

Te dice:

git diff

Ver cambios no preparados:

git diff

Ver cambios preparados:

git diff --staged

Revisar el diff antes de commitear evita errores tontos: logs de debug, archivos equivocados, secretos, cambios de formato innecesarios.

git add

Preparar archivo:

git add src/users.js

Preparar todo:

git add .

Preparar partes:

git add -p

git add -p es una frontera importante entre uso básico y uso profesional. Te permite separar cambios mezclados en commits coherentes.

git commit

Commit con mensaje corto:

git commit -m "fix: evita crear usuarios sin email"

Commit abriendo editor:

git commit

Usa el editor cuando el cambio necesita contexto.

Formato recomendable:

tipo: resumen breve en imperativo

Contexto opcional.
Explica por qué existe el cambio, no solo qué archivos tocaste.

Ejemplo:

fix: valida email antes de crear usuario

La API aceptaba usuarios sin email cuando la petición venía desde el panel
interno. Eso rompía el flujo de recuperación de contraseña.

git push

Sube commits locales al remoto:

git push

Si la rama no tiene upstream:

git push -u origin feature/validacion-email

git pull

Trae cambios remotos e intégralos:

git pull

Más adelante conviene entender que pull equivale a:

git fetch
git merge

o, según configuración:

git fetch
git rebase

En esta primera parte basta con saber que pull sincroniza tu rama local con su upstream remoto.

Staging area

Supón que has tocado src/users.js para dos cosas distintas:

Si haces:

git add src/users.js
git commit -m "fix: valida email de usuario"

el commit incluirá también el renombrado. Eso ensucia el historial.

Mejor:

git add -p src/users.js

Git te mostrará bloques de cambios y podrás decidir:

y = stage this hunk
n = do not stage this hunk
s = split hunk
e = edit hunk manually
q = quit

Después:

git diff --staged
git commit -m "fix: valida email de usuario"

Luego preparas el refactor:

git add -p src/users.js
git commit -m "refactor: renombra helper de usuarios"

Ese es el tipo de cuidado que hace que un PR sea revisable.

Commits de calidad

Un commit profesional cumple cuatro condiciones:

Mal:

git commit -m "cosas"

Mejor:

git commit -m "fix: corrige validación de email en alta de usuarios"

Tipos habituales:

feat: nueva funcionalidad
fix: corrección de bug
docs: documentación
test: tests
refactor: cambio interno sin alterar comportamiento
chore: mantenimiento
ci: pipeline
build: build o dependencias
perf: rendimiento

Antes de commitear:

git status
git diff --staged

Preguntas útiles:

Modificar el último commit

Si olvidaste añadir un archivo:

git add archivo-olvidado.js
git commit --amend

Cambiar solo el mensaje:

git commit --amend -m "fix: valida email antes de crear usuario"

Regla importante: --amend reescribe el commit. Úsalo sin problema antes de hacer push. Si el commit ya está compartido, coordina antes.

Leer el historial

Ver historial:

git log

Versión compacta:

git log --oneline

Grafo útil:

git log --oneline --graph --decorate --all

Ver un commit:

git show <hash>

Ver cambios entre dos commits:

git diff <hash-a> <hash-b>

Ver quién tocó cada línea:

git blame src/users.js

git blame no es para culpar personas. Es para encontrar contexto: cuándo se introdujo una línea, en qué commit, con qué mensaje y quizá en qué PR.

Buscar cuándo cambió algo

Buscar commits por mensaje:

git log --grep="email"

Buscar commits que tocaron un archivo:

git log -- src/users.js

Buscar commits que introdujeron o eliminaron una cadena:

git log -S "validateEmail"

Esto es muy útil cuando investigas regresiones.

Escenario completo

Flujo real para una corrección pequeña:

git status
git pull

# editar código

git status
git diff
git add -p
git diff --staged
git commit -m "fix: valida email antes de crear usuario"
git push

No parece espectacular, pero es sólido. Un buen flujo diario se basa en pasos aburridos y repetibles.

Errores comunes al empezar

Hacer commit sin revisar

Solución:

git diff --staged

Commits enormes

Si un commit toca 40 archivos sin una razón clara, será difícil de revisar y revertir.

Solución:

git add -p

Mezclar cambios no relacionados

Ejemplo malo:

fix login, refactor users, update dependencies and format project

Haz commits separados.

Subir .env

Solución:

printf ".env\n" >> .gitignore

Si ya lo subiste, no basta con borrarlo en un commit posterior. El secreto sigue en el historial. En ese caso hay que rotar la credencial y limpiar historial con cuidado.

Checklist antes de commitear

Glosario base

Working tree: archivos reales que estás editando.

Staging area: zona donde preparas el próximo commit.

Repository local: base de datos Git dentro de .git/.

Commit: snapshot versionado del proyecto.

HEAD: referencia a la posición actual.

Branch: puntero móvil a un commit.

Remote: repositorio externo conectado al local.

Origin: nombre convencional del remoto principal.

Upstream: rama remota asociada a una rama local.

Diff: diferencia entre dos estados.

Hash: identificador de un objeto Git, normalmente un commit.