viernes, 18 de junio de 2010

Deshacer el push en git

Actualizacion: Quick fix

Alguien pusheo commits que no debia, o por alguna razon se pretende "deshacer" commits que ya se enviaron al servidor central.

Quick fix

Buscar el commit a donde se pretende volver: (usar git log o git reflog, etc...), y despues hay que ejecutar estos commandos (donde a_donde_volver se reemplaza por el commit):


git reset a_donde_volver
git checkout HEAD .
git push --force


Y a trabajar

NOTA: usar --force solo para casos especificos como este, ya que directamente sobreescribe cambios en la rama remota (que es lo que se pretende hacer en este caso)

Narrado (for dummys)

Todo lo que voy a explicar es asumiendo que se esta trabajando en la rama master (que es la default en git), si no estas trabajando en la rama master, el comando "git branch" muestra la rama de trabajo en la que estas trabajando

Antes, que nada, se puede hacer un tag del master actual:

git tag ultimo_master master


Posteriormente, hay que encontrar el commit al cual se quiere volver, se pueden revisar los logs (el nombre de la rama es opcional, si no se indica usa la rama de trabajo actual):

git log [master]


Supongamos que el commit al que se quiere volver es 0123456789abcd..., puede ser util taguearlo para referenciaro facilmente mas adelante (aunque se puede hacer todo referenciando al commit, directamente)


git tag a_donde_volver 0123456789abcd...


Posteriormente, se hace un reset a para que la rama master local referencie a ese commit, y despues un checkout para cambiar los archivos y que coincidan


git reset a_donde_volver
git checkout HEAD .


Despues, hay que sobreescribir la referencia master remota con la actual, pero hay que usar --force para que git no verifique si se trata de un fast-forward (porque sino rechaza la operacion), recordar usar --force solamente en casos especificos como este.


git push --force


Y despues se puede seguir trabajando normalmente

Bonus track

Puede ser util crear un branch en el servidor a partir del master original antes de que se revierta (para poder analizarlo entre todos, etc...), para hacer esto:


git push origin ultimo_master:refs/heads/old_master


Y en este post explico como usar los branches:

http://nilclass.blogspot.com/2009/08/branches-remotos-en-git.html

2 comentarios:

gacpro dijo...

Excelente post, claro y conciso. Me ahorró mucho tiempo con un problema que tenía con un push indeseado.
Gracias!!!
Keep it up! ;)

Anónimo dijo...

Muchas gracias!! me ahorraste horas de problemas!!