¿Cómo reformulo el primer mensaje de confirmación de git?

116

Tengo un árbol de trabajo que contiene 3 commmit:

➜ ~ myproject git: (maestro) git log

commit a99cce8240495de29254b5df8745e41815db5a75
Author: My Name <[email protected]>
Date:   Thu Aug 16 00:59:05 2012 +0200

    .gitignore edits

commit 5bccda674c7ca51e849741290530a0d48efd69e8
Author: My Name <[email protected]>
Date:   Mon Aug 13 01:36:39 2012 +0200

    Create .gitignore file

commit 6707a66191c84ec6fbf148f8f1c3e8ac83453ae3
Author: My Name <[email protected]>
Date:   Mon Aug 13 01:13:05 2012 +0200

    Initial commit (with a misleading message)

Ahora deseo rewordel mensaje de confirmación de mi primera confirmación (6707a66)

➜ ~ myproject git: (maestro) git rebase -i 6707

(... entrando vim)

pick 5bccda6 Create .gitignore file
pick a99cce8 .gitignore edits

# Rebase 6707a66..a99cce8 onto 6707a66
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

En este caso, deseo corregir ( reworden el lenguaje de git) el mensaje de confirmación en cuestión:

Confirmación inicial (con un mensaje engañoso)

… A algo apropiado.

Como era de esperar, mi intento anterior no tuvo éxito ya que la primera confirmación obviamente no tiene ninguna confirmación principal . (Y cuando usted rebase, necesita hacer referencia a la siguiente confirmación más antigua antes de la que desea reword, ¿verdad?)

La esencia de mi pregunta, entonces, ¿puede lograr esto por cualquier otro medio de hacerlo?

Henrik
fuente
O simplemente puede dejarlo para siempre como una peculiaridad de mal gusto del
Christopher
4
posible duplicado de ¿ Cambiar el mensaje de la primera confirmación? (git)
Mark Longair
^ Muy cierto ... Pensé que había buscado correctamente esta pregunta en particular, pero es la misma que la mía. Se necesita una gran cantidad de perfeccionamiento de la redacción publicitaria de mi pregunta. :-P
Henrik
1
@hced: :) su redacción no se desperdicia; ayudará a otras personas a encontrar una solución en el futuro, incluso si se cerrara como un duplicado
Mark Longair
2
Cualquiera que se encuentre con esta pregunta puede encontrar mi respuesta a ¿ Cambiar el mensaje de la primera confirmación? (git) para ser útil.

Respuestas:

215

Hacer git rebase -i --root

(apunte en rootlugar de apuntar a una confirmación específica)

De esta manera, también se incluye la primera confirmación y puede rewordhacerlo como cualquier otra confirmación.

La --rootopción se introdujo en Git v1.7.12(2012). Antes, la única opción era usar filter-brancho --amend, que suele ser más difícil de hacer.

Nota: consulte también esta pregunta y respuesta similares .

florisla
fuente
12

Siempre puedes usar git filter-branch --msg-filter:

git filter-branch --msg-filter \
  'test $GIT_COMMIT = '$(git rev-list --reverse master |head -n1)' &&
echo "Nice message" || cat' master
fork0
fuente
1
fork0: Eso es genial, gracias. Es curioso que esto se considere una práctica "legítima", a falta de una mejor palabra. Quiero decir, ¿es común / recomendado hacerlo así? Además, ¿puede hacer esto una y otra vez en casos con mensajes de confirmación defectuosos? La razón para preguntar eso es porque primero lo hice con la confirmación incorrecta SHA-1, copiando su fragmento (la suya fue la última confirmación, mientras que quería cambiar la primera). Después de usar el comando una vez más, esta vez con SHA-1 correcto (primer compromiso; 6707a66), me vomitó.
Henrik
Bueno, es común :) Y sí, puedes repetirlo. Si solo agrega -f, seguirá adelante y siempre reescribirá las confirmaciones de la rama dada. El valor de referencia de la rama de la primera vez se guardó en refs/original/master, antes de ejecutar el comando.
fork0
Por supuesto, puede eliminar (o cambiar el nombre) de la referencia guardada.
fork0
2
Actualicé el código para asegurarme de que no ocurra el error con la identificación de confirmación copiada. Ahora el código es incluso copiable. Sin embargo, una advertencia : no funciona correctamente si hay más de una confirmación inicial (es decir, cuando fusionó dos o más ramas no relacionadas)
fork0
3
@hced: debe tener en cuenta que reescribir cualquier confirmación que se considere "historial publicado" suele ser una mala idea. En su caso, eso significaría que, por lo general, no debería hacer esto si alguien más hubiera estado trabajando en una confirmación que tenía su confirmación raíz como antepasado.
Mark Longair
12

La esencia de pcreux tiene una buena manera de reformular la primera confirmación:

# You can't use rebase -i here since it takes the parent commit as argument.
# You can do the following though:
git checkout FIRST_COMMIT_SHA && git commit --amend && git rebase HEAD master
Douglas
fuente
3
A partir de git 1.7.12 , git rebase -i --rootes el camino a seguir, como sugiere florisla.
Douglas