¿Cómo modificar una confirmación especificada?

2233

Normalmente presento una lista de confirmaciones para su revisión. Si tengo los siguientes commits:

  1. HEAD
  2. Commit3
  3. Commit2
  4. Commit1

... Sé que puedo modificar head commit con git commit --amend. Pero, ¿cómo puedo modificar Commit1, dado que no es el HEADcommit?

Sam Liao
fuente
31
Vea una respuesta alternativa aquí: stackoverflow.com/a/18150592/520567 Su respuesta aceptada es realmente una respuesta exacta a su pregunta, pero si tiene lista su nueva confirmación antes de decidir usar la edición, entonces esta respuesta sería más sencilla. También puede funcionar con varias confirmaciones que desea fusionar / aplastar junto con una anterior.
akostadinov
66
También puede ver Dividir una confirmación en Git Tools - Rewriting History para obtener más información.
Hakre

Respuestas:

2957

Puedes usar git rebase . Por ejemplo, si desea modificar commit bbc643cd, ejecute

$ git rebase --interactive 'bbc643cd^'

Tenga en cuenta el símbolo ^de intercalación al final del comando, ya que en realidad debe volver a redactar la confirmación antes de la que desea modificar .

En el editor predeterminado, modifique picka editen la línea que menciona 'bbc643cd'.

Guarde el archivo y salga: git interpretará y ejecutará automáticamente los comandos en el archivo. Te encontrarás en la situación anterior en la que acabas de crear commit bbc643cd.

En este punto, bbc643cdes su última confirmación y puede modificarla fácilmente : realice sus cambios y luego confirme con el comando:

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

Después de eso, escriba:

$ git rebase --continue

para volver a la confirmación HEAD anterior.

ADVERTENCIA : Tenga en cuenta que esto cambiará el SHA-1 de ese commit , así como todos los hijos ; en otras palabras, esto reescribe el historial a partir de ese momento. Puede romper repos haciendo esto si presiona usando el comandogit push --force

ZelluX
fuente
125
Otra opción interesante dentro de este flujo es que una vez que se haya movido a la confirmación que desea modificar, en lugar de modificar archivos y agregar la confirmación en la parte superior (la que está editando), es posible que desee dividir esa confirmación en dos confirmaciones diferentes (o incluso más) En ese caso, regrese al commit para editar y ejecute "git reset HEAD ^". eso pondrá los archivos modificados de ese commit en el escenario. Ahora elija y confirme los archivos que desee. Este flujo se explica bastante bien en la página de manual "git-rebase". Consulte la sección "Compromisos de división". bit.ly/d50w1M
Diego Pino
200
En Git 1.6.6 y versiones posteriores, puede usar la rewordacción en git rebase -ilugar de edit(abre automáticamente el editor y continúa con el resto de los pasos de rebase; esto evita el uso de git commit --ammendy git rebase --continuecuando solo necesita cambiar el mensaje de confirmación y no el contenido )
Chris Johnsen
108
Vale la pena señalar que es posible que deba ejecutar git stashantes git rebasey git stash popdespués, si tiene cambios pendientes.
user123444555621
3
¿Existe un comando de acceso directo para editar una confirmación específica en el rebase interactivo sin abrir el editor, encontrar la confirmación, marcarla como edición y luego volver a la línea de comando?
sstur
15
Tenga en cuenta que con git más nuevo, sería más prudente seguir instrucciones rápidas en lugar de usarlo ciegamente git commit --all --amend --no-editaquí. Todo lo que tenía que hacer después git rebase -i ...era hacerlo git commit --amendnormalmente git rebase --continue.
Eric Chen
453

Utilice la impresionante rebase interactiva:

git rebase -i @~9   # Show the last 9 commits in a text editor

Encuentre la confirmación que desea, cambie picka e( edit) y guarde y cierre el archivo. Git se rebobinará con esa confirmación, permitiéndole:

  • usar git commit --amendpara hacer cambios, o
  • use git reset @~para descartar la última confirmación, pero no los cambios en los archivos (es decir, llevarlo al punto en el que estaba cuando editó los archivos, pero aún no se comprometió).

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

Luego, ejecute git rebase --continue, y 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 HEAD, y ~es la confirmación antes de la confirmación especificada.

Lea más sobre la reescritura del historial en los documentos de Git.


No tengas miedo de rebase

ProTip ™: no tenga miedo de experimentar con comandos "peligrosos" que reescriben el historial *: Git no elimina sus 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 las opciones como --hardy --forceaunque pueden descartar datos.
* Además, no reescriba el historial en ninguna rama en la que esté colaborando.



