Introducción
git push sube commits a un remoto y actualiza las refs de ese remoto. A diferencia de fetch, modifica el estado en el servidor, así que existen mecanismos de seguridad para prevenir sobrescribir el trabajo de otras personas.
La secuencia
- Resolver la URL del remoto y el refspec destino.
- Abrir una conexión.
- Negociar capacidades.
- El servidor anuncia los valores actuales de las refs.
- El cliente verifica cada push: ¿es un fast-forward de la ref del servidor?
- El cliente empaqueta los objetos faltantes y los sube.
- El servidor ejecuta el hook
pre-receive. - Por cada ref, el servidor ejecuta el hook
updatey atómicamente actualiza la ref. - El servidor ejecuta el hook
post-receive. - El servidor reporta éxito o rechazo al cliente.
Comandos
git push # branch actual a upstream
git push origin main # explícito
git push -u origin feature/login # establecer upstream
git push origin --delete feature/login # eliminar branch remoto
git push origin v1.0.0 # push de un tag
git push --follow-tags
git push --force-with-lease
Cumplimiento de fast-forward
Por defecto, un push se rechaza si no haría fast-forward de la ref remota. Esto protege contra sobrescribir accidentalmente trabajo que otros han pusheado:
! [rejected] main -> main (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind ...
Resuelve haciendo fetch e integrando, luego haciendo push de nuevo.
Force pushing
git push --force # peligroso: ignora estado del remoto
git push --force-with-lease # más seguro: rechaza si el remoto se movió
git push --force-with-lease=feature/login:abc1234
--force-with-lease requiere que la ref remota aún sea igual a lo que tu ref de seguimiento dice. Siempre prefiérelo.
Pushes atómicos
git push --atomic origin branchA branchB
Con --atomic, o todas las actualizaciones tienen éxito o ninguna; útil cuando las refs deben moverse juntas.
Políticas de push
git config --global push.default simple # branch actual a su upstream
git config --global push.default current # branch actual a remoto del mismo nombre
git config --global push.default upstream # actual al nombre de su upstream
git config --global push.autoSetupRemote true # 2.37+: -u automático para nuevos branches
Hooks del lado del servidor
Las plataformas de hosting ejecutan hooks pre-receive y update para hacer cumplir políticas (commits firmados, nombres de branch, CI verde obligatorio). Cuando un push es rechazado, el mensaje del servidor nombra la ref o commit ofensor. Lee el mensaje antes de reintentar.
Errores comunes
Hacer force-push a un branch compartido como main y reescribir los commits de otras personas. Coordina, o usa --force-with-lease solo en branches privados. Pushear tags individualmente y olvidar pushear los commits, dejando tags colgantes en el servidor. Usa --follow-tags. Pushear al remoto incorrecto porque tienes varios configurados; git push -v muestra exactamente a dónde va. Finalmente, esperar que git push --delete elimine archivos; elimina refs. Para eliminar archivos, commitea una eliminación y pushea ese commit.