Varias formas de eliminar los cambios locales de Git

625

Acabo de clonar un repositorio de git y revisé una rama. Trabajé en él y luego decidí eliminar todos mis cambios locales, ya que quería la copia original.

En resumen, tuve que hacer los siguientes dos comandos para eliminar mis cambios locales

git checkout .

git clean -f

Mi pregunta es,

(1) ¿Es este el enfoque correcto para deshacerse de los cambios locales, o bien hágamelo saber el enfoque correcto?

(2) ¿cuándo utilizamos git reset --hardya que puedo restablecer incluso sin este comando?

Gracias

* Solución: Edición principal (es): 26/03: * Reemplazó muchos de los términos vagos con terminología específica de git [rastreado / no rastreado / escenificado / no escalonado]

Podría haber solo tres categorías de archivos cuando hacemos cambios locales:

Tipo 1. Archivos rastreados por etapas

Tipo 2. Archivos rastreados sin clasificar

Tipo 3. Archivos sin seguimiento sin clasificar, también conocidos como archivos sin seguimiento

  • Escenario: aquellos que se mueven al área de ensayo / Agregados al índice
  • Rastreado - archivos modificados
  • Sin seguimiento: nuevos archivos. Siempre sin escena. Si se escenifica, eso significa que son rastreados.

Lo que cada comando hace:

  1. git checkout . - Elimina SOLAMENTE archivos rastreados sin clasificar [Tipo 2]

  2. git clean -f - Elimina SOLAMENTE archivos sin seguimiento sin clasificar [Tipo 3]

  3. git reset --hard - Elimina SOLAMENTE archivos rastreados y no rastreados [Tipo 1, Tipo 2]

  4. git stash -u - Elimina todos los cambios [Tipo 1, Tipo 2, Tipo 3]

Conclusión:

Está claro que podemos usar cualquiera

(1) combination of `git clean -f` and `git reset --hard` 

O

(2) `git stash -u`

para lograr el resultado deseado.

Nota: Escondite, ya que la palabra significa 'Almacenar (algo) de forma segura y secreta en un lugar específico'. Esto siempre se puede recuperar usando git stash pop. Por lo tanto, elegir entre las dos opciones anteriores es una decisión del desarrollador.

Gracias Christoph y Frederik Schøning.

Editar: 27/03

Pensé que valía la pena poner la nota de " cuidado "git clean -f

git clean -f

No hay vuelta atrás. Usa -no --dry-runpara previsualizar el daño que harás.

Si también desea eliminar directorios, ejecute git clean -f -d

Si solo desea eliminar los archivos ignorados, ejecute git clean -f -X

Si desea eliminar archivos ignorados y no ignorados, ejecute git clean -f -x

referencia: más sobre git clean: ¿Cómo eliminar archivos locales (sin seguimiento) del árbol de trabajo Git actual?

Editar: 20/05/15

Descartando todas las confirmaciones locales en esta rama [Eliminando confirmaciones locales]

Para descartar todas las confirmaciones locales en esta rama, para hacer que la rama local sea idéntica al "flujo ascendente" de esta rama, simplemente ejecute git reset --hard @{u}

Referencia: http://sethrobertson.github.io/GitFixUm/fixup.html

o hacer git reset --hard origin/master[si la sucursal local es master]

Nota: 12/06/2015 Esto no es un duplicado de la otra pregunta SO marcada como duplicada. Esta pregunta aborda cómo eliminar los cambios GIT locales [eliminar un archivo agregado, eliminar cambios agregados al archivo existente, etc. y los diversos enfoques; Donde en el otro subproceso SO solo se aborda cómo eliminar la confirmación local. Si agregó un archivo, y desea eliminarlo solo, entonces el otro hilo SO no discute al respecto. Por lo tanto, este no es un duplicado del otro]

Editar: 23/06/15

¿Cómo revertir un commit ya enviado a un repositorio remoto?

$ git revert ab12cd15

Edición: 01/09/2015

Eliminar una confirmación previa de la sucursal local y la sucursal remota

Caso: Usted acaba de realizar un cambio en su sucursal local e inmediatamente empujó a la sucursal remota, De repente se dio cuenta, ¡Oh no! No necesito este cambio. Ahora haz qué?

git reset --hard HEAD~1 [por eliminar esa confirmación de la sucursal local]

git push origin HEAD --force[ambos comandos deben ser ejecutados. Para eliminar de la rama remota]

¿Cuál es la rama? Es la rama actualmente desprotegida.

Editar 08/09/2015 - Eliminar local git merge :

