Las órdenes de Git que de verdad se usan

Git tiene fama de difícil, y en parte la tiene merecida: su vocabulario es raro y sus mensajes de error no siempre ayudan. Pero el trabajo diario cabe en unas quince órdenes, y casi toda la confusión desaparece en cuanto entiendes que un cambio puede estar en cuatro sitios distintos. Esta guía va por ahí, y todo lo que aparece se ejecutó de verdad con Git 2.47 antes de publicarlo.

1. Las cuatro zonas

Esta es la idea que hay que entender antes que ninguna orden. Un archivo tuyo puede estar en cuatro estados a la vez, y casi todas las preguntas de principiante («¿por qué no se ha subido?», «¿dónde está mi cambio?») se contestan sabiendo en cuál de los cuatro está.

Las cuatro zonas de Git y las órdenes que mueven los cambios entre ellasUn archivo pasa por cuatro sitios, y cada orden lo mueve de uno al siguienteDirectoriode trabajotus archivos,como los editasÁrea depreparaciónlo que entraráen el commitRepositoriolocalla historia,en .gitRemotooriginGitHub, GitLab,un servidorgit addgit commitgit pushgit restoregit resetgit pullgit status dice en cuál de los tres primeros está cada cambio; git diff enseña qué cambióEl cuarto solo se toca a propósito, con push, fetch o pull

Lo que cuesta al principio es la segunda caja, el área de preparación, que en inglés verás como staging area o index. Parece un paso de más: ¿por qué no se guarda directamente lo que hay en disco? Porque permite elegir. Si has tocado seis archivos pero solo tres pertenecen al mismo arreglo, preparas esos tres y haces un commit limpio, en vez de un revoltijo.

2. Empezar un repositorio

Antes de nada, decir quién eres

Git firma cada commit con un nombre y un correo. Si no los configuras, la primera vez que intentes guardar algo se quejará:

git config --global user.name "Ana"
git config --global user.email "ana@ejemplo.com"
git config --global init.defaultBranch main

El --global lo deja puesto para todos tus repositorios. La tercera línea evita el aviso de que la rama por defecto se llamaba master y ahora se recomienda main.

git init — empezar de cero

mkdir tienda && cd tienda
git init
salidaInitialized empty Git repository in /home/ana/tienda/.git/

Eso crea una carpeta oculta .git con toda la historia. Si la borras, pierdes el repositorio pero no tus archivos; si borras todo menos .git, puedes recuperar los archivos. Ahí está todo.

git clone — traerse uno que ya existe

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

Descarga la historia completa, crea la carpeta, deja los archivos listos y además configura el remoto origin apuntando a donde lo trajiste. Es init más remote add más pull, en un paso.

3. El ciclo de todos los días

Son cuatro órdenes, y se repiten en bucle: mirar, preparar, guardar, comprobar.

git status — la orden que más se teclea

Recién creado el repositorio, con un README.md sin guardar:

git status
salidaOn branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	README.md

nothing added to commit but untracked files present (use "git add" to track)

Git es muy hablador y eso ayuda: casi siempre te dice entre paréntesis qué orden usar a continuación. Cuando ya te sabes el camino, git status --short da lo mismo en dos letras por archivo:

git add productos.csv
git status --short
salidaA  productos.csv
?? ventas.log
Marca Qué significa
?? Git no sabe nada de este archivo. Nunca se ha añadido
A  Nuevo y ya preparado para el próximo commit
M  Modificado y preparado. La M va en la primera columna
 M Modificado pero sin preparar. La M va en la segunda
MM Preparaste un cambio y luego seguiste editando
D  Borrado
UU Conflicto sin resolver

La clave de esas dos columnas: la primera es el área de preparación y la segunda es el disco. Por eso MM no es un error, es un archivo que preparaste y después volviste a tocar.

git add y git commit

git add README.md
git commit -m "Primer commit: README"
salida[main (root-commit) 5c9a6b2] Primer commit: README
 1 file changed, 3 insertions(+)
 create mode 100644 README.md

Ese 5c9a6b2 es el identificador del commit, los primeros caracteres de un código largo. Sirve para referirse a él en cualquier otra orden.

