Deseche los compromisos locales en Git

1469

Debido a una mala selección de cerezas, mi repositorio Git local está actualmente cinco confirmaciones por delante del origen, y no en un buen estado. Quiero deshacerme de todos estos commits y comenzar de nuevo.

Obviamente, eliminar mi directorio de trabajo y volver a clonar lo haría, pero descargar todo de GitHub nuevamente parece una exageración, y no es un buen uso de mi tiempo.

Tal vez git revertes lo que necesito, pero no quiero terminar 10 confirmaciones antes del origen (o incluso seis), incluso si el código vuelve al estado correcto. Solo quiero fingir que la última media hora nunca sucedió.

¿Hay un comando simple que haga esto? Parece un caso de uso obvio, pero no encuentro ningún ejemplo de ello.


Tenga en cuenta que esta pregunta es específicamente sobre confirmaciones , no sobre:

  • archivos sin seguimiento
  • cambios no organizados
  • etapas, pero cambios no comprometidos
David Moles
fuente
3
posible duplicado de varias formas de eliminar los cambios locales de Git
spiderman

Respuestas:

2470

Si su exceso de confirmaciones solo es visible para usted, puede hacerlo git reset --hard origin/<branch_name> para regresar a donde está el origen. Esto restablecerá el estado del repositorio a la confirmación anterior, y descartará todos los cambios locales.

Haciendo una git reverthace nuevas confirmaciones para eliminar viejos compromete de una manera que mantiene cuerdo de todos la historia.

Ben Jackson
fuente
9191
git reset --hard <commit hash, branch, or tag>si desea ir a una referencia específica que no sea una rama remota.
Sam Soffes
55
Para ser claros, si no estás trabajando en masterotra rama, deberías corrergit reset --hard origin/<your-branch-name>
Zoltán
33
Esto no solo descartará los commits locales, sino que también desechará todo en su árbol de trabajo (es decir, sus archivos locales). Si todo lo que quiere hacer es no comprometerse, pero deje su trabajo intacto, debe hacer "git reset HEAD ^" ... por stackoverflow.com/questions/2845731/…
aaronbauman
3
Es posible que desee hacer una recuperación después de esto. Esto solucionó el contador de número de confirmaciones de espera para ser empujado en SourceTree.
Stan
2
git reset --hard origin/<branch_name>También restablecerá la configuración del proyecto, así que cuídate de esto. Tengo un .cfgarchivo grande que se restableció a los valores predeterminados. Tuve que pasar horas en eso otra vez.
MAC
271

Simplemente elimine su rama maestra local y vuelva a crearla así:

git branch -D master
git checkout origin/master -b master
Ramon Zarazua B.
fuente
2
Esto funciona bien cuando retroceder sus cambios costaría demasiado tiempo, lo que me sucedió después de un par de rebases.
Aross
1
¡Útil para problemas de extracción / empuje de subárbol entre los miembros del equipo!
Jorge Orpinel
Esto es perfecto cuando desea restaurar una rama en lugar de solo maestro.
Vladimir Ralev
1
Esta no es una buena manera de eliminar una confirmación local única. Mejor usargit reset --hard origin/<branch_name>
Kirit Vaghela
1
Tal vez esa solución funcione, pero eso no significa que sea la adecuada.
Adly
202

Tratar:

git reset --hard <the sha1 hash>

para restablecer tu cabeza a donde quieras estar. Usa gitk para ver en qué compromiso quieres estar. También puedes restablecer dentro de gitk.

Anders Zommarin
fuente
55
Votó este b / c como información útil, pero la respuesta de Ben Jackson obtiene la marca de verificación para resolver exactamente lo que quería, de una manera que no me obligaba a buscar hashes de confirmación. :)
David Moles
2
Este es el momento en que su nueva sucursal nunca ha sido empujada a su origen todavía
Jan
126

Eliminar la confirmación más reciente:

git reset --hard HEAD~1

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

git reset --soft HEAD~1

James L.
fuente
55
Respuesta útil ¡Gracias! Usé git reset --soft origin / master
Tarun Kumar el
2
@TarunKumar ¡GRACIAS! Estoy utilizando la integración VS, y su solución fue la única forma en que pude eliminar un montón de confirmaciones de fusión que no quería en una sucursal que no tenía permiso para registrar.
DVK
Gracias, justo lo que estaba buscando, "git reset --soft HEAD ~ 1" hizo el trabajo ya que cometí involuntariamente y quería revertir pero tenía otros archivos que no quería destruir después de revertir.
edvard_munch
47

Si está utilizando la aplicación Atlassian SourceTree , puede usar la opción de reinicio en el menú contextual.

ingrese la descripción de la imagen aquí

murmurar
fuente
42

En su intento de rama:

git reset --hard origin/<branch_name>

