Git reset –hard y un repository remoto

Tenía un repository que tenía algunas malas asignaciones (D, E y F para este ejemplo).

ABCDEF maestro y origen / maestro

He modificado el repository local específicamente con un git reset --hard . Tomé una twig antes del reinicio así que ahora tengo un repository que se ve así:

 ABC master \ DEF old_master ABCDEF origin/master 

Ahora necesitaba algunas partes de esos commits malos así que elegí los bits que necesitaba e hice algunos commits nuevos, así que ahora tengo lo siguiente a nivel local:

 ABCGH master \ DEF old_master 

Ahora quiero impulsar este estado de cosas al repository remoto. Sin embargo, cuando trato de hacer un git push Git educadamente me quita la cabeza:

 $ 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 hago para que el repository remoto tome el estado actual del repository local?

Si forzar un empuje no ayuda (" git push --force origin " o " git push --force origin master " debería ser suficiente), podría significar que el server remoto rechaza los impulsos de avance rápido ya sea a través de la recepción. La variable de configuration denyNonFastForwards (consulte la página de configuration de git config para get una descripción), o mediante el enlace de actualización / pre-recepción.

Con Git más antiguo puedes evitar esa restricción eliminando " git push origin :master " (ver el ':' antes del nombre de la twig) y luego recreando la twig dada de " git push origin master ".

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

 ABCDEF - [(DEF) ^ - 1] maestro

 Origen / maestro ABCDEF

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

 [email protected]$ git config receive.denyNonFastforwards false 

Luego regrese a su repository local, intente de nuevo hacer su compromiso con --force :

 [email protected]$ git push origin +master:master --force 

Y finalmente revertir la configuration del server en el estado protegido original:

 [email protected]$ git config receive.denyNonFastforwards true 

En lugar de arreglar su twig "principal", es más fácil cambiarla por su "maestro deseado" al renombrar las twigs. Ver http://sofes.miximages.com/a/2862606/2321594 . De esta forma, ni siquiera dejarías ningún rastro de múltiples loggings revertidos.

Todo el negocio de restablecimiento de git me complicó mucho.

Así que hice algo en la línea para get mi carpeta src en el estado que tuve hace unos commits

 # reset the local state git reset <somecommit> --hard # copy the relevant part eg src (exclude is only needed if you specify .) tar cvfz /tmp/current.tgz --exclude .git src # get the current state of git git pull # remove what you don't like anymore rm -rf src # restre from the tar file tar xvfz /tmp/current.tgz # commit everything back to git git commit -a # now you can properly push git push 

De esta manera, el estado de las cosas en el src se mantiene en un file tar y git se ve obligado a aceptar este estado sin demasiado toquetear, básicamente, el directory src se reemplaza por el estado que tenía hace varios commits.