¿Cómo modifico un compromiso específico?

Resuelto Sam Liao asked hace 15 años • 22 respuestas

Tengo el siguiente historial de confirmaciones:

  1. HEAD
  2. HEAD~
  3. HEAD~2
  4. HEAD~3

git commit --amendmodifica la HEADconfirmación actual. ¿Pero cómo lo modifico HEAD~3?

Sam Liao avatar Jul 27 '09 12:07 Sam Liao
Aceptado

Usar git rebase. Por ejemplo, para modificar el compromiso bbc643cd, ejecute:

git rebase --interactive bbc643cd~

Tenga en cuenta la tilde ~al final del comando, porque necesita volver a aplicar confirmaciones además de la confirmación anterior debbc643cd (es decir bbc643cd~).

En el editor predeterminado, modifíquelo picken editla línea que mencionabbc643cd .

Guarda el archivo y cierra. git interpretará y ejecutará automáticamente los comandos del archivo. Te encontrarás en la situación anterior en la que acabas de crear el compromiso.bbc643cd .

En este punto, bbc643cdes su último compromiso y puede modificarlo fácilmente . Realice sus cambios y luego confírmelos con el comando:

git commit --all --amend --no-edit

Después de eso, regrese al compromiso HEAD anterior usando:

git rebase --continue

ADVERTENCIA : Tenga en cuenta que esto cambiará el SHA-1 de esa confirmación, así como de todos los elementos secundarios ; en otras palabras, esto reescribe la historia desde ese momento en adelante. Puedes romper repositorios haciendo esto si presionas usando el comando git push --force.

ZelluX avatar Jul 27 '2009 05:07 ZelluX

Utilice la increíble rebase interactiva:

git rebase -i    # Show your commits in a text editor

Busque la confirmación que desee, cámbiela picka e( edit), guarde y cierre el archivo. Git rebobinará hasta ese compromiso, permitiéndole:

  • utilizar git commit --amendpara realizar cambios, o
  • utilícelo git reset @~para descartar la última confirmación, pero no los cambios en los archivos (es decir, llevarlo al punto en el que se encontraba cuando editó los archivos, pero aún no se había comprometido).

Este último es útil para hacer cosas más complejas como dividir en múltiples confirmaciones.

Luego, ejecute git rebase --continuey Git reproducirá los cambios posteriores además de su confirmación modificada. Es posible que se le solicite que solucione algunos conflictos de fusión.

Nota: @es una abreviatura de HEADy ~es la confirmación antes de la confirmación especificada.

Lea más sobre cómo reescribir el historial en los documentos de Git.


No tengas miedo de rebase

ProTip™: No tengas miedo de experimentar con comandos "peligrosos" que reescriben el historial*: Git no elimina tus confirmaciones durante 90 días de forma predeterminada; Puedes encontrarlos en el reflog:

$ git reset @~3   # go back 3 commits
$ git reflog
c4f708b HEAD@{0}: reset: moving to @~3
2c52489 HEAD@{1}: commit: more changes
4a5246d HEAD@{2}: commit: make important changes
e8571e4 HEAD@{3}: commit: make some changes
... earlier commits ...
$ git reset 2c52489
... and you're back where you started

* Tenga cuidado con opciones como --hardy --forceaunque: pueden descartar datos.
* Además, no reescribas el historial de ninguna rama en la que estés colaborando.



En muchos sistemas, git rebase -ise abrirá Vim de forma predeterminada. Vim no funciona como la mayoría de los editores de texto modernos, así que eche un vistazo a cómo cambiar la base usando Vim . Si prefieres utilizar un editor diferente, cámbialo con git config --global core.editor your-favorite-text-editor.

Zaz avatar Apr 29 '2015 17:04 Zaz

Rebase interactivo con--autosquash uso con frecuencia cuando necesito arreglar confirmaciones anteriores más profundas en el historial. Básicamente, acelera el proceso que ilustra la respuesta de ZelluX y es especialmente útil cuando tiene más de una confirmación que necesita editar.

De la documentación:

--autosquash

Cuando el mensaje de registro de confirmación comienza con "squash! …​" (o "¡reparación! …​"), y hay una confirmación cuyo título comienza con el mismo …​, modifica automáticamente la lista de tareas pendientes de rebase -i para que la confirmación marcado para aplastamiento viene justo después del compromiso que se va a modificar

Suponga que tiene un historial similar a este:

$ git log --graph --oneline
* b42d293 Commit3
* e8adec4 Commit2
* faaf19f Commit1

y tiene cambios que desea modificar en Commit2, luego confirme sus cambios usando

