El staging area de Git explicado: las cuatro zonas

Qué es el staging area de Git, por qué existe y cómo viajan tus cambios por las cuatro zonas: working directory, staging area, repo local y remoto.

El staging area de Git explicado: las cuatro zonas

La primera vez que usé Git en serio tecleé git add . porque lo había copiado de un tutorial, sin tener ni idea de qué hacía ese punto. Un rato después hice un commit y descubrí que dentro había metido un archivo con una clave de API que nunca debería haber salido de mi máquina. El staging area de Git es justo la zona que existe para que eso no pase: es el filtro donde decides qué entra en cada commit y qué se queda fuera.

Para seguir este post solo necesitas saber que Git guarda el historial de tu proyecto en commits, y haber creado alguno copiando comandos. Si vas todavía más atrás, en primeros pasos con Git tienes el punto de partida. Aquí vamos a ver por dónde viajan de verdad tus cambios, y por qué git add no es un paso opcional que te puedas saltar sin entenderlo.

¿Por dónde pasan tus cambios en Git?

Un cambio en Git viaja por cuatro zonas antes de acabar compartido con tu equipo: el directorio de trabajo, el staging area, el repositorio local y el repositorio remoto. Cada zona es un sitio distinto donde tu código puede estar, y cada comando de Git lo que hace en realidad es mover cosas de una zona a otra.

Diagrama de flujo horizontal con las cuatro zonas de Git (directorio de trabajo, staging area, repositorio local y repositorio remoto) y los comandos git add, git commit y git push que mueven los cambios entre ellas, junto con git restore --staged para deshacer el paso a staging area.
Las cuatro zonas por las que viaja un cambio en Git, y los comandos que lo mueven de una a otra.

Piénsalo como preparar un paquete para enviarlo. El directorio de trabajo es tu mesa, con todo desordenado mientras trabajas. El staging area es la caja donde vas metiendo solo lo que quieres enviar. El repositorio local es el registro de todos los paquetes que has cerrado, guardado en tu casa. Y el remoto es la oficina de correos, donde el paquete queda accesible para los demás.

Esta es la foto de las cuatro zonas y de los comandos que mueven cosas entre ellas:

ZonaQué contieneComando que mete cosasComando que las saca
Directorio de trabajoTus archivos tal y como los estás editando ahora mismo, con cambios sin guardar en el historialEditas con tu editorgit restore archivo descarta el cambio
Staging area (index)La foto de lo que entrará en el próximo commitgit add archivogit restore --staged archivo
Repositorio localEl historial de commits guardado en tu máquinagit commit -m "..."(no aplica)
Repositorio remotoEl historial compartido en GitHub, GitLab o similargit pushgit fetch trae, no saca

Vamos zona por zona, empezando por la que ya conoces sin saber su nombre.

El directorio de trabajo: donde editas

El directorio de trabajo (o working directory) es la carpeta de tu proyecto tal y como la ves en tu editor. Cuando abres un archivo, cambias una línea y guardas, ese cambio vive aquí y solo aquí. Git todavía no ha hecho nada con él.

Esto es importante: guardar un archivo en tu editor no es lo mismo que guardarlo en Git. Para tu sistema operativo el archivo ya está a salvo en el disco, pero para el historial de Git ese cambio aún no existe. Si borraras la carpeta, se perdería.

Git se da cuenta de que has tocado algo. Si escribes git status, te dirá que hay cambios “not staged”, es decir, cambios que están en el directorio de trabajo pero que todavía no has preparado. Ahí es donde entra la siguiente zona.

¿Qué es el staging area y por qué existe?

El staging area es la zona intermedia donde preparas exactamente qué cambios formarán parte de tu próximo commit. También se le llama index, y las dos palabras significan lo mismo: es el mismo sitio con dos nombres [1]. Cuando lees “index” en la documentación de Git, están hablando del staging area.

La pregunta que se hace todo el mundo al empezar es: ¿por qué hay un paso intermedio? ¿Por qué Git no guarda directamente lo que he cambiado y ya está? La respuesta es que el staging area te da control sobre qué entra en cada commit.

Imagina que en una sesión de trabajo has arreglado un bug en login.js y, de paso, has cambiado unos colores en estilos.css. Son dos cosas distintas. Si las metes en el mismo commit, dentro de tres meses, cuando busques cuándo tocaste el login, encontrarás un commit que mezcla el arreglo con cambios de estilo que no tienen nada que ver. El staging area te deja preparar solo login.js, confirmarlo con su propio mensaje, y después preparar estilos.css en otro commit aparte. Cada commit cuenta una sola historia.

