tipos - git ver archivos modificados
Divide una confirmación previa en múltiples confirmaciones (11)
Sin crear una rama y hacer un montón de trabajo funky en una nueva rama, ¿es posible dividir un solo compromiso en unos pocos compromisos diferentes después de que se haya asignado al repositorio local?
Ahora, en el último TortoiseGit en Windows, puedes hacerlo muy fácilmente.
Abra el cuadro de diálogo de rebase, configúrelo y realice los siguientes pasos.
- Haga clic derecho en la confirmación que desea dividir y seleccione "
Edit
" (entre selección, aplastar, eliminar ...). - Haga clic en "
Start
" para comenzar a rebasar. - Una vez que llegue a la confirmación de división, marque el botón "
Edit/Split
" y haga clic en "Amend
" directamente. Se abre el diálogo de confirmación.
- Anule la selección de los archivos que desea colocar en una confirmación por separado.
- Edite el mensaje de confirmación y luego haga clic en "
commit
". - Hasta que haya archivos para confirmar, el diálogo de confirmación se abrirá una y otra vez. Cuando no haya más archivos para confirmar, aún le preguntará si desea agregar una confirmación más.
Muy útil, gracias TortoiseGit!
Creo que la mejor manera de usar git rebase -i
. Creé un video para mostrar los pasos para dividir un compromiso: https://www.youtube.com/watch?v=3EzOz7e1ADI
Del manual de git-rebase (sección SPLITTING COMMITS)
En el modo interactivo, puede marcar las confirmaciones con la acción "editar". Sin embargo, esto no significa necesariamente que git rebase espera que el resultado de esta edición sea exactamente una confirmación. De hecho, puede deshacer la confirmación o puede agregar otras confirmaciones. Esto se puede usar para dividir un commit en dos:
Comience una rebase interactiva con
git rebase -i <commit>^
, donde<commit>
es el compromiso que desea dividir. De hecho, cualquier rango de compromiso funcionará, siempre que contenga ese compromiso.Marque la confirmación que desea dividir con la acción "editar".
Cuando se trata de editar ese commit, ejecuta
git reset HEAD^
. El efecto es que la CABEZA se rebobina en uno, y el índice sigue su ejemplo. Sin embargo, el árbol de trabajo se mantiene igual.Ahora agregue los cambios al índice que desea tener en la primera confirmación. Puedes usar
git add
(posiblemente de manera interactiva) ogit gui
(o ambos) para hacer eso.Confirme el índice actual con cualquier mensaje de confirmación que sea apropiado ahora.
Repita los dos últimos pasos hasta que su árbol de trabajo esté limpio.
Continuar la rebase con
git rebase --continue
.
Las respuestas anteriores han cubierto el uso de git rebase -i
para editar la confirmación que desea dividir, y la confirmación en partes.
Esto funciona bien cuando se dividen los archivos en diferentes confirmaciones, pero si desea separar los cambios en los archivos individuales, hay más que necesita saber.
Al llegar a la confirmación que desea dividir, utilizando rebase -i
y marcándola para edit
, tiene dos opciones.
Después de usar
git reset HEAD~
, recorra los parches individualmente usandogit add -p
para seleccionar los que desee en cada confirmaciónEdite la copia de trabajo para eliminar los cambios que no desea; cometer ese estado interino y luego retire el compromiso completo para la siguiente ronda.
La opción 2 es útil si está dividiendo un compromiso grande, ya que le permite verificar que las versiones provisionales se compilen y ejecuten correctamente como parte de la combinación. Esto procede de la siguiente manera.
Después de usar rebase -i
y edit
la confirmación, use
git reset --soft HEAD~
para deshacer la confirmación, pero deje los archivos confirmados en el índice. También puede hacer un reinicio mixto omitiendo --soft, dependiendo de qué tan cerca del resultado final será su confirmación inicial. La única diferencia es si comienzas con todos los cambios en escena o con todos sin ajustar.
Ahora entra y edita el código. Puede eliminar los cambios, eliminar los archivos agregados y hacer lo que quiera para construir la primera confirmación de la serie que está buscando. También puede compilarlo, ejecutarlo y confirmar que tiene un conjunto coherente de origen.
Una vez que estés contento, prepara / desactiva los archivos según sea necesario (me gusta usar git gui
para esto) y confirma los cambios a través de la interfaz de usuario o la línea de comandos
git commit
Ese es el primer compromiso hecho. Ahora desea restaurar su copia de trabajo al estado que tenía después de la confirmación que está dividiendo, para que pueda tomar más cambios para su próxima confirmación. Para encontrar el sha1 del commit que estás editando, usa el git status
. En las primeras líneas del estado, verá el comando rebase que se está ejecutando actualmente, en el que puede encontrar el sha1 de su confirmación original:
$ git status
interactive rebase in progress; onto be83b41
Last commands done (3 commands done):
pick 4847406 US135756: add debugging to the file download code
e 65dfb6a US135756: write data and download from remote
(see more in file .git/rebase-merge/done)
...
En este caso, la confirmación que estoy editando tiene sha1 65dfb6a
. Sabiendo eso, puedo verificar el contenido de ese compromiso sobre mi directorio de trabajo mediante la forma de git checkout
que toma tanto un compromiso como una ubicación de archivo. Aquí lo uso .
como la ubicación del archivo para reemplazar toda la copia de trabajo:
git checkout 65dfb6a .
¡No te pierdas el punto al final!
Esto verificará, y preparará, los archivos tal como estaban después de la confirmación que está editando, pero en relación con la confirmación anterior que realizó, por lo que cualquier cambio que ya haya confirmado no será parte de la confirmación.
Puede seguir adelante y cometerlo como está para finalizar la división, o volver a hacerlo, eliminando algunas partes del compromiso antes de realizar otro compromiso provisional.
Si desea reutilizar el mensaje de confirmación original para una o más confirmaciones, puede usarlo directamente desde los archivos de trabajo de la rebase:
git commit --file .git/rebase-merge/message
Finalmente, una vez que hayas cometido todos los cambios,
git rebase --continue
Continuará y completará la operación de rebase.
Lo más fácil de hacer sin una rebase interactiva es (probablemente) hacer una nueva rama comenzando en la confirmación antes de la que desea dividir, seleccionar-n la confirmación, reiniciar, ocultar, cometer el movimiento del archivo, volver a aplicar el alijo y confirme los cambios y luego fusione con la rama anterior o seleccione los compromisos que siguieron. (Luego cambie el nombre de la rama anterior al titular actual). (Probablemente sea mejor seguir el consejo de los MBO y hacer una rebase interactiva).
Puedes hacer rebase interactiva git rebase -i
. La página de manual tiene exactamente lo que quieres:
Si tienes esto:
A - B <- mybranch
Donde hayas cometido algún contenido en commit B:
/modules/a/file1
/modules/a/file2
/modules/b/file3
/modules/b/file4
Pero quieres dividir B en C - D, y obtener este resultado:
A - C - D <-mybranch
Puede dividir el contenido como este, por ejemplo (contenido de diferentes directorios en diferentes confirmaciones) ...
Restablecer la rama a la confirmación antes de la división:
git checkout mybranch
git reset --hard A
Crear primer commit (C):
git checkout B /modules/a
git add -u
git commit -m "content of /modules/a"
Crear segundo commit (D):
git checkout B /modules/b
git add -u
git commit -m "content of /modules/b"
Tenga en cuenta que también hay git reset --soft HEAD^
. Es similar a git reset
(que por defecto es --mixed
) pero retiene el contenido del índice. De modo que si ha agregado / eliminado archivos, ya los tiene en el índice.
Resulta ser muy útil en caso de compromisos gigantes.
Use git rebase --interactive
para editar ese compromiso anterior, ejecute git reset HEAD~
, y luego git add -p
para agregar algo, luego haga un compromiso, luego agregue algo más y realice otro compromiso, tantas veces como desee. Cuando haya terminado, ejecute git rebase --continue
, y tendrá todas las confirmaciones de división anteriores en su pila.
Importante : Tenga en cuenta que puede jugar y hacer todos los cambios que desee, y no tener que preocuparse por perder cambios antiguos, porque siempre puede ejecutar git reflog
para encontrar el punto en su proyecto que contenga los cambios que desea (llamemos a it a8c4ab
), y luego git reset a8c4ab
.
Aquí hay una serie de comandos para mostrar cómo funciona:
mkdir git-test; cd git-test; git init
ahora agrega un archivo A
vi A
añadir esta línea:
one
git commit -am one
a continuación, agregue esta línea a A:
two
git commit -am two
a continuación, agregue esta línea a A:
three
git commit -am three
ahora el archivo A se ve así:
one
two
three
y nuestro git log
es similar al siguiente (bueno, yo uso git log --pretty=oneline --pretty="%h %cn %cr ---- %s"
bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one
Digamos que queremos dividir el segundo commit, two
.
git rebase --interactive HEAD~2
Esto trae un mensaje que se ve así:
pick 2b613bc two
pick bfb8e46 three
Cambie la primera pick
a una e
para editar ese compromiso.
git reset HEAD~
git diff
nos muestra que simplemente eliminamos el compromiso que hicimos para el segundo compromiso:
diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two
Vamos a organizar ese cambio y agregar "y un tercero" a esa línea en el archivo A
git add .
Este suele ser el punto durante una rebase interactiva en la que ejecutaríamos git rebase --continue
, porque normalmente solo queremos volver en nuestra pila de confirmaciones para editar una confirmación anterior. Pero esta vez, queremos crear un nuevo commit. Así que vamos a ejecutar git commit -am ''two and a third''
. Ahora editamos el archivo A
y agregamos la línea two and two thirds
.
git add .
git commit -am ''two and two thirds''
git rebase --continue
Tenemos un conflicto con nuestro compromiso, three
, así que resolvámoslo:
Vamos a cambiar
one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three
a
one
two and a third
two and two thirds
three
git add .; git rebase --continue
Ahora nuestro git log -p
ve así:
commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 13:57:00 2013 -0700
three
diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
one
two and a third
two and two thirds
+three
commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 14:07:07 2013 -0700
two and two thirds
diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
one
two and a third
+two and two thirds
commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 14:06:40 2013 -0700
two and a third
diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two and a third
commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 13:56:40 2013 -0700
one
diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one
git rebase -i
haré.
Primero, comience con un directorio de trabajo limpio: el git status
debe mostrar modificaciones, eliminaciones o adiciones pendientes.
Para dividir su compromiso más reciente, primero:
$ git reset HEAD~
Ahora confíe las piezas individualmente de la manera habitual, produciendo tantas confirmaciones como necesite.
Si estaba más atrás en el árbol, entonces
$ git rebase -i HEAD~3
donde 3
es cuántos se devuelve.
Si estaba más atrás en el árbol de lo que desea contar, entonces
$ git rebase -i 123abcd~
donde 123abcd
es el SHA1 de la confirmación que desea dividir.
Cuando llegue a la pantalla de edición de rebase, encuentre la confirmación que desea separar. Al principio de esa línea, reemplace pick
con edit
( e
para abreviar). Guardar el búfer y salir. Rebase se detendrá justo después de la confirmación que desea editar. Entonces:
$ git reset HEAD~
Confíe las piezas individualmente de la manera habitual, produciendo tantas confirmaciones como necesite, luego
$ git rebase --continue
git rebase --interactive
se puede usar para dividir una confirmación en confirmaciones más pequeñas. Los documentos de Git en rebase tienen un tutorial conciso del proceso - Compromisos de división :
En el modo interactivo, puede marcar las confirmaciones con la acción "editar". Sin embargo, esto no significa necesariamente que
git rebase
espera que el resultado de esta edición sea exactamente una confirmación. De hecho, puede deshacer la confirmación o puede agregar otras confirmaciones. Esto se puede usar para dividir un commit en dos:
Comience una rebase interactiva con
git rebase -i <commit>^
, donde<commit>
es el compromiso que desea dividir. De hecho, cualquier rango de compromiso funcionará, siempre que contenga ese compromiso.Marque la confirmación que desea dividir con la acción "editar".
Cuando se trata de editar ese commit, ejecuta
git reset HEAD^
. El efecto es que la CABEZA se rebobina en uno, y el índice sigue su ejemplo. Sin embargo, el árbol de trabajo se mantiene igual.Ahora agregue los cambios al índice que desea tener en la primera confirmación. Puedes usar
git add
(posiblemente de manera interactiva) o git gui (o ambos) para hacer eso.Confirme el índice actual con cualquier mensaje de confirmación que sea apropiado ahora.
Repita los dos últimos pasos hasta que su árbol de trabajo esté limpio.
Continuar la rebase con
git rebase --continue
.Si no está absolutamente seguro de que las revisiones intermedias sean coherentes (compilan, pasan el testuite, etc.), debe usar
git stash
para esconder los cambios aún no confirmados después de cada confirmación, prueba y enmienda de la confirmación si se corrigen son necesarios.