$ git commit -m "fixup! Commit2"

alternativamente, puede usar commit-sha en lugar del mensaje de confirmación, "fixup! e8adec4o incluso simplemente un prefijo del mensaje de confirmación.

Luego inicie una rebase interactiva en la confirmación antes

$ git rebase e8adec4^ -i --autosquash

su editor se abrirá con las confirmaciones ya ordenadas correctamente

pick e8adec4 Commit2
fixup 54e1a99 fixup! Commit2
pick b42d293 Commit3

todo lo que necesitas hacer es guardar y salir

thrau avatar Sep 29 '2015 17:09 thrau

Basado en documentación

Modificar el mensaje de mensajes de confirmación más antiguos o múltiples

git rebase -i HEAD~3 

Lo anterior muestra una lista de las últimas 3 confirmaciones en la rama actual, cambie 3 a otra cosa si desea más. La lista será similar a la siguiente:

pick e499d89 Delete CNAME
pick 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Reemplace pick con reformular antes de cada mensaje de confirmación que desee cambiar. Digamos que cambia la segunda confirmación en la lista, su archivo se verá así:

pick e499d89 Delete CNAME
reword 0c39034 Better README
pick f7fde4a Change the commit message but push the same commit.

Guarde y cierre el archivo de la lista de confirmación; esto abrirá un nuevo editor para que pueda cambiar su mensaje de confirmación, cambiar el mensaje de confirmación y guardar.

Finalmente, fuerce las confirmaciones modificadas.

git push --force
justMe avatar May 17 '2018 08:05 justMe

Correr:

$ git rebase --interactive commit_hash^

cada uno ^indica cuántas confirmaciones desea editar; si es solo una (el hash de confirmación que especificó), simplemente agrega una ^.

Al usar Vim, cambia las palabras pickpara rewordlas confirmaciones que desea cambiar, guardar y salir ( :wq). Luego, git le indicará cada confirmación que marcó como reformulación para que pueda cambiar el mensaje de confirmación.

Cada mensaje de confirmación debe guardarse y salir ( :wq) para ir al siguiente mensaje de confirmación.

Si desea salir sin aplicar los cambios, presione:q!

EDITAR : para navegar vimusas jsubir, kbajar, hir a la izquierda e lir a la derecha (todo esto en NORMALmodo, presiona ESCpara ir al NORMALmodo). Para editar un texto, presione ipara ingresar al INSERTmodo donde inserta texto. Pulsa ESCpara volver al NORMALmodo :)

ACTUALIZACIÓN : Aquí hay un excelente enlace de la lista de github Cómo deshacer (casi) cualquier cosa con git

betoharres avatar Jul 02 '2015 19:07 betoharres

Comando completamente no interactivo (1)

Sólo pensé en compartir un alias que estoy usando para esto. Se basa en una rebase interactiva no interactiva . Para agregarlo a su git, ejecute este comando (la explicación se proporciona a continuación):

git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`; git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"; }; f'

O bien, una versión que también puede manejar archivos no preparados (guardándolos y luego anulándolos):

git config --global alias.amend-to '!f() { SHA=`git rev-parse "$1"`; git stash -k && git commit --fixup "$SHA" && GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^" && git stash pop; }; f'

La mayor ventaja de este comando es el hecho de que no es vim .


(1) dado que no hay conflictos durante el rebase, por supuesto

Uso

git amend-to <REV> # e.g.
git amend-to HEAD~1
git amend-to aaaa1111

El nombre amend-toparece apropiado en mi humilde opinión. Compara el flujo con --amend:

git add . && git commit --amend --no-edit
# vs
git add . && git amend-to <REV>

Explicación

  • git config --global alias.<NAME> '!<COMMAND>'- crea un alias global de git llamado <NAME>que ejecutará un comando que no sea de git<COMMAND>
  • f() { <BODY> }; f- una función bash "anónima".
  • SHA=`git rev-parse "$1"`;- convierte el argumento a revisión de git y asigna el resultado a la variableSHA
  • git commit --fixup "$SHA"- compromiso de reparación para SHA. Ver git-commitdocumentos
  • GIT_SEQUENCE_EDITOR=true git rebase --interactive --autosquash "$SHA^"
    • git rebase --interactive "$SHA^"parte ha sido cubierta por otras respuestas.
    • --autosquashes lo que se usa junto con git commit --fixup, consulte git-rebaselos documentos para obtener más información
    • GIT_SEQUENCE_EDITOR=truees lo que hace que todo el asunto no sea interactivo. Este truco lo aprendí de esta publicación de blog .
Dethariel avatar Feb 27 '2018 01:02 Dethariel