En muchos sistemas, git rebase -ise abrirá Vim por defecto. Vim no funciona como la mayoría de los editores de texto modernos, así que eche un vistazo a cómo volver a crear una base usando Vim . Si prefiere usar un editor diferente, cámbielo con git config --global core.editor your-favorite-text-editor.

Zaz
fuente
29
El centro de su respuesta es un lugar extraño para poner lo que solo puedo describir como un anuncio en miniatura para VIM. Es irrelevante para la pregunta y solo llena tu respuesta.
Intentos
21
@Intentss: Ah, puedo ver por qué eso se veía raro. El razonamiento detrás de esto fue que Vim es el editor de texto predeterminado en muchos sistemas, por lo que la primera experiencia de rebase interactivo de muchas personas es una pantalla donde la escritura hace que el cursor vuele por todo el lugar. Luego, cambian su editor a otra cosa, y su segunda experiencia de rebase interactivo es bastante normal, pero los deja preguntándose por qué usa un archivo de texto en lugar de una GUI. Para lograr el flujo con rebase, necesita algo como Vim, o el modo rebase de Emacs.
Zaz
99
Bueno. Al ver que tanta gente encuentra esa parte irrelevante, la condensé en 3 líneas y también le expliqué cómo cambiar el editor si es necesario.
Zaz
17
¡Increíble! No sabía que podías usar @como taquigrafía HEAD. Gracias por publicar esto.
James Ko
3
git reset @~exactamente lo que quería hacer después de elegir commit with git rebase .... Eres mi héroe)
18 de agosto
79

El rebase interactivo con --autosquashes algo que uso con frecuencia cuando necesito arreglar compromisos previos más profundos en la historia. 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 "arreglo! ..."), y hay una confirmación cuyo título comienza con el mismo ..., modifique automáticamente la lista de tareas de rebase -i para que la confirmación marcado para aplastar viene justo después de que se modifique la confirmación

Supongamos que tiene un historial que se ve así:

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

y tiene cambios que desea modificar a Commit2 y luego confirme sus cambios usando

$ git commit -m "fixup! Commit2"

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

Luego inicie un rebase interactivo en el commit antes

$ git rebase e8adec4^ -i --autosquash

su editor se abrirá con los commits ya ordenados correctamente

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

todo lo que necesitas hacer es guardar y salir

Thrau
fuente
21
También puede usar en git commit --fixup=@~lugar de git commit -m "fixup! Commit2". Esto es especialmente útil cuando los mensajes de confirmación son más largos y sería difícil escribir todo.
Zaz
42

Correr:

$ git rebase --interactive commit_hash^

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

Usando Vim, cambia las palabras picka rewordlas confirmaciones que desea cambiar, guardar y salir ( :wq). Luego, git le indicará con cada confirmación que marcó como cambio de palabra para que pueda cambiar el mensaje de confirmación.

Cada mensaje de confirmación que tiene que guardar y salir ( :wq) para ir al siguiente mensaje de confirmación

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

EDITAR : para navegar vim, usa jpara subir, kpara bajar, hpara ir a la izquierda y lpara ir a la derecha (todo esto en NORMALmodo, presione ESCpara ir al NORMALmodo). Para editar un texto, presione ipara ingresar al INSERTmodo donde inserta el texto. Presione ESCpara volver al NORMALmodo :)

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

betoharres
fuente
44
Funcionó perfectamente para mí. Vale la pena mencionar git push --force?
u01jmg3
Lo que git push --forcehace es sobrescribir las confirmaciones remotas con sus confirmaciones locales. Ese no es el caso de este tema :)
betoharres
@BetuUuUu, por supuesto, si sus confirmaciones se envían a control remoto y ha modificado el mensaje de confirmación localmente, querría forzar la inserción a control remoto, ¿no es así?
Sudip Bhandari
@SudipBhandari Esa es la sensación que tengo. No forcé, y ahora tengo una rama adicional, reflejando todas las confirmaciones de nuevo a aquel cuyo mensaje cambié, lo cual es súper feo.
ruffin
2
@greenhouse si modificas y presionas a la fuerza, entonces otros miembros del equipo probablemente encontrarán conflictos de fusión. Por lo tanto, debe ser muy cauteloso al respecto. Pero si modifica algo que nadie más obtuvo todavía, debería estar bien (no lo notará). Por lo tanto, consideraría --force como último recurso y siempre consultar el estado del repositorio con otros miembros.
Tomasz Kaczmarzyk
18