Forma Qué prepara o guarda
git add archivo Ese archivo
git add . Todo lo que hay de aquí hacia abajo, nuevos incluidos
git add -p Te pregunta trozo a trozo. Útil para partir un cambio grande
git commit -m "…" Guarda lo preparado con ese mensaje
git commit -am "…" Prepara y guarda de golpe, pero solo archivos ya conocidos
El -a no incluye archivos nuevos. git commit -am recoge las modificaciones de lo que Git ya sigue, pero ignora lo que aparece como ??. Es la causa habitual de «hice commit y el archivo no está». Si hay archivos nuevos, git add primero.

git diff — qué ha cambiado exactamente

Tras subir un precio y añadir una línea:

git diff
salidadiff --git a/productos.csv b/productos.csv
index 18005be..a0b9baf 100644
--- a/productos.csv
+++ b/productos.csv
@@ -1,3 +1,4 @@
 nombre;precio
-camiseta;19.90
+camiseta;21.90
 gorra;12.50
+bufanda;9.00

Las líneas con - son las que había y las de + las que hay ahora; modificar una línea aparece como quitar una y poner otra. Y aquí está la trampa que confunde a todo el mundo:

git add productos.csv
git diff
salida(sin salida)

git diff a secas compara el disco con el área de preparación. En cuanto haces add, los dos coinciden y no hay nada que enseñar. Para ver lo que sí vas a guardar hace falta la otra forma:

git diff --staged
Orden Compara
git diff Disco contra área de preparación: lo que aún no has preparado
git diff --staged Área de preparación contra el último commit: lo que vas a guardar
git diff HEAD Disco contra el último commit: todo lo que ha cambiado
git diff rama1 rama2 Dos ramas entre sí

4. Qué no guardar

Un archivo .gitignore en la raíz dice qué no debe seguir Git. Una línea por patrón:

*.log
node_modules/
__pycache__/
.env
build/
*.sqlite3

Cuenta como un archivo más del proyecto, así que se añade y se guarda en un commit como cualquier otro: lo que tú ignoras lo ignora también quien clone el repositorio.

Lo que de verdad importa que esté ahí: los secretos. Una clave de API o un .env con contraseñas que entra en un commit no se arregla borrándolo en el commit siguiente, porque sigue en la historia y cualquiera que clone el repositorio puede recuperarlo. Si pasa, da por comprometida esa credencial y cámbiala; limpiar la historia es un trabajo aparte y mucho más incómodo.
Si el archivo ya estaba siendo seguido, el .gitignore llega tarde. Solo afecta a lo que Git todavía no conoce. Para que deje de seguirlo sin borrarlo del disco: git rm --cached archivo, y después un commit.

5. Deshacer: la parte difícil

Aquí es donde Git se gana su fama, porque hay cinco órdenes distintas y la que necesitas depende de en qué zona está lo que quieres deshacer. Vamos por casos.

Descartar un cambio del disco

Has tocado un archivo, no te gusta y quieres volver a como estaba:

git status --short
git restore productos.csv
git status --short
salida M productos.csv
(limpio)
Esto no se puede deshacer. git restore sobre un archivo sin preparar tira el trabajo sin pasar por ninguna parte: no hay commit que lo guarde ni papelera de donde sacarlo. Es la única orden de esta guía que destruye algo que Git nunca llegó a ver.

Sacar algo del área de preparación

Hiciste git add de algo que no querías incluir. El cambio no se pierde, solo retrocede una zona:

git restore --staged borrador.txt
git status --short
salida?? borrador.txt

Corregir el último commit

El mensaje tenía una errata, o se te olvidó incluir un archivo. --amend reemplaza el último commit en vez de añadir otro:

git commit --amend -m "Sube el precio de la camiseta y anade .gitignore"
git log --oneline
salida9af611a Sube el precio de la camiseta y anade .gitignore
e4d77a7 Anade el catalogo de productos
5c9a6b2 Primer commit: README

Fíjate en que siguen siendo tres commits, no cuatro: el anterior ha desaparecido y en su lugar hay otro, con otro identificador. Eso último importa y lo retomamos en el aviso del final de esta sección.