Estoy en una masterrama y una rama fusionada mastercon una nueva rama de trabajophase2

$ git status
# On branch master

$ git merge phase2

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 8 commits.

P: ¿Cómo deshacerse de esta fusión? Intenté git reset --hard y git clean -d -f Ambos no funcionaron.

Lo único que funcionó fue cualquiera de los siguientes:

$ git reset --hard origin/master

o

$ git reset --hard HEAD~8

o

$ git reset --hard 9a88396f51e2a068bb7 [código de confirmación sha: este es el que estaba presente antes de que ocurrieran todas las confirmaciones de fusión]

hombre araña
fuente
1
Supongo que este hilo podría responder a sus preguntas: stackoverflow.com/questions/1146973/…
Saucier
1
"git stash" eliminará cualquier cambio que haya realizado.
John Ballinger
1
Bonito resumen! Agregaría otra categoría de archivo: "Tipo 4. Archivos ignorados". git stash -a[o --all] también esconderá los archivos ignorados y no rastreados. git clean -xlimpiará los archivos ignorados también. git clean -Xlimpiará solo los archivos ignorados.
Jerry101
2
@JavaDev Su pregunta fue más como una respuesta ... aprecio que haya seguido editando y compiló todas las respuestas.
Bhavuk Mathur
1
gracias, ejecuté los 4 comandos para revertir los cambios locales
Vincent Tang

Respuestas:

505

Todo depende de exactamente lo que está intentando deshacer / revertir. Comience leyendo la publicación en el enlace de Ube . Pero para intentar una respuesta:

Restablecimiento completo

git reset --hard [HEAD]

elimine por completo todos los cambios organizados y no almacenados en los archivos rastreados.

A menudo me encuentro usando el restablecimiento completo, cuando estoy como "simplemente deshago todo como si hubiera hecho una re-clonación completa desde el control remoto". En su caso, donde solo quiere su repositorio prístino, esto funcionaría.

Limpiar

git clean [-f]

Eliminar archivos que no se rastrean.

Para eliminar archivos temporales, pero mantenga los cambios organizados y sin clasificar en archivos ya rastreados. La mayoría de las veces, probablemente terminaría haciendo una regla de ignorar en lugar de limpiar repetidamente, por ejemplo, para las carpetas bin / obj en un proyecto de C #, que generalmente querría excluir de su repositorio para ahorrar espacio, o algo así.

La opción -f (force) también eliminará archivos, que no se rastrean y que git también ignora aunque ignore-rule. En el caso anterior, con una regla de ignorar para nunca rastrear las carpetas bin / obj, a pesar de que git ignora estas carpetas, el uso de la opción force las eliminará de su sistema de archivos. He visto un uso esporádico para esto, por ejemplo, al implementar scripts, y desea limpiar su código antes de implementar, comprimir o lo que sea.

Git clean no tocará los archivos que ya están siendo rastreados.

Pago "punto"

git checkout .

En realidad nunca había visto esta notación antes de leer tu publicación. Me resulta difícil encontrar documentación para esto (tal vez alguien pueda ayudarme), pero al jugar un poco, parece que significa:

"deshacer todos los cambios en mi árbol de trabajo".

Es decir, deshacer los cambios no organizados en los archivos rastreados. Aparentemente no toca los cambios por etapas y deja solo los archivos sin seguimiento.

Escondite

Algunas respuestas mencionan escondite. Como lo indica la redacción, probablemente usaría el escondite cuando esté en medio de algo (no está listo para una confirmación), y tendrá que cambiar temporalmente las ramas o de alguna manera trabajar en otro estado de su código, más tarde para volver a su "desorden" escritorio". No veo que esto se aplique a su pregunta, pero definitivamente es útil.

Para resumir

En general, si está seguro de haberse comprometido y tal vez haya presionado a cambios importantes remotos, si solo está jugando o algo similar, el uso git reset --hard HEADseguido de git clean -flimpiará definitivamente su código al estado, estaría en, si hubiera sido clonado y desprotegido de una sucursal. Es realmente importante enfatizar que el restablecimiento también eliminará los cambios por etapas, pero no confirmados. Borrará todo lo que no se haya confirmado (excepto los archivos no rastreados, en cuyo caso, use clean ).

Todos los otros comandos están ahí para facilitar escenarios más complejos, donde se necesita una granularidad de "deshacer cosas" :)

Creo que su pregunta n. ° 1 está cubierta, pero finalmente, para concluir en el n. ° 2: la razón por la que nunca encontró la necesidad de usar git reset --hardfue porque nunca había organizado nada. Si hubieras realizado un cambio, git checkout .ni git clean -flo hubieras revertido.

