Sí, es realmente malo yada yada, pero por alguna razón necesito marcarlo como favorito.
James Morris
44
Sé que esto es estúpido, pero a veces sucede una mierda, como probar inicios de sesión y usar contraseñas de texto sin formato en su código, que son credenciales de inicio de sesión reales. Y whoops ...
frhd
66
credenciales de inicio de sesión reales ... Sí, me recuerda algunos whoopos
Estoy tan cansado de esta discusión académica sobre lo peligroso que es esto y cómo nunca debería hacerse yada yada. Hay momentos en los que es mucho, mucho mejor eliminar cosas del historial de git y lidiar con los conflictos / rupturas de otros desarrolladores. Es realmente así de simple. Las personas que ignoran esto probablemente nunca trabajaron fuera del aula.
aplastar
Respuestas:
369
Usted git reset --hardsu sucursal local para eliminar los cambios del árbol de trabajo y el índice, y git push --forcesu 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 rebasepágina del manual
Extraño. Parece que ya lo intenté. Junto con algunos rebases, funciona como un encanto. Gracias.
Arnis Lapsa
77
@Arnis: perfecto entonces;) push --forcelejos
VonC
Utilicé BFG Repo-Cleaner para deshacerme de algunos datos confidenciales, que me dejaron con una rama "sin nombre" con el archivo original en él, después de restablecer el último commit deseado y presionar duro para el origen, todo salió bien (:
Rodrirokr
Tenga en cuenta que la URL de la confirmación aún está activa (al menos durante un tiempo), por lo que si alguien tiene la URL de la confirmación (se la dio a Dios sabe por qué), podrá acceder al código.
Respuesta perfecta, elegante y simple. Acabo de volver a la última confirmación de stabe que necesitaba tanto en forma remota como local
lauWM
2
Esto también me hizo perder mis cambios locales. No esperaba eso. Pero meh, mejor que comprometer tu contraseña personal para el repositorio de trabajo.
Airwavezx
3
puede guardar sus cambios locales con git stash ... haga algunas cosas ... y git stash pop (sus cambios locales están de vuelta)
MonTea
Esto me da un error como "remoto: error: denegar referencias / cabezas / maestros que no avanzan rápidamente (debe tirar primero)"
Saurabhcdt
@Airwavezx eso es lo que git reset --hardse supone que debe hacer.
Lucas
146
Importante: ¡Asegúrese de especificar qué ramas en "git push -f" o podría modificar inadvertidamente otras ramas! [*]
Hay tres opciones que se muestran en este tutorial . En caso de que el enlace se rompa, dejaré los pasos principales aquí.
¡Asegúrese de especificar qué ramas en "git push <remote_repo> <remote_branch> -f" o podría modificar inadvertidamente otras ramas!
Nigel Sheridan-Smith
Solo los pasos 1 y 2 hicieron el trabajo y respondieron la pregunta original. (No
ejecutes el
Estas son opciones para diferentes escenarios, no pasos a seguir. En mi caso, el rebase interactivo (Opción 3) hizo lo que estaba buscando.
Steve Blackwell
Aunque tuve que hacer el paso 3. ¿Por qué no deberías ejecutar este @Saad? Afortunadamente, mi <<remote>> era simplemente el "origen" predeterminado y <remote_branch> el "maestro" predeterminado
Bart
30
Si desea eliminar, por ejemplo, las últimas 3confirmaciones, 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~Ncon <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 --softindicador 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 statusmuestra los archivos modificados desde entonces <desired-commit-id>. Si usa la --hardopción, git statusle indicará que su sucursal local es exactamente la misma que la remota. Si no usa --hardni --soft, se usa el modo predeterminado --mixed. En este modo, git help resetdice:
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-branchpuede eliminar archivos o cambiar algo en una gran cantidad de archivos a lo largo de todo su historial de git.
No es muy tarde Podría ser útil para los errantes con problemas similares :)
Arnis Lapsa
9
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
Funciona para mi, gracias. Y quiero eliminar permanentemente una confirmación (por ejemplo, contiene pwd) del historial de sucursal remota, ¿cómo hago esto?
Sonríe
1
También funciona para mí, pero tengo la misma pregunta que Smiles, no quiero que nadie vea mi commit / rever en la historia ... ¿cómo elimino eso?
Roberto Rodriguez
4
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
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.
Respuestas:
Usted
git reset --hard
su sucursal local para eliminar los cambios del árbol de trabajo y el índice, ygit 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 manualCon 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.fuente
push --force
lejosgit gc
no siempre se ejecuta con la suficiente frecuencia en el lado remoto. Por ejemplo en GitHub: twitter.com/githubhelp/status/387926738161774592?lang=esSolo tenga en cuenta usar el
last_working_commit_id
, al revertir una confirmación que no funcionaPor lo tanto, no debemos restablecer lo
commit_id
que no queremos.Entonces seguro, debemos empujar a la rama remota:
fuente
git reset --hard
se supone que debe hacer.Importante: ¡Asegúrese de especificar qué ramas en "git push -f" o podría modificar inadvertidamente otras ramas! [*]
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
2 Eliminar la última confirmación
o, si la sucursal está disponible localmente
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
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.
fuente
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:Luego ejecute el siguiente comando (en su máquina local) para forzar a la rama remota a reescribir su historial:
¡Felicidades! ¡Todo listo!
Algunas notas:
Puede recuperar la identificación de confirmación deseada ejecutando
A continuación, se puede reemplazar
HEAD~N
con<desired-commit-id>
este aspecto:Si desea mantener los cambios en el sistema de archivos y simplemente modificar el índice (historial de confirmación), use el
--soft
indicador comogit 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, runniggit 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:fuente
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í .
fuente
Simplificando de la respuesta de pctroll, similarmente basado en esta publicación de blog .
fuente
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:
copie el hash de confirmación en el que desea que esté la rama y salga del registro git
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:
Copie el hash de confirmación de la confirmación que necesita para ingresar en la rama buena y salir del registro git.
Date unas palmaditas en la espalda.
fuente
fuente