Si presiono una confirmación modificada, creará una nueva confirmación

Ya presioné una confirmación en la twig remota y ahora quiero cambiar su contenido, así que probé la modificación de git. Si el estado de git dice que las dos twigs tienen 1 y 1 commits diferentes cada uno, respectivamente. Ahora si presiono la confirmación modificada con el mismo post de confirmación, ¿agregará una nueva confirmación o cambiará la última confirmación que he enviado?

git commit --amend , al igual que git rebase , creará un nuevo object de commit. Ese object se basa en un compromiso previamente existente, pero sigue siendo un nuevo compromiso y reemplaza el antiguo por completo.

Mirando la historia, esto podría verse así:

  master ↓ * --- * --- * --- A 

Teniendo en count que A es la confirmación original. Si ahora modificamos este compromiso, obtenemos el siguiente resultado:

 * --- * --- * --- A \ --- A' ↑ master 

Entonces obtenemos un object de compromiso diferente A' , con un hash diferente, y la twig en la que estábamos (aquí: maestro) se actualiza para señalar a este.

Ahora, si agregamos un repository remoto a esa vista, y presionamos A previamente en el control remoto, entonces se ve así:

  origin/master ↓ * --- * --- * --- A \ --- A' ↑ master 

Entonces, el control remoto aún apunta a la confirmación original A , pero nuestra sucursal local apunta a la A' modificada. Esto es un problema porque no podemos presionar A' y hacer que el punto de origin/master A' ya que esto eliminaría el compromiso A ya empujado del historial.

Podemos realizar un empuje forzado usando git push --force para forzar a Git a actualizar la twig remota y, de hecho, eliminar A del historial. Sin embargo, es importante señalar que esto romperá la historia de todos los que ya han obtenido A desde el control remoto. Si algún otro desarrollador tiene A y ahora los puntos remotos en A' , entonces tienen un conflicto que tienen que arreglar manualmente. Esto a menudo es un dolor de hacer, por lo que hay una regla que debe seguir en todo momento:

Nunca rebase (o corrija) confirmaciones publicadas previamente.

La mejor alternativa es agregar una nueva confirmación B que simplemente haga las correcciones a A :

  origin/master ↓ * --- * --- * --- A --- B ↑ master 

De esta forma, la historia ya publicada sigue siendo compatible con la nueva historia, por lo que podemos empujar B al remoto sin conflictos, y todos están contentos.

tl; dr

Presionar una confirmación modificada significa presionar una confirmación diferente .

Anatomía de una identificación de compromiso

La ID única de una confirmación se compone del hash SHA-1 de sus metadatos. ¿Qué metadatos? Una de las forms de averiguarlo es usar el command cat-file plomería :

 git cat-file -p HEAD 

Después de ejecutar este command, verá una list que contiene estos campos:

  • Árbol
  • Padre
  • Autor
  • Committer
  • Mensaje

Si alguno de estos campos cambia, su hash SHA-1 también cambiará al otorgarle a la confirmación una identificación completamente nueva .

Enmendar es reescribir el historial

Es por eso que si modifica una confirmación, por ejemplo cambiando su post , tendrá una ID diferente a la que tenía anteriormente. Está efectivamente reescribiendo la historia .

Tenga en count que la ID del padre del compromiso también se incluye en los metadatos. Esto significa que una vez que una confirmación cambia de ID, todos sus descendientes también cambiarán las ID como un efecto dominó.

Una vez que haya presionado hacia el control remoto, no debe modificar localmente las confirmaciones existentes.

Básicamente, ha creado un nuevo compromiso localmente (hay un nuevo ID de confirmación) y reemplazó el anterior, pero el antiguo todavía existe en el control remoto. Esto causa el post 1 adelante y 1 detrás que ves.

Para resolverlo, deberá crear una nueva sucursal para mantener sus modificaciones, volver a verificar la bifurcación inicial, restablecerla antes de realizar la modificación, desplegar el cambio desde el control remoto. Luego, conéctese en su sucursal separada y vuelva a presionar.