Espero que esto cubra.

Frederik Struck-Schøning
fuente
Gracias por la razón detrás del uso git reset --hard. Lo probé, y sí ... esos archivos agregados al índice (puesta en escena) se eliminaron solo después git reset --hard, y supongo que por defecto git reset --hardes git reset --hard head. Este enlace también fue útil gitready.com/beginner/2009/01/18/the-staging-area.html
spiderman
Mejoré mi respuesta por qué creo que git stash -utiene más sentido aquí.
Christoph
2
Gracias a los dos. He resumido la respuesta e incrustado en mi pregunta. Christoph me hizo saber qué git stash -uhace y cómo reventarlo, pero Frederik me hizo saber restablecer completamente y usar la combinación de git reset --hardy git clean -f, y por qué no, stashse prefiere en algunos escenarios. Ahora, por favor, ayúdame a elegir cuál debo marcar como Respuesta :), ambas son mis respuestas.
Spiderman
3
.es una especificación de ruta que se refiere al directorio de trabajo actual, que podría ser la raíz del repositorio. Desde git-scm.com: git checkout [<tree-ish>] [--] <pathspec>…actualiza las rutas nombradas en el árbol de trabajo desde el archivo de índice o desde un <tree-ish> nombrado.
Jerry101
3
Nunca se hace suficiente hincapié en que ambos git reset --hardy git clean -dfxsimilares son destructivos . De todos modos, corrija la letra minúscula headen la respuesta, debe estar en mayúscula HEADo no estar presente en absoluto.
Pavel Šimerda 01 de
25

Motivo para agregar una respuesta en este momento:

Hasta ahora estaba agregando la conclusión y las 'respuestas' a mi pregunta inicial en sí, haciendo que la pregunta fuera muy larga y, por lo tanto, pasé a una respuesta separada.

También he agregado los comandos git más utilizados que me ayudan en git, para ayudar a alguien más también.

Básicamente para limpiar todos los compromisos locales $ git reset --hardy $ git clean -d -f


El primer paso antes de realizar cualquier confirmación es configurar su nombre de usuario y correo electrónico que aparece junto con su confirmación.

# Establece el nombre que desea adjuntar a sus transacciones de confirmación

$ git config --global user.name "[name]"

# Configura el correo electrónico que desea adjuntar a sus transacciones de confirmación

$ git config --global user.email "[email address]"

# Listar la configuración global

$ git config --list

# Listar la URL remota

$ git remote show origin

#comprobar estado

git status

# Enumere todas las sucursales locales y remotas

git branch -a

#crear una nueva sucursal local y comenzar a trabajar en esta sucursal

git checkout -b "branchname" 

o, se puede hacer como un proceso de dos pasos

crear rama: git branch branchname trabajar en esta rama:git checkout branchname

#commitir cambios locales [proceso de dos pasos: - Agregue el archivo al índice, eso significa agregar al área de preparación. Luego confirme los archivos que están presentes en esta área de preparación]

git add <path to file>

git commit -m "commit message"

#checkout alguna otra sucursal local

git checkout "local branch name"

#remover todos los cambios en la sucursal local [Suponga que realizó algunos cambios en la sucursal local, como agregar un archivo nuevo o modificar un archivo existente, o realizar una confirmación local, pero ya no lo necesita] git clean -d -fy git reset --hard [limpiar todos los cambios locales realizados en la sucursal local, excepto si compromiso local]

git stash -u también elimina todos los cambios

Nota: Está claro que podemos usar (1) combinación de git clean –d –fy git reset --hard OR (2) git stash -u para lograr el resultado deseado.

Nota 1: Almacenamiento, ya que la palabra significa 'Almacenar (algo) de forma segura y secreta en un lugar específico'. Esto siempre se puede recuperar utilizando git stash pop. Por lo tanto, elegir entre las dos opciones anteriores es una decisión del desarrollador.

Nota 2: git reset --hardeliminará los cambios en el directorio de trabajo. Asegúrese de guardar los cambios locales que desee conservar antes de ejecutar este comando.

# Cambie a la rama maestra y asegúrese de estar actualizado.

git checkout master

git fetch [esto puede ser necesario (dependiendo de su configuración de git) para recibir actualizaciones sobre origen / maestro]

git pull

# Combinar la rama de la función en la rama maestra.

git merge feature_branch

# Restablece la rama maestra al estado de origen.

git reset origin/master

# Eliminó accidentalmente un archivo local, ¿cómo recuperarlo? Haga una git statuspara obtener la ruta de archivo completa del recurso eliminado

