Sé que eso es una reescritura de la historia que es mala yada yada.
Pero, ¿cómo eliminar permanentemente algunas confirmaciones de la rama remota?
Sé que eso es una reescritura de la historia que es mala yada yada.
Pero, ¿cómo eliminar permanentemente algunas confirmaciones de la rama remota?
Respuestas:
Usted git reset --hard
su sucursal local para eliminar los cambios del árbol de trabajo y el índice, y git push --force
su sucursal local revisada al remoto. ( otra solución aquí , que implica eliminar la rama remota y volver a presionarla)
Esta respuesta SO ilustra el peligro de tal comando, especialmente si las personas dependen del historial remoto para sus propios repositorios locales. Debe
estar preparado para señalar a las personas a la sección RECUPERACIÓN DE REEMBOLSO DE UPSTREAM de la git rebase
página del manual
Con Git 2.23 (agosto de 2019, nueve años después), usaría el nuevo comando git switch
.
Es decir:
(reemplazar por el número de confirmaciones para eliminar)git switch -C mybranch origin/mybranch~n
n
Eso restaurará el índice y el árbol de trabajo, como lo git reset --hard
haría.
push --force
lejos
git gc
no siempre se ejecuta con la suficiente frecuencia en el lado remoto. Por ejemplo en GitHub: twitter.com/githubhelp/status/387926738161774592?lang=es
Solo tenga en cuenta usar el last_working_commit_id
, al revertir una confirmación que no funciona
git reset --hard <last_working_commit_id>
Por lo tanto, no debemos restablecer lo commit_id
que no queremos.
Entonces seguro, debemos empujar a la rama remota:
git push --force
git reset --hard
se supone que debe hacer.
Hay tres opciones que se muestran en este tutorial . En caso de que el enlace se rompa, dejaré los pasos principales aquí.
1 Revertir la confirmación completa
git revert dd61ab23
2 Eliminar la última confirmación
git push <<remote>> +dd61ab23^:<<BRANCH_NAME_HERE>>
o, si la sucursal está disponible localmente
git reset HEAD^ --hard
git push <<remote>> -f
donde + dd61 ... es su commit hash y git interpreta x ^ como el padre de x, y + como un forzado forzado no acelerado.
3 Eliminar el commit de una lista
git rebase -i dd61ab23^
Esto abrirá y el editor mostrará una lista de todos los commits. Elimine el que desea eliminar. Termina el rebase y empuja la fuerza al repositorio.
git rebase --continue
git push <remote_repo> <remote_branch> -f
Si desea eliminar, por ejemplo, las últimas 3
confirmaciones, ejecute el siguiente comando para eliminar los cambios del sistema de archivos (árbol de trabajo) y el historial de confirmaciones (índice) en su rama local:
git reset --hard HEAD~3
Luego ejecute el siguiente comando (en su máquina local) para forzar a la rama remota a reescribir su historial:
git push --force
¡Felicidades! ¡Todo listo!
Algunas notas:
Puede recuperar la identificación de confirmación deseada ejecutando
git log
A continuación, se puede reemplazar HEAD~N
con <desired-commit-id>
este aspecto:
git reset --hard <desired-commit-id>
Si desea mantener los cambios en el sistema de archivos y simplemente modificar el índice (historial de confirmación), use el --soft
indicador como git reset --soft HEAD~3
. Luego tiene la oportunidad de verificar sus últimos cambios y conservarlos o soltarlos todos o parte de ellos. En el último caso, runnig git status
muestra los archivos modificados desde entonces <desired-commit-id>
. Si usa la --hard
opción, git status
le indicará que su sucursal local es exactamente la misma que la remota. Si no usa --hard
ni --soft
, se usa el modo predeterminado --mixed
. En este modo, git help reset
dice:
Restablece el índice pero no el árbol de trabajo (es decir, los archivos modificados se conservan pero no se marcan para confirmar) e informa lo que no se ha actualizado.
Esto podría ser demasiado poco y demasiado tarde, pero lo que me ayudó es la opción 'nuclear' que suena genial. Básicamente, utilizando el comando filter-branch
puede eliminar archivos o cambiar algo en una gran cantidad de archivos a lo largo de todo su historial de git.
Se explica mejor aquí .
Simplificando de la respuesta de pctroll, similarmente basado en esta publicación de blog .
# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote
A veces, la forma más fácil de solucionar este problema es crear una nueva sucursal desde el lugar donde sabe que el código es bueno. Luego puede dejar solo el historial de la rama errante en caso de que necesite seleccionar otras confirmaciones de él más adelante. Esto también asegura que no perdió ningún historial de confirmación.
Desde su sucursal local errante:
git log
copie el hash de confirmación en el que desea que esté la rama y salga del registro git
git checkout theHashYouJustCopied
git checkout -b your_new_awesome_branch
Ahora tiene una nueva sucursal tal como la desea.
Si también necesita mantener una confirmación específica de la rama errante que no está en su nueva rama, puede elegir la confirmación específica que necesita:
git checkout the_errant_branch
git log
Copie el hash de confirmación de la confirmación que necesita para ingresar en la rama buena y salir del registro git.
git checkout your_new_awesome_branch
git cherry-pick theHashYouJustCopied
Date unas palmaditas en la espalda.