Git reset: duro y push al repositorio remoto

Resuelto robertpostill asked hace 15 años • 5 respuestas

Tenía un repositorio que tenía algunas confirmaciones incorrectas (D, E y F para este ejemplo).

Maestro ABCDEF y origen/maestro

Modifiqué el repositorio local específicamente con un archivo git reset --hard. Tomé una rama antes del reinicio, así que ahora tengo un repositorio que se ve así:

A-B-C master  
     \ D-E-F old_master

A-B-C-D-E-F origin/master

Ahora necesitaba algunas partes de esas confirmaciones incorrectas, así que seleccioné las partes que necesitaba e hice algunas confirmaciones nuevas, así que ahora tengo lo siguiente localmente:

A-B-C-G-H master
     \ D-E-F old_master

Ahora quiero llevar esta situación al repositorio remoto. Sin embargo, cuando intento hacer un git pushGit cortésmente me desestima:

$ git push origin +master:master --force  
Total 0 (delta 0), reused 0 (delta 0)  
error: denying non-fast forward refs/heads/master (you should pull first)  
To [email protected]:myrepo.git  
! [remote rejected] master -> master (non-fast forward)  
error: failed to push some refs to '[email protected]:myrepo.git'  

¿Cómo consigo que el repositorio remoto tome el estado actual del repositorio local?

robertpostill avatar Sep 04 '09 15:09 robertpostill
Aceptado

Si forzar un envío no ayuda ( git push --force origino git push --force origin masterdebería ser suficiente), podría significar que el servidor remoto está rechazando envíos que no sean de avance rápido, a través de cualquiera de receive.denyNonFastForwardslas variables de configuración (consulte la página de manual de git config para obtener una descripción) o mediante una actualización/pre- recibir gancho.

Con Git anterior, puede solucionar esa restricción eliminando git push origin :master(tenga en cuenta el :nombre de la rama anterior) y luego volviendo a crear git push origin masterla rama determinada.

Si no puede cambiar esto, entonces la única solución sería, en lugar de reescribir el historial, crear una confirmación que revierta los cambios en DEF :

A-B-C-D-E-F-[(D-E-F)^-1]   master

A-B-C-D-E-F                origin/master
Jakub Narębski avatar Sep 04 '2009 08:09 Jakub Narębski

Para los usuarios de GitHub, esto funcionó para mí:

  1. En cualquier regla de protección de rama donde desee realizar el cambio, asegúrese de que Permitir empujes forzados esté habilitado
  2. git reset --hard <full_hash_of_commit_to_reset_to>
  3. git push --force

Esto "corregirá" el historial de la rama en su máquina local y el servidor GitHub, pero cualquiera que haya sincronizado esta rama con el servidor desde la confirmación incorrecta tendrá el historial en su máquina local. Si tienen permiso para enviar directamente a la rama, estas confirmaciones se mostrarán de nuevo cuando se sincronicen.

Todo lo que todos los demás deben hacer es el git resetcomando de arriba para "corregir" la rama en su máquina local. Por supuesto, tendrían que tener cuidado con cualquier compromiso local realizado en esta rama después del hash objetivo. Elija/haga una copia de seguridad y vuelva a aplicarlos según sea necesario, pero si se encuentra en una rama protegida, es probable que la cantidad de personas que pueden comprometerse directamente con ella sea limitada.

Jason Faulkner avatar May 06 '2020 23:05 Jason Faulkner

Para complementar la respuesta de Jakub, si tiene acceso al servidor git remoto en ssh, puede ir al directorio remoto de git y configurar:

user@remote$ git config receive.denyNonFastforwards false

Luego regrese a su repositorio local, intente nuevamente realizar su confirmación con --force:

user@local$ git push origin +master:master --force

Y finalmente revierta la configuración del servidor en el estado protegido original:

user@remote$ git config receive.denyNonFastforwards true
Jealie avatar Sep 19 '2013 17:09 Jealie