git checkout branchname <file path name>

¡Eso es!

# Combinar rama maestra con otra rama

git checkout master
git merge someotherbranchname

#rename sucursal local

git branch -m old-branch-name new-branch-name

# eliminar sucursal local

git branch -D branch-name

#delete sucursal remota

git push origin --delete branchname

o

git push origin :branch-name

#revertir un commit ya enviado a un repositorio remoto

git revert hgytyz4567

# ramificación de un commit anterior usando GIT

git branch branchname <sha1-of-commit>

# Mensaje de confirmación de cambio de la confirmación más reciente que ya se ha enviado a control remoto

git commit --amend -m "new commit message"
git push --force origin <branch-name>

# Descartando todas las confirmaciones locales en esta rama [Eliminando confirmaciones locales]

Para descartar todas las confirmaciones locales en esta rama, para hacer que la rama local sea idéntica al "flujo ascendente" de esta rama, simplemente ejecute

git reset --hard @{u}

Referencia: http://sethrobertson.github.io/GitFixUm/fixup.html o do git reset --hard origin/master[si la sucursal local es maestra]

# ¿Revertir un commit ya enviado a un repositorio remoto?

$ git revert ab12cd15

# Eliminar una confirmación anterior de la sucursal local y la sucursal remota

Caso de uso: Usted acaba de realizar un cambio en su sucursal local e inmediatamente empujó a la sucursal remota, De repente se dio cuenta, ¡Oh, no! No necesito este cambio. Ahora haz qué?

git reset --hard HEAD~1[por eliminar ese commit de la sucursal local. 1 denota el compromiso UNO que hiciste]

git push origin HEAD --force[ambos comandos deben ser ejecutados. Para eliminar de la rama remota]. La rama actualmente desprotegida se denominará la rama donde está realizando esta operación.

# Elimine algunas de las confirmaciones recientes del repositorio local y remoto y conserve la confirmación que desee. (una especie de revertir confirmaciones de local y remota)

Supongamos que tiene 3 confirmaciones que ha enviado a la rama remota llamada ' develop'

commitid-1 done at 9am
commitid-2 done at 10am
commitid-3 done at 11am. // latest commit. HEAD is current here.

Para volver a la confirmación anterior (para cambiar el estado de la rama)

git log --oneline --decorate --graph // para ver todos tus commitids

git clean -d -f // limpia cualquier cambio local

git reset --hard commitid-1 // volviendo localmente a este commitid

git push -u origin +develop// empuja este estado a remoto. + para forzar el empuje

# Eliminar la fusión local de git: Caso: estoy en la rama maestra y la rama maestra fusionada con una rama de trabajo nueva fase2

$ git status

En el maestro de sucursal

$ git merge phase2 $ git status

En el maestro de sucursal

Su rama está por delante de 'origen / maestro' por 8 confirmaciones.

P: ¿Cómo deshacerse de esta fusión local de git? Intenté git reset --hardy git clean -d -fAmbos no funcionaron. Lo único que funcionó fue cualquiera de los siguientes:

$ git reset - origen duro / maestro

o

$ git reset --HAD HEAD ~ 8

o

$ git reset --hard 9a88396f51e2a068bb7 [código de confirmación sha: este es el que estaba presente antes de que ocurrieran todas las confirmaciones de fusión]

#create el archivo gitignore

touch .gitignore // crea el archivo en usuarios de mac o unix

muestra de contenidos .gitignore:

.project
*.py
.settings

Enlace de referencia a la hoja de trucos de GIT: https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf

hombre araña
fuente
1
Su comando para eliminar la rama remota podría no ser el mejor . Estás usando, git push origin :branch-namesin embargo, recomiendo usargit push origin --delete branchname
vibs2006
De acuerdo, actualicé con tu sugerencia, gracias @ vibs2006
spiderman
21

Como con todo en git, hay múltiples formas de hacerlo. Los dos comandos que usó son una forma de hacerlo. Otra cosa que podrías haber hecho es simplemente esconderlos git stash -u. Esto -uasegura que también se incluyan los archivos recién agregados (sin seguimiento).

Lo práctico git stash -ues que

  1. es probablemente el comando simple más simple (¿solo?) para lograr su objetivo
  2. si cambia de opinión después, recupera todo su trabajo git stash pop(es como eliminar un correo electrónico en gmail donde puede deshacerlo si cambia de opinión después)

A partir de su otra pregunta git reset --hardno eliminará los archivos sin seguimiento por lo que sería todavía necesita el git clean -f. Pero a git stash -upodría ser lo más conveniente.