Si por alguna razón no le gustan los editores interactivos, puede usarlos git rebase --onto.

Digamos que quieres modificar Commit1. Primero, bifurca desde antes Commit1 :

git checkout -b amending [commit before Commit1]

Segundo, agarra Commit1con cherry-pick:

git cherry-pick Commit1

Ahora, modifique sus cambios, creando Commit1':

git add ...
git commit --amend -m "new message for Commit1"

Y finalmente, después de haber ocultado cualquier otro cambio, trasplante el resto de sus confirmaciones hasta la masterparte superior de su nueva confirmación:

git rebase --onto amending Commit1 master

Lea: "rebase, en la rama amending, todos los compromisos entre Commit1(no inclusivo) e master(inclusivo)". Es decir, Commit2 y Commit3, eliminando por completo el viejo Commit1. Podrías simplemente elegirlos, pero de esta manera es más fácil.

¡Recuerda limpiar tus ramas!

git branch -d amending
FeepingCreature
fuente
44
puede utilizar git checkout -b amending Commit1~1para obtener el compromiso previo
Arin Taylor
¿Son equivalentes los dos primeros pasos git checkout -b amending Commit1?
Haoshu
16

Basado en documentación

Modificación del mensaje de mensajes de confirmación anteriores o múltiples

git rebase -i HEAD~3 

Lo anterior muestra una lista de los últimos 3 commits 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 reword antes de cada mensaje de confirmación que desee cambiar. Digamos que cambia la segunda confirmación en la lista, su archivo tendrá el siguiente aspecto:

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, aparecerá un nuevo editor para que pueda cambiar su mensaje de confirmación, cambiar el mensaje de confirmación y guardar.

Finalmente, presione forzosamente los commits enmendados.

git push --force
solo yo
fuente
Me sale el siguiente error: error: Hubo un problema con el editor 'vi'. Proporcione el mensaje utilizando la opción -m o -F.
Erick Maynard
12

Comando completamente no interactivo (1)

Solo pensé en compartir un alias que estoy usando para esto. Se basa en un rebase interactivo no interactivo. 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'

La mayor ventaja de este comando es el hecho de que es no-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-to parece apropiado en mi humilde opinión. Compare 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 git<COMMAND>
  • f() { <BODY> }; f - una función bash "anónima".
  • SHA=`git rev-parse "$1"`; - convierte el argumento a git revision, y asigna el resultado a variable SHA
  • git commit --fixup "$SHA"- Fixup-commit 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, ver git-rebasedocumentos para más información
    • GIT_SEQUENCE_EDITOR=truees lo que hace que todo sea no interactivo. Este truco lo aprendí de esta publicación de blog .
Dethariel
fuente
1
También se puede hacer que se amend-tomanejen los archivos sin clasificar: 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'
Dethariel
2
Una preocupación con este método es que podría aplicar reparaciones no relacionadas.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
¿No es el punto de la pregunta cambiar el mensaje de confirmación? Porque esta respuesta no aborda eso, o al menos no directamente.
wytten
@wytten la pregunta no pregunta sobre cambiar el mensaje de confirmación, se trata de modificar la confirmación que no es HEAD. Entonces una respuesta a su pregunta sería "no, no es el punto de la pregunta"
Dethariel
Estoy confundido, entonces, ¿cómo cambiamos el mensaje de confirmación?
ggb667
8

Edición de rebase interactiva automatizada seguida de revertir confirmación listo para una rehacer

Me encontré arreglando un commit del pasado con tanta frecuencia que escribí un script para él.

Aquí está el flujo de trabajo:

  1. git commit-edit <commit-hash>
    

    Esto lo colocará en la confirmación que desea editar.

  2. Arregle y organice la confirmación como desearía que hubiera sido en primer lugar.

    (Es posible que desee utilizar git stash savepara mantener los archivos que no está confirmando)

  3. Rehaga el compromiso con --amend, por ejemplo:

    git commit --amend
    
  4. Completa el rebase:

    git rebase --continue
    

Para que funcione lo anterior, coloque el siguiente script en un archivo ejecutable llamado git-commit-editen algún lugar de su $PATH:

#!/bin/bash

set -euo pipefail

