Curso
Probablemente hayas experimentado esto como programador: Acabas de darte cuenta de que tu código tenía un problema en tu última confirmación. Para deshacer este error, ejecuta algunos comandos y reescribe tu historial local. Cuando ejecutas git push --force para limpiarlo todo, tus compañeros de equipo te notifican que faltan algunas confirmaciones o que tu canalización tiene compilaciones rotas.
En este artículo, te explicaré qué hace realmente git push --force, cuándo utilizarlo y cómo evitar errores. Si estás empezando con Git, te recomiendo que realices nuestro curso Introducción a Git ( ) para aprender sobre el control de versiones. Además, la hoja de referencia rápida de Git, que se puede descargar, me parece muy útil porque incluye todos los términos y comandos más comunes de Git.
Cuándo podrías pensar que necesitas git push --force
Supongamos que estás limpiando tu historial de confirmaciones local antes de enviar tu trabajo. Para ordenar tu historial de confirmaciones antes de fusionar, ejecuta git rebase -i main. Todo parece perfecto a nivel local, así que intentas actualizar tu rama remota concon un simple git push. Pero en lugar del mensaje de éxito habitual, Git muestra un error.
Puedes encontrarte con otra situación en la que accidentalmente confirmes datos confidenciales , tal como una clave API o una contraseña, y los envíes al servidor remoto. Después de reescribir el historial localmente para eliminar la confirmación problemática, descubres que un push normal no actualiza el repositorio remoto y los datos confidenciales permanecen. En su lugar, aparece un mensaje de error.
! [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
hint: its remote counterpart. Integrate the remote changes (e.g.,
hint: 'git pull ...') before pushing again.
Este error de «no avance rápido» es la red de seguridad de Git, que te advierte de que algo en tu historial no coincide con lo que hay en el servidor. En este punto, es tentador ejecutar git push --force para omitir este error.
Eso puede funcionar bien si eres el único que trabaja en la rama. Sin embargo, los proyectos compartidos pueden crear fácilmente confusión o borrar el trabajo de otra persona.
¿Qué hace realmente git push --force?
Por lo general, Git solo te permite enviar tus cambios si tu rama local contiene todo lo que ya está en el remoto, incluidas tus nuevas confirmaciones. Sin embargo, a veces es posible reescribir el historial de confirmaciones mediante git rebase, squashing o removing datos confidenciales. Al hacerlo, tu rama local será diferente de la rama remota. A continuación, cuando intentas enviar una nueva confirmación, Git muestra el error, que protege la rama remota de la pérdida de trabajo.
Al utilizar « git push --force », se le indica a Git que omita la comprobación de seguridad y sobrescriba la rama remota con el contenido de la rama local.
Así es como se ve:
git push --force origin main
Esto actualizará la rama principal del control remoto para que coincida con tu rama principal local y eliminará cualquier confirmación que no esté en tu rama local.
Ahora, imagina tu rama Git como un capítulo de un libro compartido que tu equipo está escribiendo juntos. Un empuje estándar es como añadir nuevos párrafos al final del capítulo. Sin embargo, una sustitución completa ( git push --force ) es más potente y elimina el capítulo actual y lo sustituye por completo con tu versión.
El riesgo de utilizar git push --force es que los colaboradores pueden perder su trabajo si basan sus cambios en las confirmaciones que acabas de borrar. En la siguiente sección, veremos las precauciones que debes tomar al trabajar con el comando --force.
Por qué esto puede arruinarlo todo para tu equipo
Si fuerzas los cambios en una rama compartida como main o develop, es probable que ocurra lo siguiente:
- Las sucursales locales de otros usuarios se desincronizan: Si tus compañeros de equipo han extraído los compromisos antiguos que ahora has borrado del remoto, sus historiales locales ya no coincidirán con el servidor. Sus ramas harán referencia a confirmaciones que han «desaparecido», lo que creará confusión y
- Al extraer, se producen fusiones confusas o errores: Cuando alguien intentagit pull después de que hayas forzado el envío, Git no sabrá cómo conciliar el historial reescrito con su secuencia local de confirmaciones . Esto suele dar lugar a confirmaciones de fusión extrañas, errores crípticos o situaciones en las que se pide a los compañeros de equipo que intervengan manualmente con git fetch, git reset o incluso que vuelvan a clonar la rama.
- Los procesos de CI/CD pueden fallar: Los pipelines suelen depender de hash de confirmación coherentes y de un historial lineal. Un force push puede provocar que fallen las pruebas, se vuelva a implementar código incorrecto o se produzca un bloqueo al reconstruir en commits obsoletos.
Echa un vistazo a nuestro curso CI/CD para machine learning para comprender cómo crear flujos de trabajo de CI/CD. También te recomiendo que realices nuestro curso Introducción al control de versiones de datos con DVC para aprender la diferencia entre el control de versiones de datos y el control de versiones de código.
Permíteme ilustrarlo con un ejemplo: Estás en la rama « feature » con un compañero de equipo « ». Limpia el historial local de y, a continuación, ejecuta git push --force. Minutos más tarde, tu compañero de equipo envía sus cambios. Ves errores en Git. Cuando tiran, obtienen conflictos de fusión y un historial de confirmaciones desordenado. Mientras tanto, tu canalización de CI falla debido a la falta de confirmaciones. Ahora, tu compañero de equipo pierde tiempo desenredando la rama y la implementación se retrasa.
Un solo empujón lo activa todo.
La opción más segura: git push --force-with-lease
Para evitar este tipo de problemas, te recomiendo utilizar git push --force-with-lease. Este comando añade una comprobación de seguridad al enviar a una rama remota para evitar confirmaciones inesperadas.
git push --force-with-lease origin main
Piensa en « --force-with-lease » como «preguntar si la costa está despejada antes de saltar». Antes de hacer nada, se asegura de que nadie más haya cambiado la rama. Si todo está tal y como lo viste la última vez, tu historial se ha actualizado. Pero si hay nuevos cambios que no conocías, Git te detiene y te pide que revises la situación primero. Por lo tanto, este comando siempre protegerá a los colaboradores de sobrescrituras involuntarias.
Cómo recuperarse de un mal Force Push
Si pierdes algunas confirmaciones, no te preocupes, porque aún puedes recuperarlas. Git siempre guarda un registro de los cambios realizados en la confirmación actual, incluidas las reescrituras, y lo almacena en el reflog.
A continuación te explicamos cómo puedes recuperar las confirmaciones perdidas:
Paso 1: Usa git reflog para encontrar confirmaciones perdidas
Ejecuta git reflog para ver el historial de tu rama.
git reflog
Puedes ver tus confirmaciones de la siguiente manera:
abc1234 HEAD@{1}: push: force push
def5678 HEAD@{2}: commit: add new feature
Paso 2: Restaurar la confirmación perdida
Cuando hayas identificado el hash de la confirmación que deseas recuperar, utiliza el siguiente comando para acceder a la rama específica.
git checkout def5678
Paso 3: Crear una nueva rama
Para recuperar los archivos de forma segura, crea una nueva rama git.
git checkout -b recovery-branch
Paso 4: Restaurar la rama remota
Ahora envía las confirmaciones recuperadas a la rama:
git push origin recovery-branch
Ten en cuenta que los datos de reflog solo existen en máquinas locales. Por lo tanto, no podrás recuperar las confirmaciones perdidas si ninguno de tus compañeros de equipo las ha almacenado en el entorno local.
Te recomiendo que realices nuestro curso Git intermedio para aprender más sobre la colaboración y el trabajo con ramas en Git.
Prácticas recomendadas para utilizar git push --force de forma segura
Para reducir la posibilidad de romper cosas, aquí tienes algunos buenos hábitos que puedes seguir:
-
Prefiere --force-with-lease en lugar de --force: Este método es una opción más segura que comprueba si la rama remota no ha cambiado desde la última vez que la recuperaste. Te ayudaré a proteger a tus compañeros de equipo de sobrescrituras accidentales.
-
Evita forzar el envío a ramas compartidas: Nunca realices un envío forzado a ramas compartidas como
main,master,developorelease. Solo fuerza la publicación en las ramas de características en las que eres el único colaborador para evitar interrupciones. -
Notifica a tu equipo antes de realizar una publicación forzada: Si debes realizar un envío forzado a una rama compartida, avisa a tu equipo. Esto les permitirá guardar su trabajo y evitar pérdidas.
-
Utiliza ramas protegidas: También puedes habilitar la protección para tus ramas cuando utilices plataformas como GitHub, GitLab y Bitbucket. Esto restringe las ediciones directas y evita que se realicen envíos forzados accidentales a ramas importantes.
Si deseas obtener más información sobre cómo gestionar repositorios privados, consultanuestro curso Introducción a los conceptos de GitHubpara comprender cómo revisar solicitudes de extracción cuando colaboras en GitHub.
Conclusión
git push --force ofrece un método útil para reescribir el historial de tu repositorio, tanto si deseas limpiar las confirmaciones como eliminar datos confidenciales. Ten siempre cuidado al utilizar este comando para evitar interrumpir el flujo de trabajo de tu equipo.
Siempre que sea posible, utiliza --force-with-lease en su lugar. Te ofrece más control sin poner en riesgo el trabajo de otras personas. Con un poco de cuidado y comunicación, puedes mantener limpio tu historial de Git sin causar problemas a tu equipo.
Te recomiendo que eches un vistazo a nuestros programas de habilidades Fundamentos de Git y Fundamentos de GitHub para convertirte en un experto en todo lo relacionado con Git.
Aprende hoy los fundamentos de Git
Preguntas frecuentes
¿Cuáles son los riesgos de utilizar git push --force?
Puede sobrescribir confirmaciones en la rama remota, lo que provocaría que tus compañeros de equipo perdieran trabajo o se encontraran con conflictos de fusión confusos.
¿Cómo puedo usar git push --force-with-lease de forma segura?
Utiliza git push --force-with-lease en lugar de --force para asegurarte de que la rama remota no ha cambiado desde la última vez que la recuperaste y evitar sobrescrituras accidentales.
¿En qué situaciones es necesario utilizar git push --force?
git push --force puede ser necesario cuando has rebasado confirmaciones locales, eliminado datos confidenciales del historial o limpiado el historial de confirmaciones antes de fusionar una rama de características.
¿Cómo puedo deshacer un git push --force que me arrepiento?
Para deshacer un git push --force, ejecuta git reflog para encontrar la commit anterior, luego restárala marcando esa commit y forzando el envío de la rama corregida.
¿Cuáles son las mejores prácticas para evitar errores con git push --force?
Utiliza --force-with-lease, evita enviar cambios de forma forzada a ramas compartidas, comunícate con tu equipo y protege las ramas importantes en tu plataforma de alojamiento Git.
