Si se presiona una confirmación al servidor, y luego volver a escribir que se comprometen a nivel local (con git reset
, git rebase
, git filter-branch
, o cualquier otra manipulación de la historia), y luego empujados que reescrita cometen una copia de seguridad en el servidor, se le arruinar cualquier otra persona que se había detenido. He aquí un ejemplo; digamos que ha comprometido A y lo ha enviado al servidor.
- * - * - A <- maestro
- * - * - A <- origen / maestro
Ahora decides reescribir A, de la forma que mencionaste, reiniciando y volviendo a confirmar. Tenga en cuenta que esto deja una confirmación pendiente, A, que eventualmente será recolectada como basura ya que no es accesible.
-*-*-UNA
\
A '<- maestro
- * - * - A <- origen / maestro
Si alguien más, digamos Fred, se retira master
del servidor mientras haces esto, tendrá una referencia a A, desde la cual podría comenzar a trabajar:
- * - * - A '<- maestro
- * - * - A <- origen / maestro
- * - * - AB <- fred / master
Ahora bien, si pudiera empujar su A 'al origen / maestro, lo que crearía un avance no rápido, no tendría A en su historial. Entonces, si Fred intentara tirar nuevamente, de repente tendría que fusionarse y volvería a presentar el compromiso A:
- * - * - A '<- maestro
- * - * - A <- origen / maestro
- * - * - AB- \
\ * <- fred / maestro
UNA'--/
Si Fred se da cuenta de esto, entonces podría hacer un cambio de base, lo que evitaría que la confirmación A reapareciera nuevamente. Pero tendría que darse cuenta de esto y recordar hacer esto; y si tiene más de una persona que derribó A, todos tendrían que volver a basarse para evitar que el compromiso A adicional en el árbol.
Por lo tanto, generalmente no es una buena idea cambiar el historial en un repositorio del que otras personas obtienen. Sin embargo, si sabe que nadie más está extrayendo de ese repositorio (por ejemplo, es su propio repositorio privado, o solo tiene otro desarrollador trabajando en el proyecto con el que puede coordinarse fácilmente), entonces puede forzarlo actualizar ejecutando:
git push -f
o
git push origin +master
Ambos ignorarán la verificación de un empuje que no es de avance rápido y actualizarán lo que hay en el servidor a su nueva revisión A ', abandonando la revisión A para que eventualmente se recolecte basura.
Es posible que los empujes forzados estén completamente deshabilitados con la receive.denyNonFastForwards
opción de configuración. Esta opción está habilitada de forma predeterminada en los repositorios compartidos. En ese caso, si realmente desea forzar un envío, la mejor opción es eliminar la rama y volver a crearla con git push origin :master; git push origin master:master
. Sin embargo, la denyNonFastForwards
opción está habilitada por un motivo, que se describe anteriormente; en un repositorio compartido, significa que ahora todos los que lo utilizan deben asegurarse de volver a basarse en el nuevo historial.
En un repositorio compartido, generalmente es mejor colocar nuevas confirmaciones en la parte superior que solucionen cualquier problema que tenga; puede usar git revert
para generar confirmaciones que deshacerán los cambios de confirmaciones anteriores.