script_name=${0##*/}

warn () { printf '%s: %s\n' "$script_name" "$*" >&2; }
die () { warn "$@"; exit 1; }

[[ $# -ge 2 ]] && die "Expected single commit to edit. Defaults to HEAD~"

# Default to editing the parent of the most recent commit
# The most recent commit can be edited with `git commit --amend`
commit=$(git rev-parse --short "${1:-HEAD~}")
message=$(git log -1 --format='%h %s' "$commit")

if [[ $OSTYPE =~ ^darwin ]]; then
  sed_inplace=(sed -Ei "")
else
  sed_inplace=(sed -Ei)
fi

export GIT_SEQUENCE_EDITOR="${sed_inplace[*]} "' "s/^pick ('"$commit"' .*)/edit \\1/"'
git rebase --quiet --interactive --autostash --autosquash "$commit"~
git reset --quiet @~ "$(git rev-parse --show-toplevel)"  # Reset the cache of the toplevel directory to the previous commit
git commit --quiet --amend --no-edit --allow-empty  #  Commit an empty commit so that that cache diffs are un-reversed

echo
echo "Editing commit: $message" >&2
echo
Tom Hale
fuente
7

Llegué a este enfoque (y probablemente sea exactamente lo mismo que usar rebase interactivo), pero para mí es algo sencillo.

Nota: presento este enfoque para ilustrar lo que puede hacer en lugar de una alternativa diaria. Dado que tiene muchos pasos (y posiblemente algunas advertencias).

Digamos que quieres cambiar commit 0y actualmente estás enfeature-branch

some-commit---0---1---2---(feature-branch)HEAD

Pague este compromiso y cree un quick-branch. También puede clonar su rama de características como un punto de recuperación (antes de comenzar).

?(git checkout -b feature-branch-backup)
git checkout 0
git checkout -b quick-branch

Ahora tendrá algo como esto:

0(quick-branch)HEAD---1---2---(feature-branch)

Cambios de escenario, esconde todo lo demás.

git add ./example.txt
git stash

Confirmar cambios y finalizar la compra en feature-branch

git commit --amend
git checkout feature-branch

Ahora tendrá algo como esto:

some-commit---0---1---2---(feature-branch)HEAD
           \
             ---0'(quick-branch)

Rebase feature-branchen quick-branch(resolver cualquier conflicto en el camino). Aplicar alijo y eliminar quick-branch.

git rebase quick-branch
git stash pop
git branch -D quick-branch

Y terminas con:

some-commit---0'---1'---2'---HEAD(feature-branch)

Git no duplicará (aunque realmente no puedo decir hasta qué punto) el 0 se compromete al rebasar.

Nota: todos los hash de confirmación se cambian a partir de la confirmación que originalmente teníamos la intención de cambiar.

Olga
fuente
6

Para obtener un comando no interactivo, coloque un script con este contenido en su RUTA:

#!/bin/sh
#
# git-fixup
# Use staged changes to modify a specified commit
set -e
cmt=$(git rev-parse $1)
git commit --fixup="$cmt"
GIT_EDITOR=true git rebase -i --autosquash "$cmt~1"

Úselo organizando sus cambios (con git add) y luego ejecute git fixup <commit-to-modify>. Por supuesto, seguirá siendo interactivo si tienes conflictos.

Pelle Nilsson
fuente
1
Esto funciona bien Agregué algunas funciones adicionales para hacer reparaciones parciales de un árbol sucio para perfeccionar un conjunto de confirmación. `dirtydiff = $ (git diff); if ["$ {dirtydiff}"! = ""]; luego repita "Guardar árbol sucio"> & 2; git alijo; fi;
Simon Feltman
6

git stash+ rebaseautomatización

Para cuando necesito modificar un antiguo commit muchas veces para las revisiones de Gerrit, he estado haciendo:

git-amend-old() (
  # Stash, apply to past commit, and rebase the current branch on to of the result.
  current_branch="$(git rev-parse --abbrev-ref HEAD)"
  apply_to="$1"
  git stash
  git checkout "$apply_to"
  git stash apply
  git add -u
  git commit --amend --no-edit
  new_sha="$(git log --format="%H" -n 1)"
  git checkout "$current_branch"
  git rebase --onto "$new_sha" "$apply_to"
)

GitHub aguas arriba .

Uso:

  • modificar el archivo fuente, no es necesario git addsi ya está en repositorio
  • git-amend-old $old_sha

Me gusta esto --autosquashya que no aplasta otras reparaciones no relacionadas.

Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
fuente
Muy buena solución, esta debería ser una opción predeterminada git amendpara aplicar cambios a una confirmación específica con el uso del alijo actual, ¡muy inteligente!
caiohamamura
5

Resolví esto

1) creando una nueva confirmación con los cambios que quiero ...

r8gs4r commit 0

2) Sé qué compromiso necesito fusionar con él. que es commit 3.

entonces, el git rebase -i HEAD~4# 4 representa el commit 4 reciente (aquí commit 3 está en el 4to lugar)

3) en el rebase interactivo la confirmación reciente se ubicará en la parte inferior. se verá igual

pick q6ade6 commit 3
pick vr43de commit 2
pick ac123d commit 1
pick r8gs4r commit 0

4) aquí necesitamos reorganizar commit si quieres fusionar con uno específico. debería ser como,

parent
|_child

pick q6ade6 commit 3
f r8gs4r commit 0
pick vr43de commit 2
pick ac123d commit 1

después de reorganizar, debe reemplazarlo p pickcon f(la reparación se fusionará sin el mensaje de confirmación) o s(la combinación de squash con el mensaje de confirmación puede cambiar en el tiempo de ejecución)

y luego salva tu árbol.

ahora fusionar hecho con commit existente.

Nota: No es un método preferible a menos que lo mantengas solo. Si tiene un gran tamaño de equipo, no es un método aceptable para reescribir git tree terminará en conflictos que no conoce otros. si quieres mantener tu árbol limpio con menos commits, puedes probar esto y si su pequeño equipo de lo contrario no es preferible .....

Mohideen bin Mohammed
fuente
Esta es una buena solución si no desea realizar modificaciones en vivo durante un rebase interactivo.
Dunatotatos
4

La mejor opción es utilizar el "Comando de rebase interactivo" .

El git rebasecomando es increíblemente poderoso. Le permite editar mensajes de confirmación , combinar confirmaciones, reordenarlas ... etc.

¡Cada vez que reescriba un commit, se creará un nuevo SHA para cada commit, independientemente del contenido que se cambie o no! Debe tener cuidado al usar este comando porque puede tener implicaciones drásticas, especialmente si trabaja en colaboración con otros desarrolladores. Es posible que comiencen a trabajar con su confirmación mientras está modificando algunos. Después de forzar a empujar los commits, no estarán sincronizados y puede descubrirlo más tarde en una situación desordenada. ¡Así que ten cuidado!

Se recomienda crear una backupbifurcación antes de volver a cambiar el nombre para que cada vez que encuentre cosas fuera de control pueda volver al estado anterior.

¿Ahora cómo usar este comando?

git rebase -i <base> 

-isignifica "interactivo" . Tenga en cuenta que puede realizar un rebase en modo no interactivo. ex:

#interactivly rebase the n commits from the current position, n is a given number(2,3 ...etc)
git rebase -i HEAD~n 

HEADindica su ubicación actual (también puede ser el nombre de la sucursal o confirmar SHA). El ~nmedio "n beforeé, por lo que HEAD~nserá la lista de 'n' commit antes del que se encuentra actualmente.

git rebase tiene un comando diferente como:

  • po pickpara mantener el compromiso tal como es.
  • ro reword: para mantener el contenido de la confirmación pero alterar el mensaje de confirmación.
  • so squash: para combinar los cambios de este commit en el commit anterior (el commit arriba en la lista).
  • ... etc.

    Nota: Es mejor hacer que Git funcione con su editor de código para simplificar las cosas. Por ejemplo, si usa código visual, puede agregarlo así git config --global core.editor "code --wait". O puede buscar en Google cómo asociar que prefiere su editor de código con GIT.

Ejemplo de git rebase

Quería cambiar las últimas 2 confirmaciones que hice, así que proceso así:

  1. Mostrar las confirmaciones actuales:
    #This to show all the commits on one line
    $git log --oneline
    4f3d0c8 (HEAD -> documentation) docs: Add project description and included files"
    4d95e08 docs: Add created date and project title"
    eaf7978 (origin/master , origin/HEAD, master) Inital commit
    46a5819 Create README.md
    
  2. Ahora uso git rebasepara cambiar los 2 últimos mensajes de confirmación: $git rebase -i HEAD~2 Abre el editor de código y muestra esto:

    pick 4d95e08 docs: Add created date and project title
    pick 4f3d0c8 docs: Add project description and included files
    
    # Rebase eaf7978..4f3d0c8 onto eaf7978 (2 commands)
    #
    # Commands:
    # p, pick <commit> = use commit
    # r, reword <commit> = use commit, but edit the commit message
    ...
    

    Como quiero cambiar el mensaje de confirmación para estas 2 confirmaciones. Entonces escribiré ro reworden lugar de pick. Luego guarde el archivo y cierre la pestaña. Tenga en cuenta que rebasese ejecuta en un proceso de varios pasos, por lo que el siguiente paso es actualizar los mensajes. Tenga en cuenta también que las confirmaciones se muestran en orden cronológico inverso, por lo que la última confirmación se muestra en esa y la primera confirmación en la primera línea y así sucesivamente.

  3. Actualice los mensajes: Actualice el primer mensaje:

    docs: Add created date and project title to the documentation "README.md"
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    ...
    

    guardar y cerrar Editar el segundo mensaje

    docs: Add project description and included files to the documentation "README.md"
    
    # Please enter the commit message for your changes. Lines starting
    # with '#' will be ignored, and an empty message aborts the commit.
    ...
    

    guardar y cerrar.

  4. Recibirá un mensaje como este al final del rebase: lo Successfully rebased and updated refs/heads/documentationque significa que tiene éxito. Puede mostrar los cambios:

    5dff827 (HEAD -> documentation) docs: Add project description and included files to the documentation "README.md"
    4585c68 docs: Add created date and project title to the documentation "README.md"
    eaf7978 (origin/master, origin/HEAD, master) Inital commit
    46a5819 Create README.md
    

    Deseo que pueda ayudar a los nuevos usuarios :).

DINA TAKLIT
fuente
2

Para mí fue para eliminar algunas credenciales de un repositorio. Traté de rebase y me encontré con una tonelada de conflictos aparentemente no relacionados en el camino al intentar rebase - continuar. No te molestes en intentar cambiar tu base, usa la herramienta llamada BFG (brew install bfg) en mac.

Bolita
fuente
0

Si aún no ha enviado las confirmaciones, puede volver a una confirmación anterior utilizando git reset HEAD^[1,2,3,4...]

Por ejemplo

git commit <file1> -m "Updated files 1 and 2"
git commit <file3> -m "Updated file 3"

¡Vaya! Olvidé agregar file2 al primer commit ...

git reset HEAD^1 // because I only need to go back 1 commit

git add <file2>

Esto agregará file2 a la primera confirmación.

rharvey
fuente
0

Bueno, esta solución puede sonar muy tonta, pero puede salvarte en ciertas condiciones.

Un amigo mío se topó accidentalmente con algunos archivos enormes (cuatro archivos generados automáticamente que van desde 3 GB hasta 5 GB cada uno) y luego realizó algunos compromisos de código adicionales además de eso antes de darse cuenta del problema que git pushya no funcionaba.

Los archivos se habían incluido en la lista, .gitignorepero después de cambiar el nombre de la carpeta del contenedor, ¡quedaron expuestos y comprometidos! Y ahora había algunas confirmaciones más del código además de eso, pero se pushestaba ejecutando para siempre (¡tratando de cargar GB de datos!) Y finalmente fallaría debido a los límites de tamaño de archivo de Github .

El problema con el rebase interactivo o algo similar era que tratarían de hurgar en estos enormes archivos y les tomaría una eternidad hacer cualquier cosa. Sin embargo, después de pasar casi una hora en la CLI, no estábamos seguros de si los archivos (y deltas) realmente se eliminan del historial o simplemente no se incluyen en las confirmaciones actuales. El empuje tampoco estaba funcionando y mi amigo estaba realmente atrapado.

Entonces, la solución que se me ocurrió fue:

  1. Cambie el nombre de la carpeta git actual a ~/Project-old.
  2. Clone la carpeta git nuevamente desde github (a ~/Project).
  3. Pago a la misma sucursal.
  4. Manualmente cp -rlos archivos de la ~/Project-oldcarpeta a ~/Project.
  5. Asegúrese de que los archivos masivos, que no es necesario registrar, estén mveditados e incluidos .gitignorecorrectamente.
  6. También asegúrese de no sobrescribir la .gitcarpeta en el clonado recientemente~/Project por la anterior. ¡Ahí es donde viven los registros de la problemática historia!
  7. Ahora revise los cambios. Debe ser la unión de todos los commits recientes, excluyendo los archivos problemáticos.
  8. Finalmente cometer los cambios, y es bueno estar push'ed.

El mayor problema con esta solución es que trata con la copia manual de algunos archivos, y también combina todos los commits recientes en uno (obviamente con un nuevo commit-hash). B

Los grandes beneficios son que, es muy claro en cada paso, funciona muy bien para archivos grandes (así como para archivos confidenciales) , ¡y no deja ningún rastro en la historia!

Ayuda en
fuente