Comment restaurer tous les changements locaux du projet géré par Git à l'état précédent?

1914

J'ai un projet dans lequel j'ai couru git init. Après plusieurs commits, j'ai fait git statusce qui m'a dit que tout était à jour et qu'il n'y avait aucun changement local.

Ensuite, j'ai fait plusieurs changements consécutifs et j'ai réalisé que je voulais tout jeter et revenir à mon état d'origine. Cette commande le fera-t-elle pour moi?

git reset --hard HEAD
Jacques René Mesrine
la source

Réponses:

3390

Si vous souhaitez annuler les modifications apportées à votre copie de travail, procédez comme suit:

git checkout .

Si vous souhaitez annuler les modifications apportées à l'index (c'est-à-dire que vous avez ajoutées), faites-le. Attention, cela réinitialisera tous vos commits non poussés à maîtriser! :

git reset

Si vous souhaitez annuler une modification que vous avez validée, procédez comme suit:

git revert <commit 1> <commit 2>

Si vous souhaitez supprimer des fichiers non suivis (par exemple, de nouveaux fichiers, des fichiers générés):

git clean -f

Ou des répertoires non suivis (par exemple, des répertoires nouveaux ou générés automatiquement):

git clean -fd
1800 INFORMATION
la source
133
fwiw après une si longue période, git checkout path/to/filene reviendra que sur les changements locauxpath/to/file
Matijs
29
+1 sur les réponses ci-dessous mentionnant également git clean -f (pour supprimer les modifications non suivies) et -fd (pour supprimer également les répertoires non suivis)
ptdev
3
et si vous souhaitez également nettoyer vos fichiers non suivis, lisez ce stackoverflow.com/questions/61212/…
Surasin Tancharoen
9
git checkout .et git reset [--hard HEAD]n'a pas fonctionné, j'ai dû faire un git clean -fdpour annuler mes modifications.
BrainSlugs83
7
git resetne réinitialise pas vos modifications, git reset --hardfait cela.
Cerin
388

Remarque: vous pouvez également exécuter

git clean -fd

comme

git reset --hard

ne pas supprimer les fichiers non suivis, alors que nettoyer git supprimer tous les fichiers du répertoire racine chenillé qui ne sont pas sous suivi git. AVERTISSEMENT - SOYEZ PRUDENT AVEC CELA! Il est utile d'exécuter un essai à sec avec git-clean d'abord, pour voir ce qu'il supprimera.

Ceci est également particulièrement utile lorsque vous obtenez le message d'erreur

~"performing this command will cause an un-tracked file to be overwritten"

Ce qui peut se produire lorsque vous faites plusieurs choses, l'une étant la mise à jour d'une copie de travail lorsque vous et votre ami avez tous deux ajouté un nouveau fichier du même nom, mais il l'a d'abord validé dans le contrôle de source, et vous ne vous souciez pas de supprimer votre copie non suivie .

Dans cette situation, faire un essai à vide vous aidera également à afficher une liste de fichiers qui seraient écrasés.

Antony Stubbs
la source
13
La commande de nettoyage de fichier est "git clean -f". Les répertoires non suivis sont supprimés avec "git clean -d"
Jonathan Mitchell
35
git clean -fd (la force est requise pour -d)
electblake
14
-n ou --dry-run sont les drapeaux pour le dry-run.
stephenbez
2
git clean -ffd si vous avez un autre référentiel git dans votre référentiel git. Sans double f, il ne serait pas supprimé.
Trismegistos
149

Re-cloner

GIT=$(git rev-parse --show-toplevel)
cd $GIT/..
rm -rf $GIT
git clone ...
  • ✅ Supprime les commits locaux non poussés
  • ✅ Annule les modifications que vous avez apportées aux fichiers suivis
  • ✅ Restaure les fichiers suivis que vous avez supprimés
  • ✅ Supprime les fichiers / répertoires répertoriés dans .gitignore(comme les fichiers de construction)
  • ✅ Supprime les fichiers / répertoires qui ne sont pas suivis et ne .gitignore
  • 😀 Vous n'oublierez pas cette approche
  • 😔 gaspille la bande passante

