Pregunta ¿Cómo elimino las confirmaciones de git sin apresurar?


Accidentalmente me comprometí con la rama incorrecta. ¿Cómo borro esa confirmación?


593
2017-07-07 17:47


origen


Respuestas:


Elimine la confirmación más reciente, manteniendo el trabajo que ha realizado:

git reset --soft HEAD~1

Eliminar la confirmación más reciente destruyendo el trabajo has hecho:

git reset --hard HEAD~1

1121
2017-07-07 17:50



No lo elimine: solo por una confirmación git cherry-pick es suficiente.

Pero si tuvieras varios se compromete en la rama incorrecta, ahí es donde git rebase --onto brilla:

Supongamos que tienes esto:

 x--x--x--x <-- master
           \
            -y--y--m--m <- y branch, with commits which should have been on master

, entonces puedes marcar master y moverlo a donde quieras estar:

 git checkout master
 git branch tmp
 git checkout y
 git branch -f master

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- y branch, master branch

, restablecer la rama donde debería haber estado:

 git checkout y
 git reset --hard HEAD~2 # ~1 in your case, 
                         # or ~n, n = number of commits to cancel

 x--x--x--x <-- tmp
           \
            -y--y--m--m <- master branch
                ^
                |
                -- y branch

, y finalmente mueve tus commits (vuelve a aplicarlos, haciendo commits realmente nuevos)

 git rebase --onto tmp y master
 git branch -D tmp


 x--x--x--x--m'--m' <-- master
           \
            -y--y <- y branch

46
2017-07-07 17:58



Haz un git rebase -i FAR_ENOUGH_BACK y deje caer la línea para la confirmación que no desea.


10
2017-07-07 17:55



Si desea mover ese compromiso a otra sucursal, obtenga el SHA del compromiso en cuestión

git rev-parse HEAD

Luego cambie la rama actual

git checkout other-branch

Y cherry-pick el compromiso de other-branch

git cherry-pick <sha-of-the-commit>

6
2017-07-07 17:55



Para su referencia, creo que puede "comprometerse" con su rama actual no solo con el restablecimiento de git --hard, sino también con el siguiente comando:

git checkout -B <branch-name> <SHA>

De hecho, si no le importa retirar, puede configurar la rama a lo que desee con:

git branch -f <branch-name> <SHA>

Esta sería una forma programática de eliminar commits de una rama, por ejemplo, para copiar nuevas confirmaciones (usando rebase).

Supongamos que tiene una rama que está desconectada de la maestra porque ha tomado fuentes de otra ubicación y la ha descargado en la sucursal.

Ahora tiene una rama en la que ha aplicado cambios, vamos a llamarlo "tema".

Ahora creará un duplicado de su rama de tema y luego volverá a basarlo en el volcado de código fuente que está sentado en la rama "volcado":

git branch topic_duplicate topic
git rebase --onto dump master topic_duplicate

Ahora sus cambios se vuelven a aplicar en branch topic_duplicate en función del punto de inicio de "dump", pero solo los commits que han sucedido desde "master". Entonces sus cambios desde el maestro ahora se vuelven a aplicar en la parte superior de "volcado", pero el resultado termina en "topic_duplicate".

Luego puede reemplazar "dump" por "topic_duplicate" haciendo:

git branch -f dump topic_duplicate
git branch -D topic_duplicate

O con

git branch -M topic_duplicate dump

O simplemente descartando el vertedero

git branch -D dump

Tal vez también podría simplemente seleccionar cuidadosamente después de borrar el actual "topic_duplicate".

Lo que trato de decir es que si desea actualizar la rama "duplicada" actual basada en un antecesor diferente, primero debe eliminar las confirmaciones previamente "elegidas como cerezas" haciendo una git reset --hard <last-commit-to-retain> o git branch -f topic_duplicate <last-commit-to-retain> y luego copia los otros commits over (desde la rama principal del tema) ya sea por rebasing o cherry-picking.

Rebasing solo funciona en una rama que ya tiene commits, por lo que debe duplicar su rama de tema cada vez que quiera hacer eso.

Cherrypicking es mucho más fácil:

git cherry-pick master..topic

Entonces, toda la secuencia se reducirá a:

git reset --hard <latest-commit-to-keep>
git cherry-pick master..topic

Cuando su rama tema duplicado ha sido extraída. Eso eliminaría las confirmaciones seleccionadas previamente del duplicado actual, y simplemente volvería a aplicar todos los cambios que suceden en el "tema" en la parte superior de su "volcado" actual (ancestro diferente). Parece una forma razonablemente conveniente de basar su desarrollo en el maestro upstream "real" mientras utiliza un maestro "downstream" diferente para verificar si los cambios locales también se siguen aplicando a eso. Alternativamente, puedes generar un diff y luego aplicarlo fuera de cualquier árbol fuente de Git. Pero de esta manera puede mantener una versión modificada (parchada) actualizada que se basa en la versión de su distribución, mientras que su desarrollo real está en contra del maestro original en sentido ascendente.

Entonces solo para demostrar:

  • restablecer hará que su bifurcación apunte a una confirmación diferente (--hard también verificará la confirmación anterior, --soft conservará los archivos agregados en el índice (que se confirmaría si se confirma nuevamente) y el valor predeterminado (--mixed) no revisa la confirmación anterior (borrando tus cambios locales) pero borrará el índice (aún no se ha agregado nada para la confirmación)
  • puedes simplemente forzar a una rama para que apunte a un compromiso diferente
  • puedes hacerlo mientras revisas de inmediato que cometes también
  • rebase de trabajos en commits presentes en su rama actual
  • seleccionar cereza significa copiar desde una rama diferente

Espero que esto ayude a alguien. Quería reescribir esto, pero no puedo hacerlo ahora. Saludos.


2
2017-07-28 16:02



Si tiene una copia de seguridad de su código (incluido .git carpeta), elimine la carpeta .git de su última base de código. Copia de edad .git carpeta a la última base de código. Ejecutar git pull.

Nota: Utilice esta solución solo si se está quedando sin tiempo y se confunde mucho.


0
2018-06-07 12:25