Introducción
Cada operación de Git mueve datos entre tres áreas: el árbol de trabajo (tus archivos), el index (borrador del próximo commit) y el repositorio (historial commiteado bajo .git). Nombrar lo que se mueve a dónde es el modelo mental más útil.
Las áreas
- Árbol de trabajo: el directorio en el que editas.
- Index:
.git/index, el tree staged. - Repositorio: objetos en
.git/objectsmás refs en.git/refs.
Comandos por dirección
# árbol de trabajo -> index
git add file
git rm file
git mv old new
# index -> repositorio
git commit
git write-tree # plumbing
# repositorio -> index
git reset <commit>
git read-tree <tree>
# repositorio -> árbol de trabajo (y normalmente index)
git checkout <commit> -- file
git restore --source <commit> file
git switch <branch>
Los cuatro diffs
Puedes comparar cualesquiera dos áreas:
git diff # árbol de trabajo vs index
git diff --staged # index vs HEAD
git diff HEAD # árbol de trabajo vs HEAD
git diff main feature # repositorio vs repositorio
Status decodificado
git status -s
# XY filename
# X = estado del index, Y = estado del árbol de trabajo
# M modified, A added, D deleted, R renamed, ?? untracked
Por ejemplo MM significa modificado tanto en el index como en el árbol de trabajo (stageaste un cambio y luego volviste a editar).
Reset, restore, checkout
Cada uno afecta áreas diferentes:
git reset --soft: solo repositorio (mover ref).git reset(mixed): repositorio + index.git reset --hard: repositorio + index + árbol de trabajo.git restore --staged: index desde HEAD.git restore: árbol de trabajo desde el index.git restore --source=<commit>: árbol de trabajo (y opcionalmente index) desde un commit específico.
Un ejercicio
echo a > f.txt
git add f.txt
git commit -m "v1"
echo b >> f.txt
git add f.txt
echo c >> f.txt
git status
git diff
git diff --staged
git diff HEAD
Lee cada diff; entender por qué difieren cementa el modelo.
Plumbing para cada área
Conocer el plumbing para cada área desmitifica los comandos de nivel superior:
- Árbol de trabajo: operaciones ordinarias del sistema de archivos.
- Index:
git update-index,git ls-files,git read-tree,git write-tree. - Base de datos de objetos:
git hash-object,git cat-file,git mktree,git commit-tree. - Refs:
git update-ref,git symbolic-ref,git for-each-ref.
git ls-files --stage # index
git ls-tree HEAD # repo
ls -R # árbol de trabajo
Errores comunes
Intentar memorizar comandos en lugar de áreas; una vez que sabes qué área es la fuente y cuál el destino, el comando correcto es obvio. Confundir git restore file con git checkout file; son equivalentes para ese caso, pero los muchos otros modos de checkout confunden a usuarios nuevos. Usar git reset --hard para "limpiar" sin darte cuenta de que destruye el árbol de trabajo. Y finalmente, esperar que git commit incluya ediciones no staged; no lo hace (a menos que pases -a para archivos rastreados solamente).