Valide la reversión (al estado, sin compromisos locales), usando " git log" o " git status" por lo tanto.

parasitar
fuente
1
@Troyseph: todas las respuestas enumeradas anteriormente, intenté como es, y no solucioné el escenario. El enfoque genérico, que no se ilustra en ninguna de las respuestas anteriores, es lo que se ha intentado responder aquí.
parasrish 01 de
3
La respuesta aceptada es la misma que la suya, menos el nombre genérico de la sucursal, y en los comentarios @Zoltan dice explícitamenteJust to be clear, if you're not working on master but on another branch, you should run git reset --hard origin/<your-branch-name>
Troyseph
1
Esta es la mejor respuesta en mi opinión.
dwjohnston
21

git reset --hard @{u}* elimina todos los cambios locales en la rama actual, incluidas las confirmaciones. Me sorprende que nadie haya publicado esto aún, teniendo en cuenta que no tendrá que buscar qué compromiso volver o jugar con las ramas.

* Es decir, restablecer a la rama actual en @{upstream}—comúnmente origin/<branchname>, pero no siempre

Kevin Chen
fuente
1
Algunas conchas como el pescado interpretarán la "@", por lo que es posible que tenga que poner la '@ {u}' entre comillas, por ejemplo, `git reset --hard '@ {u}'. De todos modos, buen hallazgo!
trysis
Impresionante respuesta es increíble
Marko
1
¿Cómo imprime el valor de @ {u}?
Philip Rego
12

Para ver / obtener la identificación SHA-1 de la confirmación, también desea volver

gitk --all

Para volver a ese compromiso

git reset --hard sha1_id

!Nota. Todos los commits que se hicieron después de ese commit serán eliminados (y todas sus modificaciones al proyecto). Así que primero clone mejor el proyecto en otra rama o cópielo en otro directorio.

Nicholas
fuente
Esto es ideal para situaciones en las que el control remoto ya no está disponible, y uno simplemente necesita restablecer a alguna confirmación local. gitk es increíble, no lo sabía de antemano.
theRiley
Si ya está en gitk, simplemente puede hacer clic derecho en el compromiso y seleccionar "restablecer la rama XY aquí".
mkrieger1
Y las nuevas confirmaciones no se eliminarán de inmediato. Simplemente ya no hay una rama que los señale (recuerde, una rama no es más que un "marcador" para un commit en particular).
mkrieger1
9

Tuve una situación en la que quería eliminar una confirmación que no se envió, pero la confirmación fue antes que otra. Para hacerlo, he usado el siguiente comando

git rebase -i HEAD~2 -> rebase las dos últimas confirmaciones

Y usé 'soltar' para la firma de confirmación que quería eliminar.

Robert
fuente
9

Eliminar archivos no rastreados (cambios locales no confirmados)

git clean -df

Eliminar permanentemente todas las confirmaciones locales y obtener la última confirmación remota

git reset --hard origin/<branch_name>
Código elástico
fuente
8

Para las confirmaciones locales que no se envían, también puede usar git rebase -ipara eliminar o aplastar una confirmación.

Nikhil Katre
fuente
1
Sé que esta puede no ser la solución más corta, pero lo voté porque IMHO git rebase -ies una forma más genérica de resolver muchos problemas similares y puede ser útil en una variedad de situaciones.
Stefan Marinov
1
Use la droppalabra clave (en lugar de eliminar una línea) cuando elimine todas las confirmaciones para evitar que se cancele el rebase.
Michal Čizmazia
6

La solución simple será hacer coincidir la HEAD de la rama maestra local con la HEAD de la rama maestra de origen

git reset --hard origin/master

PD: origen / maestro: es un puntero remoto a la rama maestra. Puede reemplazar el maestro con cualquier nombre de sucursal

narwanimonish
fuente
4

Antes de responder agreguemos algunos antecedentes, explicando qué es esto HEAD. ya que algunas de las opciones a continuación resultarán en un cabezal separado

First of all what is HEAD?

HEADes simplemente una referencia a la confirmación actual (más reciente) en la rama actual.
Solo puede haber una sola HEADen un momento dado. (excluyendo git worktree)

El contenido de HEADse almacena dentro .git/HEADy contiene los 40 bytes SHA-1 de la confirmación actual.


detached HEAD

Si no está en la última confirmación, lo que significa que HEADapunta a una confirmación previa en la historia se llama detached HEAD.

ingrese la descripción de la imagen aquí

En la línea de comando, se verá así: SHA-1 en lugar del nombre de la rama ya HEADque no apunta a la punta de la rama actual

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

Algunas opciones sobre cómo recuperarse de un HEAD separado:


git checkout

git checkout <commit_id>
git checkout -b <new branch> <commit_id>
git checkout HEAD~X // x is the number of commits t go back

Esto verificará que la nueva rama apunte a la confirmación deseada.
Este comando pagará a un commit dado.
En este punto, puede crear una rama y comenzar a trabajar a partir de este punto.

# Checkout a given commit. 
# Doing so will result in a `detached HEAD` which mean that the `HEAD`
# is not pointing to the latest so you will need to checkout branch
# in order to be able to update the code.
git checkout <commit-id>

# create a new branch forked to the given commit
git checkout -b <branch name>

git reflog

Siempre puedes usar el reflogtambién.
git reflogmostrará cualquier cambio que haya actualizado HEADy revisando la entrada de reflog deseada establecerá el HEADrespaldo de este commit.

Cada vez que se modifique el HEAD habrá una nueva entrada en el reflog

git reflog
git checkout HEAD@{...}

Esto lo llevará de regreso a su compromiso deseado

ingrese la descripción de la imagen aquí


git reset --hard <commit_id>

"Mueva" su CABEZA de nuevo a la confirmación deseada.

# This will destroy any local modifications.
# Don't do it if you have uncommitted work you want to keep.
git reset --hard 0d1d7fc32

# Alternatively, if there's work to keep:
git stash
git reset --hard 0d1d7fc32
git stash pop
# This saves the modifications, then reapplies that patch after resetting.
# You could get merge conflicts if you've modified things which were
# changed since the commit you reset to.
  • Nota: ( desde Git 2.7 )
    también puedes usar el git rebase --no-autostash.

git revert <sha-1>

"Deshacer" el compromiso o rango de compromiso dado.
El comando reset "deshacerá" cualquier cambio realizado en el commit dado.
Se confirmará una nueva confirmación con el parche de deshacer, mientras que la confirmación original también permanecerá en el historial.

# add new commit with the undo of the original one.
# the <sha-1> can be any commit(s) or commit range
git revert <sha-1>

Este esquema ilustra qué comando hace qué.
Como puede ver allí reset && checkoutmodifique el HEAD.

ingrese la descripción de la imagen aquí

CodeWizard
fuente
3

Para aquellos interesados ​​en la solución de Visual Studio, aquí está el ejercicio:

  1. En la Team Explorerventana, conéctese al repositorio de destino.
  2. Luego Branches, desde , haga clic derecho en la rama de interés y seleccione View history.
  3. Haga clic derecho en una confirmación en la Historyventana y elija Reset -> Delete changes (--hard).

Eso descartará sus confirmaciones locales y restablecerá el estado de su repositorio a la confirmación seleccionada. Es decir, sus cambios después de retirar el repositorio se perderán.

Bozhidar Stoyneff
fuente
2

Si su rama está por delante de ' origin/XXX' por 5 commits.

Puedes emitir:

git reset --hard HEAD~5

Y debería eliminar los últimos 5 commits.

Ha Choo
fuente
0
git reset --hard <SHA-Code>

Esto será útil si ha cometido algunos errores en su copia local que desea asegurarse de que no se envíen a su sucursal remota por error.

El código SHA se puede obtener mirando la versión web de su panel de control de git para la última confirmación en la rama.

De esta manera, puede sincronizarse con la última confirmación en la rama.

Puede hacerlo git pulldespués de haber completado con éxito el restablecimiento completo para confirmar que no hay nada nuevo para sincronizar, es decir, puede ver el mensaje.

Su sucursal está actualizada con Origin/<Branch Name>

Sameer Ashraf
fuente
0

Si obtiene su repositorio local en un completo desastre, entonces una forma confiable de descartar los compromisos locales en Git es ...

  1. Use "git config --get remote.origin.url" para obtener la URL de origen remoto
  2. Cambie el nombre de la carpeta local de git a "my_broken_local_repo"
  3. Use "git clone <url_from_1>" para obtener una copia local fresca del repositorio remoto de git

En mi experiencia, Eclipse maneja el mundo que cambia a su alrededor bastante bien. Sin embargo, es posible que deba seleccionar proyectos afectados en Eclipse y limpiarlos para forzar a Eclipse a reconstruirlos. Supongo que otros IDEs también pueden necesitar una reconstrucción forzada.

Un beneficio adicional del procedimiento anterior es que descubrirá si su proyecto se basa en archivos locales que no se pusieron en git. Si encuentra que le faltan archivos, puede copiarlos desde "my_broken_local_repo" y agregarlos a git. Una vez que tenga confianza en que su nuevo repositorio local tiene todo lo que necesita, puede eliminar "my_broken_local_repo".

Adam Gawne-Cain
fuente
0

Si solo quiere deshacerse de las confirmaciones locales y mantener las modificaciones realizadas en los archivos, haga
git reset @ ~
Otras respuestas abordaron el restablecimiento completo

Ashish Banker
fuente