Voici d'autres commandes que j'oublie quotidiennement.

Nettoyer et réinitialiser

git clean --force -d -x
git reset --hard
  • ❌ Supprime les commits locaux non poussés
  • ✅ Annule les modifications que vous avez apportées aux fichiers suivis
  • ✅ Restaure les fichiers suivis que vous avez supprimés
  • ✅ Supprime les fichiers / répertoires répertoriés dans .gitignore(comme les fichiers de construction)
  • ✅ Supprime les fichiers / répertoires qui ne sont pas suivis et ne .gitignore

Nettoyer

git clean --force -d -x
  • ❌ Supprime les commits locaux non poussés
  • ❌ Annule les modifications que vous avez apportées aux fichiers suivis
  • ❌ Restaure les fichiers suivis que vous avez supprimés
  • ✅ Supprime les fichiers / répertoires répertoriés dans .gitignore(comme les fichiers de construction)
  • ✅ Supprime les fichiers / répertoires qui ne sont pas suivis et ne .gitignore

Réinitialiser

git reset --hard
  • ❌ Supprime les commits locaux non poussés
  • ✅ Annule les modifications que vous avez apportées aux fichiers suivis
  • ✅ Restaure les fichiers suivis que vous avez supprimés
  • ❌ Supprime les fichiers / répertoires répertoriés dans .gitignore(comme les fichiers de construction)
  • ❌ Supprime les fichiers / répertoires qui ne sont pas suivis et ne .gitignore

Remarques

Cas de test pour confirmer tout ce qui précède (utilisez bash ou sh):

mkdir project
cd project
git init
echo '*.built' > .gitignore
echo 'CODE' > a.sourceCode
mkdir b
echo 'CODE' > b/b.sourceCode
cp -r b c
git add .
git commit -m 'Initial checkin'
echo 'NEW FEATURE' >> a.sourceCode
cp a.sourceCode a.built
rm -rf c
echo 'CODE' > 'd.sourceCode'

Voir également

  • git revert pour effectuer de nouveaux validations qui annulent les validations antérieures
  • git checkout pour remonter dans le temps aux validations précédentes (peut nécessiter l'exécution des commandes ci-dessus en premier)
  • git stashcomme git resetci-dessus, mais vous pouvez l'annuler
William Entriken
la source
Désolé d'avoir volé les réponses ci-dessus. J'utilise cette référence constamment, publiant surtout pour moi.
William Entriken
1
Je suis à peu près sûr que la première option ( Re-clone ) FAIT réellement "supprimer les commits locaux non poussés" :)
Marandil
1
@styfle ✅ est quelque chose qu'il fait, ❌ est quelque chose qu'il ne fait pas
William Entriken
3
@FullDecent C'est un peu déroutant à lire. Msgstr "❌ NE supprime PAS les commits locaux non poussés". Cela signifie qu'il ne supprime PAS. Le double négatif signifie qu'il supprime?
styfle
1
A propos de l'indicateur -x dans git clean -f -d -x: si l'option -x est spécifiée, les fichiers ignorés sont également supprimés. Cela peut, par exemple, être utile pour supprimer tous les produits de construction
Alex
82

