TL;DR

Si estás seguro que querés sobreescribir la historia en la rama develop con un git push -f en un proyecto alojado en Bitbucket asegurate de sacar esta rama de:

  1. Settings
  2. Branch management
  3. Prevent history re-writes (rebase) on these branches

De otro modo vas a recibir el siguiente mensaje:

$ git push -f
Total 0 (delta 0), reused 0 (delta 0)
remote: permission denied to force push branch develop
To https://xxxxxx@bitbucket.org/yyyyyy/zzzzzz.git
 ! [remote rejected] develop -> develop (pre-receive hook declined)
error: failed to push some refs to 'https://xxxxxx@bitbucket.org/yyyyyy/zzzzzz.git'

Importante: Sobreescribir la historia no es recomendado. Asegurate que nadie esté trabajando en esa rama mientras vos cometés este acto criminal perverso.

Importante 2: Luego de sobreescribir la historia, volvé a incluir la rama en las opciones de Bitbucket para prevenir que algún otro criminal intente sobreescribir la historia.

La historia completa que a nadie le importa

El otro día quería hacer revert de un merge que ya estaba pusheado en origin en el branch develop. El merge que había hecho no resultó como yo esperaba: resolví muy mal los conflictos. En un ataque de demencia, hice lo siguiente:

  1. Descarte todo archivo no conflictuado.
  2. Resolví el único archivo en conflicto.
  3. Commiteé.
  4. Luego volví a mergear esperando que el proceso modifique los archivos que descarté inicialmente.
  5. WTF!!!

1er. intento: deshacer el merge

Lógicamente, pensé que con deshacer el merge era suficiente. Para ello seguí el querido tutorial Undoing Merges. Pero claro, no era eso lo yo necesitaba. Yo quería mergear los archivos que descarté. ¿Por qué? Porque luego de deshacer el merge correctamente e intentar volver a mergear el branch a develop, Git inteligentemente intuía que debía descartar los archivos porque yo los descarté en el merge inicial. Hacer revert del revert del merge sólo me daría el archivo en conflicto. Desastre absoluto.

Nota mental. Git is never wrong.

Git is never wrong

2do. intento: push force

Resignado, debía hacer algo totalmente en contra de cualquier recomendación: hacer un revert al commit previo al merge, y forzar un push al branch remoto.

Suerte para mí: soy quién gestiona el proyecto. Podía romper el historial -con mucho cuidado- porque soy yo quién integra las características (de todos modos avisé que nadie toque nada en develo por las dudas).

Mi historia había quedado muy sucia y por varios motivos, prefería destruir esa historia totalmente, para poder volver a realizar el merge como quería hacerlo originalmente.

En otras palabras: quería deshacer un historial sucio mediante una acción más sucia aún.

Nasty.

Nasty

Lo intenté. No funcionó. El error recibido era el siguiente.

$ git push -f
Total 0 (delta 0), reused 0 (delta 0)
remote: permission denied to force push branch develop
To https://xxxxxx@bitbucket.org/yyyyyy/zzzzzz.git
 ! [remote rejected] develop -> develop (pre-receive hook declined)
error: failed to push some refs to 'https://xxxxxx@bitbucket.org/yyyyyy/zzzzzz.git'

Lo raro era que hice esto varias veces (sí, no tengo miedo al decirlo) y no había recibido este error.

Luego de investigar por la web, encontré que esto era por una medida de seguridad que Bitbucket tiene por defecto para los branches master y develop.

La solución

Ingresás a tu proyecto en Bitbucket y luego vas a:

  1. Settings
  2. Branch management
  3. Sacar la rama develop o master de Prevent history re-writes (rebase) on these branches

Prevent history re-writes (rebase) on these branches

Luego de esto, podrás hacer git push -f sin recibir este error.

No olvidés volver a incluir la rama en esta característica de seguridad al terminar de realizar este acto criminal.




¡Gracias por tu tiempo!

Soy nahuelhds. Si te gusta lo que hago, podés...