Tutorial Avanzado de Git
Git Avanzado 🧙♂️
De duglasm.com
Rebase interactivo · Reflog · Bisect · Worktrees · Hooks · Filter-repo
Agenda
- 🌳 Modelo interno: objects & refs
- 🎛️ Rebase interactivo quirúrgico
- ⏮️ Reflog: la máquina del tiempo
- 🍒 Cherry-pick con conflictos
- 🐞 Bisect automatizado
- 🌿 Worktrees paralelos
- 🪝 Hooks locales y de servidor
- 🧹 Reescribir historia con filter-repo
- 🚀 Tips de productividad
::right::
💡 Regla de oro
Nunca reescribas historia que ya fue pusheada a una rama compartida.
Salvo que sepas exactamente lo que estás haciendo — y avises al equipo.
1. Modelo interno de Git
Git es una base de datos de contenido direccionable. Todo es un objeto SHA-1.
# Ver el tipo de un objeto
git cat-file -t HEAD # → commit
# Ver el contenido crudo
git cat-file -p HEAD # → tree, parent, author, message
# Explorar el tree del commit actual
git ls-tree -r HEAD # → blobs (archivos) con sus hashes
# Ver dónde apunta una ref
cat .git/refs/heads/main # → SHA del último commit
Los cuatro objetos: blob (contenido) · tree (directorio) · commit (snapshot + metadata) · tag (ref anotada).
2. Rebase interactivo quirúrgico
Reordenar, aplastar, dividir y editar commits antes de mergear.
git rebase -i HEAD~5pick a1b2c3d feat: agregar endpoint /users
squash e4f5g6h fix: typo en endpoint
reword h7i8j9k feat: paginación # cambiar solo el mensaje
edit k0l1m2n feat: filtros # detenerse para modificar
drop p3q4r5s wip: debug prints # descartar completamente
fixup t6u7v8w fix: lint # como squash pero descarta mensaje
Dividir un commit (durante un edit):
git reset HEAD^ # deshacer el commit, mantener cambios
git add -p # stagear por hunks
git commit -m "parte 1"
git commit -am "parte 2"
git rebase --continue
3. Reflog: la máquina del tiempo
Git registra cada movimiento de HEAD localmente por 90 días. Nada se pierde.
git reflog # historial completo de HEAD
# Recuperar una rama borrada
git reflog | grep "checkout: moving from feature/x"
git branch feature/x-rescatado HEAD@{15}
# Deshacer un rebase catastrófico
git reflog # buscar el estado previo
git reset --hard HEAD@{7}
# Reflog de una rama específica
git reflog show feature/pagos🚨 Ojo: reflog es local. No sirve para recuperar cosas en el remoto.
✅ Antes de operaciones peligrosas: git tag backup-$(date +%s)
4. Cherry-pick con conflictos
Traer commits específicos desde otra rama sin mergear todo.
git cherry-pick abc1234 # un commit
git cherry-pick abc1234^..def5678 # un rango (inclusive)
# Con estrategia de merge y mantener autoría
git cherry-pick -x --strategy=recursive -X theirs abc1234
# Si hay conflicto
git cherry-pick --continue # después de resolver
git cherry-pick --abort # cancelar todo
Flag -x: agrega (cherry picked from commit ...) al mensaje. Oro puro para auditoría en hotfixes que van a main y release/*.
# Cherry-pick sin commitear (para revisar antes)
git cherry-pick -n abc1234
git diff --cached
5. Bisect: cazar bugs con búsqueda binaria
Encontrar el commit que rompió algo en log2(n) pasos.
git bisect start
git bisect bad # HEAD está roto
git bisect good v1.4.0 # esta versión andaba
# Git checkoutea el commit del medio → probás → marcás
git bisect good # o `git bisect bad`
# ... repetir hasta que Git identifica el culpable
git bisect reset # volver al estado inicial
Automatizado con un script que retorna 0 (good) o 1 (bad):
git bisect start HEAD v1.4.0
git bisect run npm test -- --grep "checkout flow"Git corre el comando en cada bisección y te deja parado en el commit exacto. Es magia.
6. Worktrees: múltiples ramas simultáneas
Trabajar en varias branches en paralelo sin stash ni cambio de contexto.
# Crear un worktree nuevo apuntando a otra rama
git worktree add ../proyecto-hotfix hotfix/prod-caido
# Crear worktree con rama nueva
git worktree add -b feature/nuevo ../proyecto-feature main
# Listar todos
git worktree list
# Limpiar cuando terminaste
git worktree remove ../proyecto-hotfix🎯 Caso de uso real: estás mid-feature, salta un hotfix crítico. En vez de stashear y cambiar de branch, creás un worktree en ../hotfix, resolvés ahí, y volvés al tuyo sin tocar nada. Cada worktree tiene su propio node_modules, cache, etc.
7. Hooks: automatizar todo
Scripts que Git ejecuta en momentos clave del ciclo de vida.
.git/hooks/
├── pre-commit # antes de crear el commit
├── commit-msg # validar mensaje (conventional commits)
├── pre-push # antes de pushear
└── post-merge # después de un pull# .git/hooks/pre-commit — bloquear commits con TODO/FIXME
#!/usr/bin/env bash
if git diff --cached | grep -E "^\+.*\b(TODO|FIXME|console\.log)\b"; then
echo "❌ Encontré TODO/FIXME/console.log en el staging"
echo " Usá 'git commit --no-verify' si es intencional"
exit 1
fi
Compartir hooks con el equipo: husky, lefthook, o core.hooksPath:
git config core.hooksPath .githooks # commiteás la carpeta al repo
8. Reescribir historia con git filter-repo
filter-branch está deprecado. La herramienta moderna es git-filter-repo.
# Borrar un archivo con secretos de TODA la historia
git filter-repo --path .env --invert-paths
# Reemplazar un email en todos los commits
git filter-repo --email-callback '
return email.replace(b"viejo@empresa.com", b"nuevo@empresa.com")'
# Extraer un subdirectorio como repo independiente
git filter-repo --subdirectory-filter packages/ui
# Cambiar mensajes de commit masivamente
git filter-repo --message-callback '
return message.replace(b"WIP:", b"chore:")'⚠️ Después de reescribir historia compartida: todos deben re-clonar. Coordiná con el equipo.
9. Tips de productividad
# Aliases que cambian la vida
git config --global alias.lg \
"log --graph --oneline --all --decorate"
git config --global alias.undo "reset HEAD~1 --mixed"
git config --global alias.amend "commit --amend --no-edit"
git config --global alias.wip "!git add -A && git commit -m 'wip'"
# Autocorrección
git config --global help.autocorrect 20
# Rebase por default en pull
git config --global pull.rebase true
# Recordar resolución de conflictos
git config --global rerere.enabled true::right::
Flags que valen oro:
git log -S "texto"→ pickaxe: commits que agregaron/quitaron ese stringgit log -L :funcion:archivo.py→ historia de una funcióngit blame -w -C -C→ ignorar whitespace y detectar copy-pastegit switch -c→ alternativa moderna acheckout -bgit restore --staged→ unstage sinresetgit maintenance start→ GC automático en background
DUGLAS MORENO
Comentarios (0)
Sé el primero en comentar.