¿Cómo edito un mensaje de confirmación incorrecto en git (que he presionado)?

152

Quiero modificar un mensaje de confirmación más profundo en la historia y he introducido muchas nuevas confirmaciones.

¿Cómo cambio el mensaje de confirmación? ¿Es posible?

Mehdi Raash
fuente

Respuestas:

125

El mensaje de Linus Torvalds puede responder a su pregunta:

Modificar / editar viejos mensajes de confirmación

Respuesta corta: no puede (si se presiona).


extracto (Linus se refiere a BitKeeper como BK):

Nota al margen, solo por interés histórico: en BK podrías.

Y si estás acostumbrado (como yo), fue realmente bastante práctico. Aplicaría una bomba de parche de Andrew, notaría que algo andaba mal y solo la editaría antes de sacarla.

Podría haber hecho lo mismo con git. Hubiera sido bastante fácil hacer que solo el mensaje de confirmación no formara parte del nombre, y aún así garantizar que el historial no se haya tocado, y permitir la cuestión de "arreglar comentarios más tarde".

Pero no lo hice.

Parte de esto es puramente "consistencia interna". Git es simplemente un sistema más limpio gracias a que todo está protegido por SHA1 y todos los objetos reciben el mismo tratamiento, independientemente del tipo de objeto. Sí, hay cuatro tipos diferentes de objetos, y todos son realmente diferentes, y no se pueden usar de la misma manera, pero al mismo tiempo, incluso si su codificación puede ser diferente en el disco, conceptualmente todos funcionan exactamente lo mismo.

Pero la consistencia interna no es realmente una excusa para ser inflexible, y claramente sería muy flexible si pudiéramos solucionar los errores después de que sucedan. Entonces ese no es un argumento realmente fuerte.

La verdadera razón por la que git no le permite cambiar el mensaje de confirmación termina siendo muy simple: de esa manera, puede confiar en los mensajes. Si permitiste que la gente los cambiara después, los mensajes son intrínsecamente poco confiables.


Para completar, puede reescribir su historial de confirmación local para reflejar lo que desea, como lo sugiere sykora (con un poco de rebase y reinicio: ¡duro, jadeo!)

Sin embargo, una vez que se publique su historia revisada de nuevo (con una git push origin +master:master, la +señal de forzar el empuje que se produzca, incluso si no se traduce en un "avance rápido" commit) ... se puede obtener en algunos problemas .

Extracto de esta otra pregunta SO:

En realidad, una vez presioné con --force to git.git repositorio y Linus me regañó. Creará muchos problemas para otras personas. Una respuesta simple es "no lo hagas".

VonC
fuente
buena respuesta. ¿Sabe si ahora puede cambiar los mensajes de confirmación ya enviados en versiones más nuevas de git? ¿Ha cambiado algo desde que esto se publicó en el '09?
David West
@DavidWest se mantiene el mismo principio: puede reescribir su historial y forzar un empujón.
VonC
2
Para hacer las cosas más específicas, si corrige / rebase los commits, sus identificadores de commit (hashes hexadecimales en el índice git) cambian inevitablemente; significa que las confirmaciones editadas se tratan de manera diferente a sus confirmaciones anteriores en el historial de git VCS. Dicho esto, si los miembros de su equipo de desarrollo lamentablemente ya retiraron los commits antiguos, están obligados a extraer los commits nuevos y editados, y realizar una fusión entre lo antiguo y lo nuevo en sus copias de trabajo locales.
Shigerello
1
Es mejor impulsar los compromisos editados de nuevo para mayor comodidad de sus colegas, eliminando así favorablemente la necesidad de fusionarse en las copias de trabajo de sus colegas.
Shigerello
28

Actualmente, un reemplazo de git podría hacer el truco.

En detalle: crear una rama de trabajo temporal

git checkout -b temp

Restablecer el compromiso para reemplazar

git reset --hard <sha1>

Modifique el compromiso con el mensaje correcto

git commit --amend -m "<right message>"

Reemplace la confirmación anterior por la nueva

git replace <old commit sha1> <new commit sha1>

vuelve a la rama donde estabas

git checkout <branch>

eliminar la rama temporal

git branch -D temp

empujar

guess

hecho.

Johan
fuente
11
@Jonah: Recibo el mensaje "Todo actualizado" cuando intento
ingresar
1
Como se menciona en otra respuesta: use rebase -i con reword. Y reescribirá la historia.
Sylvain
Gracias por la solución que estaba buscando. ¡Me ahorras tiempo!
Tomasz Kuter
1
@ Jonás - Tengo un problema ... su solución actualizó mis registros de confirmación localmente, pero no remotamente. ¿Cómo empujarlos allí?
Tomasz Kuter
1
@TomaszKuter, tuve el mismo problema que tú. Mi mensaje de confirmación no se actualizó de forma remota. Lo resolví utilizando la siguiente ayuda de GitHub: help.github.com/articles/changing-a-commit-message . Siga la sección: Modificación del mensaje de mensajes de confirmación anteriores o múltiples. Básicamente es la respuesta de abajo dada por user987419 Si ya ha cambiado el mensaje de confirmación, puede hacer la selección y guardar sin tener que cambiarlo nuevamente.
evaldeslacasa
19