Deshacer commits: las tres caras de reset

La misma orden hace tres cosas distintas según la opción, y la diferencia está exactamente en hasta qué zona retrocede. Partiendo de dos commits:

git log --oneline
salidaf60a94d Commit B
6cfc382 Commit A
git reset --soft HEAD~1
git log --oneline
git status --short
salida6cfc382 Commit A
A  b.txt

El commit ha desaparecido, pero su contenido sigue preparado, listo para volver a guardarlo mejor. Si añadimos un paso más:

git reset
git status --short
salida?? b.txt

Ahora ya no está preparado, pero el archivo sigue en el disco. Y la tercera:

git reset --hard HEAD~1
git log --oneline
ls
salidaHEAD is now at 6cfc382 Commit A
6cfc382 Commit A
a.txt

El archivo b.txt ya no está. --hard arrasa las tres zonas de golpe.

Orden Quita el commit Vacía la preparación Borra del disco
git reset --soft sí no no
git reset (mixed) sí sí no
git reset --hard sí sí sí

git revert — deshacer sin reescribir

Las anteriores borran historia. revert hace lo contrario: deja el commit donde está y añade otro encima que lo anula.

git revert --no-edit HEAD
git log --oneline
salida[main 7e315fc] Revert "Sube el precio de la camiseta y anade .gitignore"
 2 files changed, 1 insertion(+), 3 deletions(-)

7e315fc Revert "Sube el precio de la camiseta y anade .gitignore"
9af611a Sube el precio de la camiseta y anade .gitignore
e4d77a7 Anade el catalogo de productos
5c9a6b2 Primer commit: README

Parece más aparatoso, porque la historia se alarga en vez de acortarse, y es justo eso lo que lo hace seguro.

git stash — aparcar lo que tienes a medias

Estás con algo sin terminar y te piden mirar otra cosa. stash guarda tu trabajo en un cajón aparte y te deja el repositorio limpio:

git stash
git status --short
salidaSaved working directory and index state WIP on main: 564c449 Reapply "Sube el precio…"
(limpio)
git stash list
git stash pop
salidastash@{0}: WIP on main: 564c449 Reapply "Sube el precio…"

Changes not staged for commit:
	modified:   productos.csv

Dropped refs/stash@{0} (d2f6ca9e7777f12c0047f6175845437ee61991fd)

pop lo devuelve y vacía el cajón; git stash apply lo devuelve pero lo conserva guardado.

La regla que evita el 90 % de los disgustos. reset y --amend reescriben la historia: cambian o eliminan commits que ya existían. Si esos commits todavía no han salido de tu máquina, perfecto. Si ya los has subido con push y alguien más los tiene, reescribirlos obliga a un push --force que romperá el repositorio de tus compañeros. Para deshacer algo ya compartido, revert.
Lo que quieres deshacer La orden
Un cambio en el disco, sin preparar git restore archivo
Un git add que no querías git restore --staged archivo
El mensaje del último commit git commit --amend
El último commit, para rehacerlo mejor git reset --soft HEAD~1
Todo lo local, volver al último commit git reset --hard HEAD
Un commit que ya está compartido git revert <commit>
Nada; solo aparcarlo un rato git stash

6. Ramas

Una rama es una línea de trabajo paralela. Te separas de main, haces lo tuyo sin molestar a nadie, y cuando funciona lo devuelves.

Cómo se separa una rama de main y cómo vuelve con un mergeUna rama es una línea de trabajo que se separa y vuelveABDMC1C2maindescuentosgit switch -c descuentosgit merge descuentosM es el commit de fusión: tiene dos padres, uno de cada ramaSi main no se movió mientras tanto, Git no crea M: adelanta la rama y lo llama fast-forward
git switch -c descuentos
salidaSwitched to a new branch 'descuentos'

El -c es de crear. Sin él, git switch descuentos se cambia a una rama que ya existe. Para ver cuáles hay, con un asterisco en la actual:

git branch
salida* descuentos
  main

Terminado el trabajo, se vuelve a main y se fusiona:

git switch main
git merge descuentos
salidaSwitched to branch 'main'
Updating 564c449..2e3967a
Fast-forward
 productos.csv | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Ese fast-forward significa que main no se había movido mientras trabajabas, así que Git no ha tenido que inventar nada: simplemente ha adelantado la etiqueta. Cuando las dos ramas han avanzado, crea un commit de fusión con dos padres, como la M del esquema.

Orden Qué hace
git switch rama Cambia a una rama existente
git switch -c rama La crea y se cambia a ella
git switch - Vuelve a la rama anterior
git branch Lista las ramas locales
git branch -d rama Borra una rama ya fusionada
git merge rama Trae esa rama a la actual
Si has aprendido git checkout, no estaba mal. checkout hacía de todo: cambiar de rama, restaurar archivos y moverse a un commit concreto, y por eso era confuso. Desde la versión 2.23 ese trabajo está repartido en git switch para las ramas y git restore para los archivos. checkout sigue funcionando, pero las dos nuevas son más claras.

7. Conflictos

Un conflicto no es un error ni algo que hayas hecho mal: es Git diciendo que dos ramas tocaron las mismas líneas y que la decisión es tuya.

git merge rebajas
salidaAuto-merging ficha.txt
CONFLICT (content): Merge conflict in ficha.txt
Automatic merge failed; fix conflicts and then commit the result.

Abres el archivo y te encuentras esto dentro:

ficha.txt<<<<<<< HEAD
precio: 24.90
=======
precio: 14.90
>>>>>>> rebajas
stock: 40
Las marcas que Git deja en un archivo con conflicto y qué significa cada unaEsto es lo que Git escribe dentro del archivo cuando no sabe decidir<<<<<<< HEADprecio: 24.90=======precio: 14.90>>>>>>> rebajasempieza lo tuyo, lo que ya había en la rama actualtu versiónla frontera entre las dosla versión que llegay aquí acaba, con el nombre de la otra ramaSe arregla editando el archivo a mano: dejas lo que quieras y borras las tres líneas de marcasDespués git add archivo y git commit cierran la fusión. git merge –abort la cancela entera

Observa que stock: 40 está fuera de las marcas: Git solo pide ayuda en las líneas que no sabe resolver, el resto lo fusiona solo. Tú editas, dejas el contenido que quieras —puede ser una de las dos versiones, o una tercera cosa—, borras las tres líneas de marcas y cierras:

git add ficha.txt
git commit -m "Fusiona rebajas: precio intermedio"
git log --oneline --graph
salida*   f7f6816 Fusiona rebajas: precio intermedio
|\
| * 5834f54 Rebaja el precio
* | 258088c Sube el precio por temporada
|/
* ec9b9a7 Ficha inicial

Ahí se ven las dos ramas separándose y volviendo a juntarse. Y si en mitad del lío prefieres no seguir, git merge --abort deja todo exactamente como estaba antes de empezar.

8. Trabajar con un remoto

Hasta aquí todo ha pasado en tu máquina. Un remoto es una copia del repositorio en otro sitio, que por convención se llama origin.

git remote add origin https://github.com/usuario/tienda.git
git remote -v
salidaorigin	https://github.com/usuario/tienda.git (fetch)
origin	https://github.com/usuario/tienda.git (push)

El primer envío lleva un -u que emparenta tu rama local con la del remoto. Solo hace falta la primera vez:

git push -u origin main
salida * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

A partir de ahí basta con git push, y además git status empieza a decirte cómo vas respecto al remoto:

git fetch origin
git status -sb
salidaFrom /home/ana/servidor
   2e3967a..b8c0202  main       -> origin/main
## main...origin/main [behind 1]

Ese behind 1 dice que hay un commit en el remoto que tú no tienes. Y aquí está la diferencia que más se pregunta:

Orden Qué hace
git fetch Descarga lo nuevo pero no toca tus archivos. Puedes mirarlo antes
git pull fetch y además lo fusiona con tu rama, en un paso
git push Sube tus commits al remoto

Con fetch hecho, se puede ver exactamente qué va a entrar antes de aceptarlo:

git log --oneline HEAD..origin/main
salidab8c0202 Anade mochila
git pull
salidaUpdating 2e3967a..b8c0202
Fast-forward
 productos.csv | 1 +
 1 file changed, 1 insertion(+)