Esa curación selectiva es la razón de ser del staging area. No preparas “todo lo que has tocado” a lo bruto: preparas lo que forma un cambio coherente. Cuando tecleas git add estilos.css, lo que le estás diciendo a Git es “este archivo, con su estado actual, va en el próximo commit”. El resto de tus cambios se queda esperando en el directorio de trabajo.

Aquí lo ves de un vistazo con git status. He cambiado dos archivos y he creado uno nuevo, pero solo he preparado uno:

# archivo.js: modificado y ya preparado con "git add archivo.js"
# estilos.css: modificado pero SIN preparar
# notas.txt: archivo nuevo que Git todavia no sigue
git status

La salida real de Git separa esos tres estados en tres bloques distintos (los comentarios con # los añado yo para señalar qué zona es cada bloque, no salen en la salida de Git):

Changes to be committed:          # ya esta en el staging area, entrara en el commit
	modified:   archivo.js

Changes not staged for commit:    # esta en el directorio de trabajo, fuera del commit
	modified:   estilos.css

Untracked files:                  # archivo nuevo, Git aun no lo rastrea
	notas.txt

Fíjate en el detalle: archivo.js está bajo “Changes to be committed” (preparado) y estilos.css bajo “Changes not staged for commit” (sin preparar). El mismo git status te está mostrando dos zonas a la vez. Si hicieras un commit ahora, solo entraría archivo.js. Los otros dos se quedarían fuera, esperando.

Repositorio local y remoto: dos historiales, no uno

El repositorio local es el historial de commits que vive en tu máquina, dentro de la carpeta oculta .git. Cuando haces git commit, Git coge lo que hay en el staging area y lo graba ahí como un punto permanente del historial. A partir de ese momento el cambio está guardado de verdad: puedes volver a él aunque sigas editando. Si quieres entender qué guarda por dentro cada uno de esos puntos, mira qué es exactamente un commit.

El repositorio remoto es una copia de ese historial que vive en un servidor, normalmente en GitHub o GitLab, y que tu equipo comparte. Es lo que ves cuando entras en la página web del proyecto. Un git commit no lo toca: el commit se queda en tu máquina hasta que lo envías con git push.

Esta separación confunde a mucha gente al principio, y con razón. Haces un commit, ves el mensaje de confirmación, y das por hecho que el cambio ya está “subido”. No lo está. Sigue solo en tu repositorio local. Hasta que no ejecutas git push, nadie de tu equipo puede ver ese commit. Es la diferencia entre cerrar el paquete en casa y llevarlo a la oficina de correos.

¿Cómo muevo cambios entre zonas?

Cada comando básico de Git es, en el fondo, una flecha que mueve tu código de una zona a la siguiente. Si tienes clara la zona de salida y la de destino, los comandos dejan de ser magia copiada de un tutorial.

Para preparar un cambio concreto, nombra el archivo en lugar de usar el punto:

# Mueve SOLO archivo.js del directorio de trabajo al staging area.
# No toca ningun otro cambio que tengas pendiente.
git add archivo.js

Si preparas algo por error y quieres sacarlo del staging area sin perder lo que has escrito, usa git restore --staged. Devuelve el archivo al directorio de trabajo con tus cambios intactos [2]:

# Saca archivo.js del staging area.
# Tus cambios NO se pierden: vuelven al directorio de trabajo.
git restore --staged archivo.js

Antes esto se hacía con git reset HEAD archivo.js (HEAD es tu último commit), y sigue funcionando igual; verás ese comando en tutoriales antiguos. git restore --staged es la forma moderna y más fácil de recordar, porque el nombre dice lo que hace.

Cuando el staging area tiene justo lo que quieres, lo confirmas en el repositorio local con un mensaje que explique el cambio:

# Coge todo lo que hay en el staging area y crea un commit
# en tu repositorio LOCAL. Nada se envia todavia.
git commit -m "Arregla el bug de login"

Y para que ese commit llegue al equipo, lo envías al repositorio remoto:

# Envia tus commits locales al remoto (por ejemplo, a GitHub).
# Ahora si: el resto del equipo puede verlos.
git push

Son cuatro comandos y cuatro flechas entre zonas: ese es el modelo mental completo. Lo que cambia entre proyectos son los nombres de los archivos, no el recorrido. Si quieres ver ese recorrido de principio a fin con más ejemplos, lo tienes en el flujo git add, commit y push.

Ahora pruébalo tú. En este ejercicio interactivo tienes unos cuantos cambios en el directorio de trabajo: decide cuáles preparas en el staging area y cuáles dejas fuera antes de confirmar el commit.

Cargando ejercicio...

Errores típicos con el staging area

Casi todos los tropiezos con Git al principio salen de no ver estas zonas como sitios separados. Estos son los que más me he encontrado.

Creer que git add guarda tus cambios

git add no guarda nada en el historial. Solo prepara. El único comando que crea un punto permanente es git commit. Si haces git add archivo.js, cierras el portátil y no llegas a hacer commit, no has guardado el cambio en Git: sigue en el staging area, en el aire.

git add . a ciegas

El punto en git add . prepara todo lo que has cambiado en el directorio actual y hacia abajo. Es cómodo, pero es también como me colé aquella clave de API. Si no miras qué estás preparando, acabas metiendo cosas que no tocan: un archivo de secretos, una carpeta node_modules pesada, un fichero de configuración local. La costumbre sana es teclear git status antes de cualquier git add ., y tener un .gitignore que excluya lo que nunca debe entrar. No es que git add . esté mal, es que no debe usarse sin mirar.

Pensar que git commit -a incluye tus archivos nuevos

Hay un atajo, git commit -a, que prepara y confirma en un solo paso para ahorrarte el git add. El problema es lo que cubre. git commit -a solo incluye modificaciones y borrados de archivos que Git ya rastreaba; los archivos nuevos, que Git nunca ha visto (los “untracked”), se quedan fuera [3].

# Prepara y confirma en un paso, PERO solo archivos ya rastreados.
# Un archivo nuevo (untracked) NO entra aqui: necesita "git add" antes.
git commit -a -m "Actualiza el login"

Si acabas de crear nuevo-modulo.js y confías en git commit -a para subirlo, te llevarás la sorpresa de que no está. Para archivos nuevos, git add primero, siempre.

Confundir el commit con el push

Hacer commit y creer que el cambio ya está subido es el malentendido más común, y ya lo hemos visto: el commit vive en tu repositorio local hasta que haces git push. Si tu compañero no ve tu trabajo, antes de buscar qué ha fallado conviene preguntarse si de verdad se ha hecho git push.

Practica las zonas de Git a fondo

Ver el diagrama ayuda, pero el modelo mental se te queda cuando mueves cambios tú mismo entre zonas y ves qué entra en cada commit. En el curso Git de cero a profesional practicas el staging area con ejercicios interactivos como el de arriba, paso a paso y sin instalar nada, hasta que curar un commit te salga solo.

Y si quieres que te avise cuando publique más guías sobre Git, déjame tu correo:

Un concepto nuevo cada semana

Fuentes

  1. Pro Git: What is Git? (sección “The Three States”). El nombre técnico del staging area en Git es “index”, y “staging area” vale igual como sinónimo.
  2. Documentación oficial de git restore (git-scm.com). El flag --staged restaura solo el index y deja intactos los cambios del directorio de trabajo; es equivalente a git reset HEAD.
  3. Documentación oficial de git commit (git-scm.com). Comportamiento del flag -a: solo prepara modificaciones y borrados de archivos ya rastreados, no archivos nuevos.

Preguntas Frecuentes

¿Puedo saltarme el staging area?

En parte sí, con git commit -a, que prepara y confirma en un solo paso. El matiz importante es que solo funciona con archivos que Git ya rastreaba: modificaciones y borrados. Los archivos nuevos siguen necesitando un git add explícito. Y aunque el atajo es cómodo, te quita el control de decidir archivo por archivo qué entra en el commit, que es justo para lo que existe el staging area.

¿El staging area es lo mismo que el index?

Sí, son dos nombres para exactamente la misma zona: “staging area” es el nombre descriptivo e “index” es el término técnico que verás en la documentación de Git.

¿Qué diferencia hay entre git add y git commit?

git add mueve tus cambios del directorio de trabajo al staging area: los prepara, pero no los guarda en el historial. git commit coge lo que hay en el staging area y crea un punto permanente en tu repositorio local. Uno prepara, el otro guarda. Necesitas los dos para que un cambio quede registrado en Git.

¿Cómo saco un archivo del staging area sin perder los cambios?

Con git restore --staged:

# Saca archivo.js del staging area sin tocar tus cambios,
# que vuelven al directorio de trabajo intactos.
git restore --staged archivo.js

El equivalente clásico, que verás en tutoriales antiguos, es git reset HEAD archivo.js, y hace lo mismo.