ver restaurar regresar modificados eliminar archivos anterior git split commit revision-history

restaurar - ¿Cómo puedo dividir un commit de Git enterrado en la historia?



git ver archivos modificados (4)

Revolví mi historia y quiero hacerle algunos cambios. El problema es que tengo un compromiso con dos cambios no relacionados, y este compromiso está rodeado de algunos otros cambios en mi historial local (no incluido).

Quiero dividir este compromiso antes de expulsarlo, pero la mayoría de las guías que veo tienen que ver con dividir su compromiso más reciente o cambios locales no comprometidos. ¿Es factible hacer esto para un compromiso que está enterrado un poco en la historia, sin tener que "volver a hacer" mis compromisos desde entonces?


Hay una guía para dividir los compromisos en la página de manual de rebase . El resumen rápido es:

  • Realice una rebase interactiva que incluya la confirmación de destino (por ejemplo, git rebase -i <commit-to-split>^ branch ) y márquela para editarla.

  • Cuando el rebase alcance ese compromiso, use git reset HEAD^ para restablecer antes del compromiso, pero mantenga su árbol de trabajo intacto.

  • Aumente los cambios de forma incremental y confírmelos, realizando tantos compromisos como desee. add -p puede ser útil para agregar solo algunos de los cambios en un archivo dado. Utilice commit -c ORIG_HEAD si desea reutilizar el mensaje de confirmación original para una confirmación determinada.

  • Si desea probar lo que está cometiendo (¡buena idea!) git stash para ocultar la parte que no ha cometido (o el stash --keep-index antes de cometerlo), haga una prueba, luego git stash pop para Devuelve el resto al arbol de trabajo. Siga haciendo confirmaciones hasta que haya confirmado todas las modificaciones, es decir, tenga un árbol de trabajo limpio.

  • Ejecute git rebase --continue para continuar aplicando las confirmaciones después de la confirmación ahora dividida.


He aquí cómo hacerlo con Magit .

Say commit ed417ae es el que quieres cambiar; Contiene dos cambios no relacionados y está enterrado bajo uno o más compromisos. Presiona ll para mostrar el registro y navega a ed417ae:

Luego presiona r para abrir la ventana emergente de rebase

y m para modificar el commit en el punto.

Observe cómo @ allí está ahora en el compromiso que desea dividir, lo que significa que HEAD ahora está en ese compromiso:

Queremos mover HEAD al padre, así que navegue hasta el padre (47e18b3) y presione x ( magit-reset-quickly , ligado a o si está usando evil-magit ) e ingrese para decir "sí, quise decir cometer en el punto ". Su registro ahora debería verse como:

Ahora, presione q para ir al estado Magit regular, luego use el comando unstage u regular para eliminar lo que no va en el primer commit, comience con el resto como de costumbre, luego s tage y c omita lo que pasa en el segundo commit , y cuando haya terminado: pulsa r para abrir la ventana emergente de rebase

y otra r para continuar, y listo! ahora muestra:


Para dividir una confirmación <commit> y agregar la nueva confirmación antes de esta , y guardar la fecha de autor de <commit> , los pasos son los siguientes:

  1. Edite el commit antes de <commit>

    git rebase -i <commit>^^

    NB: quizás también se necesite editar <commit> también.

  2. Cherry pick <commit> en el índice

    git cherry-pick -n <commit>

  3. Restablecer interactivamente los cambios innecesarios del índice y restablecer el árbol de trabajo

    git reset -p && git checkout-index -f -a

    Como alternativa, simplemente oculte los cambios innecesarios de forma interactiva: git stash push -p -m "tmp other changes"

  4. Haz otros cambios (si los hay) y crea el nuevo commit

    git commit -m "upd something" .

    Opcionalmente, repita los elementos 2-4 para agregar más confirmaciones intermedias.

  5. Continuar rebasando

    git rebase --continue


Si aún no has empujado, solo usa git rebase . Aún mejor, use git rebase -i para mover los compromisos de forma interactiva. Puede mover el compromiso ofensivo al frente, luego dividirlo como desee y mover los parches hacia atrás (si es necesario).