Si push es rechazado con un mensaje sobre non-fast-forward, no es que hayas roto nada: alguien subió algo mientras tú trabajabas. Se arregla con git pull y volviendo a empujar. Lo que no hay que hacer es responder con --force, que borraría el trabajo de la otra persona.

9. Mirar la historia

git log a secas saca un párrafo por commit y llena la pantalla. La forma que se usa de verdad es esta, y merece la pena aprendérsela:

git log --oneline --graph --decorate -4
salida* 2e3967a (HEAD -> main, descuentos) Anade columna de descuento
* 564c449 Reapply "Sube el precio de la camiseta y anade .gitignore"
* 7e315fc Revert "Sube el precio de la camiseta y anade .gitignore"
* 9af611a Sube el precio de la camiseta y anade .gitignore

El --decorate es lo que añade entre paréntesis dónde apuntan las etiquetas: ahí se ve que HEAD, main y descuentos están en el mismo commit.

Dos formas más que resuelven preguntas concretas. La historia de un solo archivo:

git log --oneline -- productos.csv

Y quién escribió cada línea, con el commit y la fecha al lado:

git blame productos.csv
salida2e3967a3 (Ana 2026-10-05 19:00:12 +0000 1) nombre;precio;descuento
2e3967a3 (Ana 2026-10-05 19:00:12 +0000 2) camiseta;21.90;10
2e3967a3 (Ana 2026-10-05 19:00:12 +0000 3) gorra;12.50;0
2e3967a3 (Ana 2026-10-05 19:00:12 +0000 4) bufanda;9.00;25

Etiquetas

Una etiqueta marca un punto de la historia con un nombre, normalmente una versión publicada:

git tag -a v1.0 -m "Primera version publicada"
git tag
salidav1.0

Las etiquetas no se suben con un push normal; hay que pedirlo: git push origin v1.0, o git push --tags para todas.

10. Configuración que merece la pena

Tres ajustes que ahorran tiempo desde el primer día:

git config --global pull.rebase false
git config --global core.editor "nano"
git config --global alias.lg "log --oneline --graph --decorate -15"

El primero fija qué hace pull cuando hay que mezclar, y quita un aviso que Git repite si no lo has decidido. El segundo evita que se abra vim cuando Git te pide un mensaje, que es el momento en que mucha gente se queda atrapada sin saber salir. El tercero crea un atajo: a partir de ahí, git lg enseña el gráfico de la historia.

Si te pasa: para salir de vim se escribe :wq y Intro para guardar y salir, o :q! para salir sin guardar.

Para ver todo lo que tienes configurado y de qué archivo sale cada cosa: git config --list --show-origin.

11. La chuleta

Quiero… Orden
Saber cómo está todo git status --short
Ver qué he cambiado git diff
Ver qué voy a guardar git diff --staged
Guardar lo preparado git commit -m "…"
Corregir el último commit git commit --amend
Descartar un cambio del disco git restore archivo
Quitar un add git restore --staged archivo
Deshacer el último commit, conservando el trabajo git reset --soft HEAD~1
Deshacer un commit ya compartido git revert <commit>
Aparcar lo que tengo a medias git stash y luego git stash pop
Crear una rama y cambiarme git switch -c rama
Volver a la rama anterior git switch -
Traer una rama a la actual git merge rama
Cancelar una fusión con conflictos git merge --abort
Ver qué hay de nuevo sin aplicarlo git fetch y git log HEAD..origin/main
Traer y mezclar git pull
Subir git push
Ver la historia de un vistazo git log --oneline --graph --decorate
Saber quién escribió una línea git blame archivo

Todas las órdenes y todas las salidas de esta página se ejecutaron con Git 2.47.3 sobre Debian 13 en un contenedor limpio antes de publicarla, con un usuario normal; están copiadas de esa ejecución, no redactadas. Los conflictos y los errores son reales, provocados a propósito. Los identificadores de commit que aparecen son los de esa sesión y serán distintos en tu máquina. El logotipo de la portada es de Jason Long, bajo licencia CC BY 3.0. Si esto te sirve, en la misma sección están los comandos de Linux y la guía de Docker.