Christoph
fuente
git reset --hardno eliminará sin seguimiento archivos de hecho, sino que se retire cambios sin seguimiento, es decir, cambios en los archivos que ya están en el índice. Estoy seguro de que eso es lo que
querías
Cuando lo usé git stash -u, vi esta respuesta de git bash. "Directorio de trabajo guardado y estado de índice WIP en {branchname}. Puede que este guardado sea lo que podríamos recuperar usando git stash pop.
spiderman
Gracias a los dos. He resumido la respuesta e incrustado en mi pregunta. Christoph me hizo saber qué git stash -uhace y cómo reventarlo, pero Frederik me hizo saber cómo reiniciar y usar la combinación de git reset --hardy git clean -f, y por qué no, stashse prefiere en algunos escenarios. Ahora, por favor, ayúdame a elegir cuál debo marcar como Respuesta :), ambas son mis respuestas.
Spiderman
pero ¿qué pasa si hay un archivo que agregué a mi repositorio que no quiero rastrear? solo en mi repositorio. Si lo agrego a la lista de ignorados, entonces tengo un archivo .ignore para confirmar que afectará a todos los demás también.
user20358
7

1. Cuando no desea mantener sus cambios locales en absoluto.

git reset --hard

Este comando eliminará por completo todos los cambios locales de su repositorio local. Esta es la mejor manera de evitar conflictos durante el comando de extracción, solo si no desea conservar los cambios locales.

2. Cuando quieres mantener tus cambios locales

Si desea extraer los nuevos cambios desde el control remoto y desea ignorar los cambios locales durante esta extracción, entonces,

git stash

Guardará todos los cambios locales, ahora puede extraer los cambios remotos,

git pull

Ahora, puede recuperar sus cambios locales,

git stash pop
Actung
fuente
1
git reset --hardno elimina todos los cambios locales. Solo elimina las modificaciones. Si desea eliminar las adiciones, también debe hacerlogit clean -fd
John Henckel
4

Utilizar:

git checkout -- <file>

Para descartar los cambios en el directorio de trabajo.

Tadas Stasiulionis
fuente
4

Creo que git tiene una cosa que no está claramente documentada. Creo que en realidad fue descuidado.

git checkout .

Hombre, me salvaste el día. Siempre tengo cosas que quiero probar usando el código modificado. Pero las cosas a veces terminan arruinando el código modificado, agregando nuevos archivos no rastreados, etc. Entonces, lo que quiero hacer es organizar lo que quiero, hacer las cosas desordenadas, luego limpiar rápidamente y comprometerme si estoy feliz.

Hay git clean -fd funciona bien para los archivos sin seguimiento.

Luego, git resetsimplemente elimina la puesta en escena, pero git checkoutes demasiado engorrosa. Especificar el archivo uno por uno o usar directorios no siempre es ideal. A veces, los archivos modificados de los que quiero deshacerme están dentro de los directorios que quiero conservar. Deseaba este comando que solo elimina los cambios no organizados y aquí está. Gracias.

Pero creo que deberían tener git checkoutsin ninguna opción, eliminar todos los cambios no organizados y no tocar el escenario. Es un poco modular e intuitivo. Más como lo que git resethace. git cleanTambién debería hacer lo mismo.

Emmanuel Mahuni
fuente
2

La mejor manera es revisar los cambios.

Cambiando el archivo pom.xml en un proyecto llamado nombre-proyecto puede hacerlo:

git status

# modified:   project-name/pom.xml

git checkout project-name/pom.xml
git checkout master

# Checking out files: 100% (491/491), done.
# Branch master set up to track remote branch master from origin.
# Switched to a new branch 'master'
bpedroso
fuente
2

Para descartar todo lo que me gusta esconder y soltar ese alijo, es la forma más rápida de descartar todo, especialmente si trabaja entre múltiples repositorios.

Esto ocultará todos los cambios en la {0}clave y la soltará instantáneamente{0}

git stash && git stash drop

Tatarin
fuente
1

En primer lugar, verifique si su cambio importante se guarda o no mediante:

$ git status

que intentar

$ git reset --hard

restablecerá su rama a la predeterminada

pero si solo necesitas deshacer:

$ edit (1) $ git add frotz.c filfre.c $ mailx (2) $ git reset
(3) $ git pull git: //info.example.com/ nitfol


Leer más >> https://git-scm.com/docs/git-reset

Rizo
fuente
Nota al margen: reset --hard es un comando peligroso que eliminará todos los cambios y no se puede deshacer. El usuario debe tener en cuenta al usar el restablecimiento completo.
danglingpointer