Puede usar git rebase -i(contra la rama de la que se bifurcó) 'i' para interactiva.

Reemplace el picksiguiente al comentario de confirmación que desea cambiar con r(o reword), guarde y salga y al hacerlo podrá hacer la edición.

git push una vez más y ya está!

Marcus
fuente
1
Esto no permite editar mensajes en confirmaciones de fusión. ¿Es eso posible con alguna variante de este comando?
Andrew Mao
1
Pruebe el -pargumento de rebasequé preservas se fusionan.
Cactus
3
Me gusta este procedimiento, pero al principio no entendí la respuesta. En caso de que alguien necesite ayuda, la página de ayuda de Githulb ofrece buena información al respecto: help.github.com/articles/changing-a-commit-message
evaldeslacasa
15

Supongamos que tienes un árbol como este:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]

Primero, checkoutuna rama temporal:

git checkout -b temp

En la temprama, reset --harda una confirmación que desea cambiar su mensaje (por ejemplo, esa confirmación es 946992):

git reset --hard 946992

Use amendpara cambiar el mensaje:

git commit --amend -m "<new_message>"

Después de eso, el árbol se verá así:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
           \
            b886a0 [temp]

Entonces, cherry-picktodo el commit que está por delante de los 946992de mastera tempy los cometen, su uso amendsi desea cambiar sus mensajes, así:

git cherry-pick 9143a9
git commit --amend -m "<new_message>
...
git cherry-pick 5a6057
git commit --amend -m "<new_message>

El árbol ahora se ve así:

dd2e86 - 946992 - 9143a9 - a6fd86 - 5a6057 [master]
               \
                b886a0 - 41ab2c - 6c2a3s - 7c88c9 [temp]

Ahora fuerza empujar la rama temporal al control remoto:

git push --force origin temp:master

El paso final, elimine la sucursal masteren local, git fetch originpara extraer la sucursal masterdel servidor, luego cambie a la sucursal mastery elimine la sucursal temp.

Ahora tanto su local como su remoto tendrán todos los mensajes actualizados.

Huy Vo
fuente
5

En nuestra tienda, presenté la convención de agregar etiquetas anotadas reconocidas con nombre a las confirmaciones con mensajes incorrectos, y usar la anotación como reemplazo.

Aunque esto no ayuda a las personas que ejecutan comandos casuales de "git log", nos proporciona una forma de corregir las referencias incorrectas del rastreador de errores en los comentarios, y todas mis herramientas de compilación y lanzamiento comprenden la convención.

Obviamente, esta no es una respuesta genérica, pero podría ser algo que la gente pueda adoptar dentro de comunidades específicas. Estoy seguro de que si se usa a mayor escala, podría surgir algún tipo de soporte de porcelana, eventualmente ...

Christian Goetze
fuente
3
"git notes" podría tener un propósito similar
Christian Goetze
2

(De http://git.or.cz/gitwiki/GitTips#head-9f87cd21bcdf081a61c29985604ff4be35a5e6c0 )

Cómo cambiar los compromisos más profundamente en la historia

Dado que el historial en Git es inmutable, arreglar cualquier cosa menos el commit más reciente (commit que no es el encabezado de la rama) requiere que el historial se reescriba desde el commit modificado y hacia adelante.

Puede usar StGIT para eso, inicializar la rama si es necesario, sin comprometerse hasta la confirmación que desea cambiar, abrirla si es necesario, hacer un cambio y luego actualizar el parche (con la opción -e si desea corregir el mensaje de confirmación), luego presione todo y stg commit.

O puede usar rebase para hacer eso. Cree una nueva rama temporal, rebobínela en la confirmación que desea cambiar usando git reset --hard, cambie esa confirmación (sería la parte superior del encabezado actual), luego vuelva a basar la rama encima de la confirmación modificada, usando git rebase --onto.

O puede usar git rebase --interactive, que permite varias modificaciones como reordenamiento de parches, colapso, ...

Creo que eso debería responder a tu pregunta. Sin embargo, tenga en cuenta que si ha insertado código en un repositorio remoto y la gente lo ha retirado, esto va a estropear sus historiales de código, así como el trabajo que han realizado. Entonces hazlo con cuidado.

sykora
fuente
Buena respuesta en teoría, muy peligrosa en la práctica: consulte stackoverflow.com/questions/253055#432518
VonC el
0

Si está utilizando extensiones de Git: vaya a la pantalla Confirmar, debe haber una casilla de verificación que dice "Modificar confirmación" en la parte inferior, como se puede ver a continuación:

ingrese la descripción de la imagen aquí

batsheva
fuente
@KrunalPandya sí, o simplemente presione commit & push
batsheva