tipos - git ver archivos modificados
¿Cómo puedo combinar dos confirmaciones en una si ya empecé a reajustar? (11)
Rebase: No lo vas a necesitar:
Una forma más sencilla para el escenario más frecuente.
En la mayoría de los casos:
En realidad, todo lo que desea es simplemente fusionar varias confirmaciones recientes en una, pero no es necesario drop
, modificar y otras tareas de rebase.
simplemente puedes hacer
git reset --soft "HEAD~n"
- Suponiendo que
~n
es el número de confirmaciones para cancelar suavemente la confirmación (es decir,~1
,~2
, ...)
Luego, use el siguiente comando para modificar el mensaje de confirmación.
git commit --amend
que es bastante similar a una gran variedad de squash
y una pick
.
Y funciona para n confirmaciones pero no solo dos confirmaciones como se indica en la respuesta anterior.
Estoy tratando de unir 2 confirmaciones en 1, así que seguí "squashing commit with rebase" desde git ready .
corrí
git rebase --interactive HEAD~2
En el editor resultante, cambio pick
to squash
y luego save-quit, pero la rebase falla con el error
No se puede ''aplastar'' sin un compromiso previo
Ahora que mi árbol de trabajo ha alcanzado este estado, tengo problemas para recuperarme. El comando git rebase --interactive HEAD~2
falla con
Rebase interactivo ya iniciado
y git rebase --continue
falla con
No se puede ''aplastar'' sin un compromiso previo
Resumen
El mensaje de error
No se puede ''aplastar'' sin un compromiso previo
significa que es probable que haya intentado "aplastar hacia abajo". Git siempre aplasta un cometer más reciente en un cometer más antiguo o "hacia arriba" como se ve en la lista de tareas de rebase interactiva, que es un cometer en una línea anterior. Cambiar el comando en la primera línea de su lista de tareas pendientes para squash
siempre producirá este error ya que no hay nada en lo que la primera confirmación se aplasta.
La solución
Primero vuelve a donde empezaste
$ git rebase --abort
Di que tu historia es
$ git log --pretty=oneline
a931ac7c808e2471b22b5bd20f0cad046b1c5d0d c
b76d157d507e819d7511132bdb5a80dd421d854f b
df239176e1a2ffac927d8b496ea00d5488481db5 a
Es decir, a fue el primer commit, luego b, y finalmente c. Después de cometer c decidimos aplastar b y c juntos:
(Nota: la ejecución git log
canaliza su salida en un buscapersonas, less
de forma predeterminada en la mayoría de las plataformas. Para salir del buscapersonas y volver a la línea de comandos, presione la tecla q
).
Ejecutar git rebase --interactive HEAD~2
te da un editor con
pick b76d157 b
pick a931ac7 c
# Rebase df23917..a931ac7 onto df23917
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit''s log message
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
(Observe que esta lista de tareas pendientes está en orden inverso en comparación con la salida del git log
de git log
).
Cambiar la pick
de b para squash
resultará en el error que vio, pero si en cambio aplasta c en b (comillas más recientes en la más antigua o "aplastando hacia arriba") cambiando la lista de tareas a
pick b76d157 b
squash a931ac7 c
y si guarda su editor, obtendrá otro editor cuyos contenidos son
# This is a combination of 2 commits.
# The first commit''s message is:
b
# This is the 2nd commit message:
c
Cuando guarda y sale, el contenido del archivo editado se convierte en el mensaje de confirmación de la nueva confirmación combinada:
$ git log --pretty=oneline
18fd73d3ce748f2a58d1b566c03dd9dafe0b6b4f b and c
df239176e1a2ffac927d8b496ea00d5488481db5 a
Nota sobre la historia de reescritura
Rebase interactivo reescribe la historia. El intento de enviar a un control remoto que contiene el historial anterior fallará porque no es un avance rápido.
Si la rama que rebasó es una rama de tema o característica en la que está trabajando solo , no hay problema. Para ingresar a otro repositorio se requerirá la opción --force
, o, de forma alternativa, podrá, dependiendo de los permisos del repositorio remoto, eliminar primero la rama antigua y luego presionar la versión rebasada. Los ejemplos de los comandos que potencialmente destruirán el trabajo están fuera del alcance de esta respuesta.
La reescritura de la historia ya publicada en una rama en la que está trabajando con otras personas sin una buena razón, como filtrar una contraseña u otros detalles confidenciales, obliga a los colaboradores a trabajar, es antisocial y molestará a otros desarrolladores. La sección "Recuperación de una Rebase ascendente" en la documentación de git rebase
explica, con mayor énfasis.
Rehacer (o cualquier otra forma de reescritura) de una rama en la que otros han trabajado en el trabajo es una mala idea: cualquier persona que esté más abajo se vea obligada a corregir manualmente su historial. Esta sección explica cómo hacer la corrección desde el punto de vista del flujo descendente. La solución real, sin embargo, sería evitar volver a basar el flujo ascendente en primer lugar. ...
A menudo utilizo git reset - mezclado para revertir una versión base antes de las confirmaciones múltiples que desea fusionar, luego hago una nueva confirmación, de esta forma podría dejar su confirmación más reciente, asegurar que su versión sea HEAD después de ingresar al servidor.
commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date: Tue Jun 11 10:23:07 2013 +0500
Added algorithms for Cosine-similarity
commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date: Tue Jun 11 13:02:14 2013 -0700
Set stage for similar objects
commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date: Thu Jun 13 16:44:12 2013 -0700
Fixed a bug in space world automation
Si quiero unir dos head comets en uno, primero uso:
git reset --mixed 249cf9392da197573a17c8426c282
"249cf9392da197573a17c8426c282" fue la tercera versión, también es su versión base antes de fusionar, después de eso, hago un nuevo compromiso:
git add .
git commit -m ''some commit message''
Es todo, la esperanza es otra manera para todos.
Para tu información, desde git reset --help
:
--mixed
Resets the index but not the working tree (i.e., the changed files are
preserved but not marked for commit) and reports what has not been
updated. This is the default action.
Primero debes comprobar cuántos compromisos tienes:
git log
Hay dos estados:
Una es que solo hay dos confirmaciones:
Por ejemplo:
commit A
commit B
(En este caso, no puede usar git rebase para hacerlo) debe hacer lo siguiente.
$ git reset --soft HEAD^1
$ git commit --amend
Otra es que hay más de dos compromisos; quieres fusionar cometer C y D.
Por ejemplo:
commit A
commit B
commit C
commit D
(bajo esta condición, puedes usar git rebase)
git rebase -i B
Y que usar "squash" para hacer. El resto se adelgaza es muy fácil. Si todavía no lo sabes, lee http://zerodie.github.io/blog/2012/01/19/git-rebase-i/
Si desea combinar los dos compromisos más recientes y simplemente usar el mensaje de compromiso anterior, puede automatizar el proceso usando expect
.
Asumo:
- Estás usando vi como tu editor
- Tus compromisos son de una línea cada uno
He probado con git version 2.14.3 (Apple Git-98)
.
#!/usr/bin/env expect
spawn git rebase -i HEAD~2
# down, delete word, insert ''s'' (for squash), Escape, save and quit
send "jdwis /033:wq/r"
expect "# This is a"
# down 4, delete 3 lines, save and quit
send "4j3d/r:wq/r"
interact
Si hay múltiples confirmaciones, puedes usar git rebase -i
para aplastar dos confirmaciones en una.
Si solo hay dos confirmaciones que desea fusionar, y son las "dos más recientes", se pueden usar los siguientes comandos para combinar las dos confirmaciones en una:
git reset --soft "HEAD^"
git commit --amend
Si su rama principal git log
ve algo como lo siguiente:
commit ac72a4308ba70cc42aace47509a5e
Author: <[email protected]>
Date: Tue Jun 11 10:23:07 2013 +0500
Added algorithms for Cosine-similarity
commit 77df2a40e53136c7a2d58fd847372
Author: <[email protected]>
Date: Tue Jun 11 13:02:14 2013 -0700
Set stage for similar objects
commit 249cf9392da197573a17c8426c282
Author: Ralph <[email protected]>
Date: Thu Jun 13 16:44:12 2013 -0700
Fixed a bug in space world automation
y desea fusionar los dos compromisos superiores, simplemente siga los sencillos pasos:
- Primero para estar en el lado seguro de la caja la segunda última confirmación en una rama separada. Puedes nombrar la rama cualquier cosa.
git checkout 77df2a40e53136c7a2d58fd847372 -b merged-commits
- Ahora, simplemente elija sus cambios del último compromiso en esta nueva rama como:
git cherry-pick -n -x ac72a4308ba70cc42aace47509a5e
. (Resolver conflictos si surgen) - Así que ahora, sus cambios en el último compromiso están allí en su segundo último compromiso. Pero todavía tiene que confirmar, así que primero agregue los cambios que acaba de seleccionar y luego ejecute
git commit --amend
.
Eso es. Puede insertar esta versión combinada en la rama "fusionado-confirmados" si lo desea.
Además, ahora puede descartar las dos confirmaciones consecutivas en su rama maestra. Solo actualiza tu rama maestra como:
git checkout master
git reset --hard origin/master (CAUTION: This command will remove any local changes to your master branch)
git pull
Suponiendo que estuvieras en tu propia rama temática. Si desea combinar los últimos 2 compromisos en uno y parecer un héroe, bifurque el compromiso justo antes de realizar los últimos dos compromisos.
git checkout -b temp_branch HEAD^2
Luego squash cometer la otra rama en esta nueva rama:
git merge branch_with_two_commits --squash
Eso traerá los cambios pero no los comprometeremos. Así que simplemente cométalos y listo.
git commit -m "my message"
Ahora puede fusionar esta nueva rama de tema de nuevo en su rama principal.
Ya que uso git cherry-pick
para casi todo, para mí es natural hacerlo incluso aquí.
Teniendo en cuenta que he verificado branchX
y hay dos confirmaciones en la punta, de las cuales quiero crear una confirmación combinando su contenido, hago esto:
git checkout HEAD^ // Checkout the privious commit
git cherry-pick --no-commit branchX // Cherry pick the content of the second commit
git commit --amend // Create a new commit with their combined content
Si también quiero actualizar branchX
(y supongo que este es el branchX
de este método) también tengo que:
git checkout branchX
git reset --hard <the_new_commit>
puedes cancelar el rebase con
git rebase --abort
y cuando ejecutas el comando rebase interactivo otra vez el ''squash; commit debe estar debajo del pick commit en la lista
$ git rebase --abort
Ejecute este código en cualquier momento si desea deshacer el rebase de git
$ git rebase -i HEAD~2
Para volver a aplicar los dos últimos compromisos. El comando anterior abrirá un editor de código
- [ La última confirmación será en la parte inferior ]. Cambia el último commit a squash (s). Ya que el squash se fusionará con el commit anterior.
- Luego presione la tecla esc y escriba: wq para guardar y cerrar
Después: wq estarás en modo rebase activo
Nota : obtendrá otro editor si no hay mensajes de advertencia / error. Si hay un error o advertencia que otro editor no mostrará, puede abortar ejecutando $ git rebase --abort
si ve un error o advertencia, si no, simplemente continúe con corriendo $ git rebase --continue
Verás tu 2 mensajes de confirmación. Elija uno o escriba su propio mensaje de confirmación, guarde y salga [: wq]
Nota 2: es posible que deba forzar la inserción de los cambios en el repositorio remoto si ejecuta el comando rebase
$ git push -f
$ git push -f origin master