Deberías usar el índice. Después de hacer un reinicio mixto (" git reset HEAD ^"), agregue el primer conjunto de cambios en el índice, luego confírmelos. Luego comete el resto.
Puede usar " git add " para colocar todos los cambios realizados en un archivo en el índice. Si no desea organizar cada modificación realizada en un archivo, solo algunas, puede usar "git add -p".
Veamos un ejemplo. Supongamos que tengo un archivo llamado myfile, que contiene el siguiente texto:
something
something else
something again
Lo modifiqué en mi último commit para que ahora se vea así:
1
something
something else
something again
2
Ahora decido que quiero dividirlo en dos, y quiero que la inserción de la primera línea esté en la primera confirmación, y la inserción de la última línea en la segunda confirmación.
Primero vuelvo al padre de HEAD, pero quiero mantener las modificaciones en el sistema de archivos, así que uso "git reset" sin argumento (que hará un llamado reinicio "mixto"):
$ git reset HEAD^
myfile: locally modified
$ cat myfile
1
something
something else
something again
2
Ahora uso "git add -p" para agregar los cambios que quiero confirmar en el índice (= los pongo en escena). "git add -p" es una herramienta interactiva que le pregunta acerca de qué cambios al archivo debe agregar al índice.
$ git add -p myfile
diff --git a/myfile b/myfile
index 93db4cb..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,5 @@
+1
something
something else
something again
+2
Stage this hunk [y,n,a,d,/,s,e,?]? s # split this section into two!
Split into 2 hunks.
@@ -1,3 +1,4 @@
+1
something
something else
something again
Stage this hunk [y,n,a,d,/,j,J,g,e,?]? y # yes, I want to stage this
@@ -1,3 +2,4 @@
something
something else
something again
+2
Stage this hunk [y,n,a,d,/,K,g,e,?]? n # no, I don't want to stage this
Luego cometo este primer cambio:
$ git commit -m "Added first line"
[master cef3d4e] Added first line
1 files changed, 1 insertions(+), 0 deletions(-)
Ahora puedo confirmar todos los demás cambios (es decir, el número "2" puesto en la última línea):
$ git commit -am "Added last line"
[master 5e284e6] Added last line
1 files changed, 1 insertions(+), 0 deletions(-)
Revisemos el registro para ver qué confirmaciones tenemos:
$ git log -p -n2 | cat
Commit 5e284e652f5e05a47ad8883d9f59ed9817be59d8
Author: ...
Date: ...
Added last line
Diff --git a/myfile b/myfile
Index f9e1a67..2f113ce 100644
--- a/myfile
+++ b/myfile
@@ -2,3 +2,4 @@
something
something else
something again
+2
Commit cef3d4e0298dd5d279a911440bb72d39410e7898
Author: ...
Date: ...
Added first line
Diff --git a/myfile b/myfile
Index 93db4cb..f9e1a67 100644
--- a/myfile
+++ b/myfile
@@ -1,3 +1,4 @@
+1
something
something else
something again
git reset [--patch|-p] <commit>
que puede usar para evitar la molestia de tener que hacerlogit add -p
después de reiniciar. Estoy en lo cierto? Usando git 1.7.9.5.Metas:
splitme
) en dos.Plan:
splitme
.splitme
.Los pasos de rebase (1 y 7) se pueden omitir si
splitme
es el commit más reciente.Si quisiera que los archivos divididos se confirmaran primero, luego volvería a escribir -i nuevamente y cambiaría el orden
fuente
git reset HEAD^
era la pieza faltante del rompecabezas. Funciona bien con-p
también. ¡Gracias!-- $files
argumento agit reset
. Con las rutas pasadas,git reset
restaura esos archivos al estado de la confirmación referenciada pero no cambia ninguna confirmación. Si deja los caminos, entonces "pierde" el compromiso que desea modificar en el siguiente paso.git reset HEAD^ -- .
. Extremadamente sorprendente, este no es exactamente el comportamiento degit reset HEAD^
.Para cambiar la confirmación actual en dos confirmaciones, puede hacer algo como lo siguiente.
Ya sea:
Esto deshace la última confirmación pero deja todo en escena. A continuación, puede desestabilizar ciertos archivos:
Opcionalmente reajuste partes de esos archivos:
Haz un nuevo primer commit:
La etapa y cometer el resto de los cambios en una segunda confirmación:
O:
Deshacer y desestabilizar todos los cambios desde la última confirmación:
Etapa selectiva de la primera ronda de cambios:
Cometer:
Cometer el resto de los cambios:
(En cualquiera de los pasos, si deshizo una confirmación que agregó un archivo nuevo y desea agregarla a la segunda confirmación, tendrá que agregarla manualmente, ya que
commit -a
solo realiza cambios en los archivos ya rastreados).fuente
Ejecutar
git gui
, seleccione el botón de opción "Modificar la última confirmación" y desarme los cambios (Confirmar> Sin etapa de confirmación, o Ctrl- U) que no desea incluir en la primera confirmación. Creo que esa es la forma más fácil de hacerlo.Otra cosa que podría hacer es seleccionar el cambio sin comprometer (
git cherry-pick -n
) y luego manualmente o congit gui
seleccionar los cambios deseados antes de confirmar.fuente
lo duro es lo que está matando tus cambios.
fuente
Me sorprende que nadie sugirió
git cherry-pick -n forum
. Esto organizará los cambios desde la últimaforum
confirmación, pero no los confirmará; puedereset
eliminar los cambios que no necesita y confirmar lo que desea conservar.fuente
El método de doble reversión de squash
git checkout HEAD~1 -- files with unwanted changes
ygit commit
. Si no, los archivos con cambios mixtos pueden organizarse parcialmentegit reset file
ygit add -p file
como un paso intermedio). Llame a esto la reversión .git revert HEAD
- Realice otra confirmación, que agrega los cambios no deseados. Esta es la doble reversióngit rebase -i HEAD~3
). Esta confirmación ahora se libera de los cambios no deseados, ya que están en la segunda confirmación.Beneficios
fuente
Como estás recogiendo cerezas, puedes:
cherry-pick
con la--no-commit
opción agregada.reset
y usaradd --patch
,add --edit
o simplementeadd
para poner en escena lo que quieres conservar.commit
Los cambios escenificados.--reuse-message=<old-commit-ref>
u--reedit-message=<old-commit-ref>
opciones alcommit
comando.reset --hard
.Otra forma, preservar o editar el mensaje de confirmación original:
cherry-pick
El commit original como de costumbre.add
para organizar la inversión.commit --amend
para efectuar la reversión en el compromiso seleccionado.fuente
Esta podría ser otra solución destinada a casos en los que existe una gran confirmación y una pequeña cantidad de archivos debe trasladarse a una nueva confirmación. Esto funcionará si
<path>
se va a extraer un conjunto de archivos de la última confirmación en HEAD y todos se moverán a una nueva confirmación. Si se necesitan confirmaciones múltiples, se pueden usar las otras soluciones.Primero haga parches en las áreas preparadas y no preparadas que contendrían los cambios para revertir el código antes de la modificación y después de la modificación respectivamente:
Para entender lo que sucederá (la flecha y los comentarios no son parte del comando):
Revertir los
<path>
cambios en la última confirmación:Crear nueva confirmación con
<path>
cambios:Esto tiene el efecto de crear una nueva confirmación que contiene los cambios extraídos de la última confirmación.
fuente