Cambié mi historial y quiero hacer algunos cambios. El problema es que tengo un commit con dos cambios no relacionados, y este commit está rodeado por otros cambios en mi historial local (no push).
Quiero dividir este commit antes de sacarlo, pero la mayoría de las guías que estoy viendo tienen que ver con dividir su commit más reciente o cambios locales no confirmados. ¿Es factible hacer esto a un commit que está enterrado en la historia un poco, sin tener que "rehacer" mis commits desde entonces?
Respuestas:
Hay una guía para dividir commits en la página de manual de rebase . El resumen rápido es:
Realice un rebase interactivo que incluya el commit de destino (por ejemplo
git rebase -i <commit-to-split>^ branch
) y márquelo para editarlo.Cuando el rebase alcanza ese compromiso, úselo
git reset HEAD^
para restablecerlo antes del compromiso, pero mantenga su árbol de trabajo intacto.Agregue los cambios de forma incremental y comprométalos, haciendo tantos commits como desee.
add -p
puede ser útil agregar solo algunos de los cambios en un archivo determinado. Úselocommit -c ORIG_HEAD
si desea reutilizar el mensaje de confirmación original para una confirmación determinada.Si desea probar lo que está comprometiendo (¡buena idea!) Use
git stash
para ocultar la parte que no ha comprometido (ostash --keep-index
incluso antes de comprometerla), pruebe y luegogit stash pop
devuelva el resto al árbol de trabajo. Siga haciendo confirmaciones hasta que se confirmen todas las modificaciones, es decir, tenga un árbol de trabajo limpio.Ejecute
git rebase --continue
para continuar aplicando los commits después del commit ahora dividido.fuente
git rebase -i <sha1_of_the_commit_to_split>^ branch
. Ygit gui
es una buena herramienta para la tarea de división, que se puede usar para agregar diferentes partes de un archivo en diferentes confirmaciones.git add -p
, que puede hacer más de lo quegit gui
puede en este departamento (en particular, editar trozos, organizar todo a partir del trozo actual y buscar trozos por expresiones regulares).Aquí se explica cómo hacerlo con Magit .
Digamos que commit ed417ae es el que quieres cambiar; contiene dos cambios no relacionados y está enterrado bajo una o más confirmaciones. Presione
ll
para mostrar el registro y navegue hasta ed417ae:Luego
r
presione para abrir la ventana emergente rebasey
m
para modificar el compromiso en el punto.Observe cómo
@
hay ahora en la confirmación que desea dividir; eso significa que HEAD ahora está en esa confirmación:Queremos mover HEAD al padre, así que navegue al padre (47e18b3) y presione
x
(magit-reset-quickly
, vinculadoo
si está usandoevil-magit
) e ingrese para decir "sí, me refería a confirmar en el punto". Su registro ahora debería verse así:Ahora,
q
presione para ir al estado normal de Magit, luego use elu
comando regular de unstage para destrabar lo que no sucede en el primer commit, confirmec
el resto como de costumbre, luego tages
yc
omita lo que sucede en el segundo commit, y cuando haya terminado: golpeador
para abrir la ventana emergente de rebasey otro
r
para continuar, ¡y listo!ll
ahora muestra:fuente
Para dividir un commit
<commit>
y agregar el nuevo commit antes de este , y guardar la fecha del autor de<commit>
, - los pasos son los siguientes:Edite el commit antes
<commit>
NB: quizás también será necesario editar
<commit>
.Cherry pick
<commit>
en el índiceRestablezca interactivamente los cambios innecesarios del índice y restablezca el árbol de trabajo
Como alternativa, solo guarde los cambios innecesarios de forma interactiva:
git stash push -p -m "tmp other changes"
Realice otros cambios (si los hay) y cree la nueva confirmación
Opcionalmente, repita los elementos 2-4 para agregar más confirmaciones intermedias.
Continuar rebasando
fuente
Hay una versión más rápida si solo desea extraer contenido de un solo archivo. Es más rápido porque el rebase interactivo ya no es interactivo (y, por supuesto, es aún más rápido si desea extraer del último commit, entonces no hay necesidad de rebase en absoluto)
the_file
. Cerrarthe_file
. Esa es la única edición que necesitas, todo lo demás son solo comandos git.Etapa esa eliminación en el índice:
¡Restaure las líneas que acaba de eliminar en el archivo sin afectar el índice !
"SHA1" es la confirmación de la que desea extraer las líneas:
Cree el segundo compromiso nuevo con el contenido para extraer restaurado en el paso 3:
No edite, no pare / continúe, simplemente acepte todo:
Por supuesto, incluso más rápido cuando el commit para extraer es el último commit:
Si lo usa
magit
, los pasos 4, 5 y 6 son una sola acción: Confirmar, Reparación instantáneafuente
Si aún no has presionado, solo úsalo
git rebase
. Aún mejor, usegit rebase -i
para mover commits de forma interactiva. Puedes mover el commit ofensivo al frente, luego dividirlo como quieras y mover los parches hacia atrás (si es necesario).fuente