git push: cómo subir tus cambios al repositorio remoto
git push envía los commits locales de la rama actual al repositorio remoto y mueve allí el puntero de la rama. La primera vez una rama se publica con git push -u origin nombre-rama, y después basta con git push. Si en el servidor hay commits de otras personas, primero hay que traerlos con git pull, no hacer un force push.
Qué hace git push
El comando git push toma de tu rama local los commits que todavía no están en el servidor, los envía al repositorio remoto (que normalmente se llama origin) y mueve allí el puntero de la rama hasta tu último commit. Los archivos de la carpeta de trabajo y los cambios sin confirmar no se envían: solo viaja el historial, es decir, los commits.
Es importante entender que push no es una «sincronización». Funciona en un solo sentido: del repositorio local al remoto. Para recibir los cambios de otros se necesitan git fetch o git pull. Confundir estas direcciones provoca casi todos los problemas con los que los principiantes acuden a un mentor.
Otra regla de Git: por defecto, push solo se permite como «avance rápido» (fast-forward). El servidor aceptará tus commits si continúan el historial que ya tiene. Si alguien ha subido sus commits antes que tú, tu push será rechazado, y eso es una protección, no un error.
Sintaxis del comando
git push [<remote>] [<rama-local>[:<rama-remota>]]
Si ejecutas git push sin argumentos, Git toma la rama actual y la envía a la rama configurada como upstream (la rama de seguimiento). La forma explícita es útil cuando el upstream aún no está configurado o quieres subir la rama con otro nombre:
git push origin main # subir la main local a origin/main
git push origin feature/login # subir la rama feature/login
git push origin fix:hotfix-123 # subir la fix local como hotfix-123 en el servidor
git push origin HEAD # subir la rama actual con el mismo nombre
Cómo subir cambios por primera vez
El camino típico de un proyecto nuevo hasta tener el código en GitHub o GitLab es este. Primero creas un repositorio vacío en el servidor, luego lo enlazas con el local y subes la rama.
git init
git add .
git commit -m "Primer commit"
git branch -M main
git remote add origin git@github.com:user/project.git
git push -u origin main
La opción -u (forma larga --set-upstream) enlaza la rama local main con la remota origin/main. A partir de ahí, en esa rama basta con escribir git push y git pull, y git status empezará a mostrar cuántos commits vas por delante o por detrás del servidor.
Para comprobar a dónde apunta el remote, usa git remote -v. Si la dirección es incorrecta, corrígela con git remote set-url origin <nueva-url> en lugar de borrar y volver a crear el repositorio.
Cómo subir una rama nueva
Has creado una rama para una tarea, has hecho commits y escribes git push. Git responde:
fatal: The current branch feature/login has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin feature/login
No es un error, sino una pista: la rama todavía no tiene pareja en el servidor. Ejecuta el comando que te sugiere o la forma corta git push -u origin feature/login. Para que Git lo haga automáticamente con todas las ramas nuevas, activa este ajuste (disponible desde Git 2.37):
git config --global push.autoSetupRemote true
Por qué se rechaza git push: rejected, non-fast-forward
La situación más común al trabajar en equipo:
! [rejected] main -> main (fetch first)
error: failed to push some refs to 'github.com:user/project.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.
Un compañero subió sus commits antes que tú. Tu historial y el del servidor han divergido, y si Git aceptara tu push, los commits de tu compañero se perderían. La solución correcta es traer primero esos cambios e integrar los tuyos encima:
git pull --rebase # traer los commits ajenos y recolocar los tuyos encima
# si hay conflictos: corregir archivos, git add, git rebase --continue
git push
En lugar de --rebase puedes hacer un git pull normal; entonces aparecerá un merge commit. Ambas opciones son correctas; en la mayoría de los equipos se prefiere rebase para los commits locales propios, para mantener un historial lineal. Lo importante es no «resolver» el rechazo con --force.
git push --force y --force-with-lease
El envío forzado hace falta cuando has reescrito a propósito el historial de tu rama: hiciste git commit --amend, git rebase o combinaste commits antes de la revisión. Un push normal no aceptará esa rama, porque los commits antiguos del servidor ya no son ancestros de los nuevos.
git push --force-with-lease
--force-with-lease sobrescribe la rama en el servidor solo si está donde tu Git local la vio por última vez (según la referencia origin/<rama>). Si un compañero ha subido algo entretanto, el comando se negará y no borrarás su trabajo. El --force normal (-f) no hace esa comprobación y lo sobrescribe todo sin avisar.
Hay un matiz: si justo antes ejecutas git fetch, la referencia origin/<rama> se actualiza y la protección deja de funcionar, porque Git supondrá que ya «has visto» los commits ajenos. Así que no hagas fetch justo antes de un force push sin revisar qué ha llegado.
| Comando | Qué hace | Cuándo usarlo |
|---|---|---|
git push | Solo fast-forward | Siempre, por defecto |
git push --force-with-lease | Sobrescribe con comprobación | Tu propia rama tras un rebase o un amend |
git push --force | Sobrescribe sin comprobaciones | Casi nunca; jamás en ramas compartidas |
En las ramas compartidas (main, develop) no se hace push forzado: a todos los que ya descargaron el historial antiguo se les desincronizará respecto al servidor. Además, normalmente estas ramas están protegidas en la configuración del repositorio y el servidor devolverá protected branch hook declined.
Cómo subir etiquetas
Un git push normal no envía las etiquetas (tags). Hay que enviarlas explícitamente:
git tag -a v1.2.0 -m "Release 1.2.0"
git push origin v1.2.0 # una etiqueta
git push --tags # todas las etiquetas locales
git push --follow-tags # commits y las etiquetas anotadas que apuntan a ellos
--follow-tags es más cómodo que --tags: no envía etiquetas ligeras locales creadas por accidente, solo las anotadas y solo las alcanzables desde los commits que se suben.
Cómo borrar una rama en el servidor
Borrar también se hace con push:
git push origin --delete feature/login
# sintaxis antigua, hace lo mismo:
git push origin :feature/login
La rama local se mantiene; puedes borrarla con git branch -d feature/login. Y tus compañeros seguirán viendo la referencia origin/feature/login hasta que ejecuten git fetch --prune.
Opciones útiles de git push
| Opción | Para qué sirve |
|---|---|
-u, --set-upstream | Guardar la rama remota como upstream |
-n, --dry-run | Mostrar qué se enviaría sin enviar nada |
--all | Subir todas las ramas locales |
--tags / --follow-tags | Subir etiquetas |
-d, --delete | Borrar una rama o etiqueta en el servidor |
--force-with-lease | Reescritura segura del historial |
-v, --verbose | Salida detallada |
--no-verify | Saltarse el hook pre-push (úsalo con conocimiento de causa) |
Errores frecuentes con git push y cómo solucionarlos
Permission denied (publickey)
El servidor no ha aceptado tu clave SSH. Comprueba que la clave existe (ls ~/.ssh), que la parte pública está añadida a tu cuenta y que la conexión funciona: ssh -T git@github.com. Si el remote está configurado por HTTPS, Git te pedirá usuario y token, no la clave; revisa git remote -v.
Authentication failed por HTTPS
GitHub y muchos otros servicios hace tiempo que no aceptan la contraseña de la cuenta por HTTPS. Necesitas un token de acceso personal o pasarte a SSH. Para guardar el token usa un credential helper: git config --global credential.helper store (lo guarda en texto plano) o el gestor de credenciales de tu sistema operativo.
src refspec main does not match any
No tienes ninguna rama con ese nombre. Lo más habitual es que en un repositorio vacío aún no se haya hecho ningún commit o que la rama se llame master. Revisa git branch y haz un commit o renombra la rama: git branch -M main.
Everything up-to-date aunque hay cambios
Se te olvidó hacer commit. git push envía commits, no archivos. Ejecuta git status y luego git add y git commit. La otra posibilidad es que no estés en la rama que esperas ver en el servidor.
Archivo demasiado grande
Los servicios limitan el tamaño de los archivos (en GitHub, 100 MB). Si ese archivo ya está en el historial, no basta con borrarlo en un commit nuevo: hay que reescribir el historial o quitarlo de los commits que aún no se han subido (git reset --soft y volver a hacer el commit). Para archivos binarios grandes se usa Git LFS.
Flujo de trabajo con git push
git switch -c feature/x: rama para la tarea.- Commits en pasos lógicos pequeños.
git fetchygit rebase origin/main: traer la rama principal actualizada.git push -u origin feature/x: publicar la rama.- Abrir un pull request; tras la revisión, commits adicionales y un
git pushnormal. - Si has tenido que reescribir el historial:
git push --force-with-lease.
Antes de subir, conviene ver qué va a llegar exactamente al servidor: git log origin/main..HEAD --oneline muestra los commits que aún no están allí.
Qué configurar una sola vez
Unos cuantos ajustes globales te ahorran la mayoría de las sorpresas al subir cambios. push.default define qué envía git push sin argumentos. El valor por defecto en las versiones actuales es simple: solo se sube la rama actual y solo a la rama upstream del mismo nombre. Normalmente no hace falta cambiarlo, pero vale la pena comprobar que en una configuración antigua no se haya quedado matching, que sube de golpe todas las ramas con nombres coincidentes.
git config --global push.default simple
git config --global push.autoSetupRemote true
git config --global push.followTags true
git config --global pull.rebase true
push.followTags convierte --follow-tags en el comportamiento por defecto, y pull.rebase evita merge commits innecesarios cuando el push se rechaza y primero hay que traer los cambios ajenos.
Hook pre-push
El archivo .git/hooks/pre-push se ejecuta antes del envío. Si termina con un código distinto de cero, el push no se realiza. Los equipos suelen lanzar ahí los tests o el linter para que el código roto no llegue al servidor. Saltarse el hook con --no-verify solo tiene sentido cuando entiendes exactamente por qué falla.
Conclusión
git push publica tus commits en el repositorio remoto y funciona en un solo sentido. Haz la primera subida de una rama con -u; si te la rechazan, trae primero los cambios ajenos con pull, y sube el historial reescrito de tu propia rama solo con --force-with-lease. El trabajo con repositorios remotos, push, pull y claves SSH se practica en el curso de Git.
Preguntas frecuentes
¿git push envía los cambios que no están en un commit?
No. Push solo transfiere commits; los cambios de la carpeta de trabajo y del índice se quedan en local hasta que hagas commit.
¿Cómo deshacer un git push?
En tu propia rama puedes deshacer el commit en local (git reset) y subirlo con git push --force-with-lease. En una rama compartida es más seguro crear un commit inverso con git revert y hacer un push normal.
¿Se puede subir un solo commit?
Sí, indicando su hash: git push origin abc1234:main sube todo el historial hasta ese commit incluido, pero no los posteriores. No se puede subir un commit sin sus ancestros.
¿En qué se diferencia git push de git push origin main?
Sin argumentos, Git usa el upstream configurado de la rama actual; la forma explícita indica directamente el remote y la rama, y funciona aunque no haya upstream configurado.
¿Cómo hacer push a dos repositorios a la vez?
Añade un segundo remote y sube a cada uno por su nombre, o añade a origin dos URL de envío con git remote set-url --add --push origin url (ejecútalo para ambas direcciones, incluida la original; si no, el push irá solo a la segunda).
Este tema se explica a fondo y con práctica en el curso «Git desde cero hasta desarrollador seguro».
Ir al curso