Si vous souhaitez annuler toutes les modifications ET être à jour avec le maître distant actuel (par exemple, vous trouvez que la tête principale a avancé depuis que vous l'avez dérivée et que votre push est `` rejeté ''), vous pouvez utiliser

git fetch  # will fetch the latest changes on the remote
git reset --hard origin/master # will set your local branch to match the representation of the remote just pulled down.
Michael Durrant
la source
Il semble important de spécifier origindans git reset --hard origin/master(ce qui fonctionne) - sans cela (c'est-à-dire git reset --hard) rien ne semble être changé.
Jake
J'ai eu quelques changements locaux et je n'ai pas pu m'en débarrasser par aucune commande.J'ai réinitialisé git - origine / maître dur et il a également pu tirer les changements de maître
abhishek ringsia
50

Regardez dans git-reflog. Il répertorie tous les états dont il se souvient (la valeur par défaut est de 30 jours) et vous pouvez simplement vérifier celui que vous souhaitez. Par exemple:

$ git init > /dev/null
$ touch a
$ git add .
$ git commit -m"Add file a" > /dev/null
$ echo 'foo' >> a
$ git commit -a -m"Append foo to a" > /dev/null
$ for i in b c d e; do echo $i >>a; git commit -a -m"Append $i to a" ;done > /dev/null
$ git reset --hard HEAD^^ > /dev/null
$ cat a
foo
b
c
$ git reflog
145c322 HEAD@{0}: HEAD^^: updating HEAD
ae7c2b3 HEAD@{1}: commit: Append e to a
fdf2c5e HEAD@{2}: commit: Append d to a
145c322 HEAD@{3}: commit: Append c to a
363e22a HEAD@{4}: commit: Append b to a
fa26c43 HEAD@{5}: commit: Append foo to a
0a392a5 HEAD@{6}: commit (initial): Add file a
$ git reset --hard HEAD@{2}
HEAD is now at fdf2c5e Append d to a
$ cat a
foo
b
c
d
William Pursell
la source
merci une tonne William, pour git reflog. J'ai réinitialisé mon arbre à l'ancienne version et je ne sais pas comment revenir à la version récente. votre git reflog m'a sauvé. Encore merci.
palaniraja
1
m'a aussi sauvé! Dans mon cas, mon aventure avec git rebase -iavait mal tourné (a fini par effacer certains commits en raison d'une erreur d'édition). Grâce à cette astuce je suis de retour en bon état!
paneer_tikka
Que voulez-vous dire par 30 jours par défaut!?
Mohe TheDreamy
@MoheTheDreamy Je veux dire qu'il y a une limite de temps. Finalement, le garbage collector supprimera les références inaccessibles lorsque leur âge dépassera cette limite. La valeur par défaut était (et est peut-être toujours) de 30 jours. Les anciennes références peuvent donc ne pas être disponibles.
William Pursell
36

DANGER AHEAD: (veuillez lire les commentaires. L'exécution de la commande proposée dans ma réponse pourrait supprimer plus que vous ne le souhaitez)

pour supprimer complètement tous les fichiers, y compris les répertoires que j'ai dû exécuter

git clean -f -d
Tobias Gassmann
la source
13
Pour sauver quiconque la douleur que je viens de traverser: cela supprimera également les fichiers .gitignore-d!
landons
désolé si je vous ai causé des ennuis. À l'époque, j'essayais simplement de rétablir et de supprimer tout dans ce dossier. Je ne me souviens pas des circonstances exactes, mais le "-d" était la seule chose qui fonctionnait pour moi. J'espère que je ne vous ai pas trop fait mal :-)
Tobias Gassmann
1
pas de mal. J'ai eu des sauvegardes, mais cela mérite probablement une clause de non-responsabilité;)
Landons
35

Après avoir lu un tas de réponses et les avoir essayées, j'ai trouvé divers cas marginaux qui signifient parfois qu'ils ne nettoient pas complètement la copie de travail.

Voici mon script bash actuel pour le faire, qui fonctionne tout le temps.

#!/bin/sh
git reset --hard
git clean -f -d
git checkout -- HEAD

Exécuter à partir du répertoire racine de copie de travail.

Scott Davey
la source
10
La dernière commande me donneerror: pathspec 'HEAD' did not match any file(s) known to git.
0xC0000022L
1
Cela a fonctionné pour moi lorsque j'ai retiré le "-". git checkout HEAD
Jester
4
git reset --hardrétablit les fichiers suivis (par étapes ou non), git clean -f -dsupprime les fichiers non suivis, git checkout -- HEADpourquoi en avons-nous besoin alors?
v.shashenko
Nous n'avons pas besoin du double trait d'union. Doit être une faute de frappe.
Farax
35

exécutez simplement -

git stash

cela supprimera toutes vos modifications locales. et vous pouvez également l'utiliser plus tard en exécutant -

git stash apply 
piyushmandovra
la source
3
l'utilisation git stash popsupprimerait automatiquement la modification cachée pour vous
Arrow Cen
8
git stash droppour supprimer le dernier état caché sans appliquer à la copie de travail.
deerchao
git stash apply n'ajoutera pas les fichiers nouvellement créés
Ravistm
27

J'ai rencontré un problème similaire. La solution consiste à git logrechercher quelle version du commit local est différente de la version distante. (Par exemple, la version est 3c74a11530697214cbcc4b7b98bf7a65952a34ec).

Utilisez ensuite git reset --hard 3c74a11530697214cbcc4b7b98bf7a65952a34ecpour annuler la modification.

Patrick
la source
16

J'ai cherché un problème similaire,

Je voulais jeter les commits locaux:

  1. cloné le référentiel (git clone)
  2. basculé vers la branche dev (dev git checkout)
  3. a fait peu de validations (git commit -m "commit 1")
  4. mais a décidé de jeter ces commits locaux pour revenir à distance (origine / dev)

De même que ci-dessous:

git reset --hard origin/dev

Vérifier:

git status  

        On branch dev  
        Your branch is up-to-date with 'origin/dev'.  
        nothing to commit, working tree clean  

maintenant les validations locales sont perdues, revenant à l'état cloné initial, point 1 ci-dessus.

Manohar Reddy Poreddy
la source
1
merci, c'est la seule chose qui a fonctionné pour moi - "git reset --hard origin"
Nisim Naim
heureux de savoir que cela a aidé.
Manohar Reddy Poreddy
7

Vous ne voudrez pas nécessairement / besoin de ranger votre travail / vos fichiers dans votre répertoire de travail, mais au lieu de cela, supprimez-les complètement. La commande git cleanfera cela pour vous.

Certains cas d'utilisation courants pour ce faire seraient de supprimer la corruption générée par des fusions ou des outils externes ou de supprimer d'autres fichiers afin de pouvoir exécuter une nouvelle génération.

Gardez à l'esprit que vous voudrez être très prudent avec cette commande, car elle est conçue pour supprimer les fichiers de votre répertoire de travail local qui ne sont pas suivis. si vous changez soudainement d'avis après avoir exécuté cette commande, vous ne pourrez plus voir le contenu des fichiers supprimés. Une alternative plus sûre consiste à exécuter

git stash --all

qui supprimera tout mais l'enregistrera dans une cachette. Cette réserve peut ensuite être utilisée ultérieurement.

Cependant, si vous voulez vraiment supprimer tous les fichiers et nettoyer votre répertoire de travail, vous devez exécuter

git clean -f -d

Cela supprimera tous les fichiers et tous les sous-répertoires qui n'ont aucun élément à la suite de la commande. Une chose intelligente à faire avant d'exécuter la git clean -f -dcommande est d'exécuter

git clean -f -d -n

qui vous montrera un aperçu de ce qui sera supprimé après l'exécution git clean -f -d

Voici donc un résumé de vos options du plus agressif au moins agressif


Option 1 : supprimer tous les fichiers localement (le plus agressif)

git clean -f -d

Option 2 : Aperçu de l'impact ci-dessus (Aperçu le plus agressif)

git clean -f -d -n

Option 3 : Stockez tous les fichiers (les moins agressifs)

`git stash --all` 
jbooker
la source
6

Essayez ceci pour annuler toutes les modifications non validées dans la branche locale

$ git reset --hard HEAD

Mais si vous voyez une erreur comme celle-ci:

fatal: Unable to create '/directory/for/your/project/.git/index.lock': File exists.

Vous pouvez accéder au dossier '.git' puis supprimer le fichier index.lock:

$ cd /directory/for/your/project/.git/
$ rm index.lock

Enfin, relancez la commande:

$ git reset --hard HEAD
Janderson Silva
la source
0

Cette question concerne davantage la réinitialisation / restauration du référentiel plus large, mais si vous souhaitez annuler une modification individuelle, j'ai ajouté une réponse similaire ici:

https://stackoverflow.com/a/60890371/2338477

Réponses aux questions:

  • Comment annuler un changement individuel avec ou sans changement de conservation dans l'historique Git

  • Comment revenir à l'ancienne version pour redémarrer à partir du même état

TarmoPikaro
la source