Différentes façons de supprimer les modifications locales de Git

625

Je viens de cloner un référentiel git et de vérifier une branche. J'ai travaillé dessus, puis j'ai décidé de supprimer toutes mes modifications locales, car je voulais la copie originale.

En bref, j'ai dû faire les deux commandes suivantes pour supprimer mes modifications locales

git checkout .

git clean -f

Ma question est,

(1) Est-ce la bonne approche pour se débarrasser des changements locaux, ou bien faites-moi savoir la bonne approche.

(2) Quand utilisons-nous git reset --hardcar je peux réinitialiser même sans cette commande

Merci

* Solution: Édition (s) majeure (s): 26/03: * Remplacement de nombreux termes vagues par une terminologie spécifique à git [tracked / untracked / staged / unstaged]

Il ne peut y avoir que trois catégories de fichiers lorsque nous apportons des modifications locales:

Type 1. Fichiers suivis par étapes

Type 2. Fichiers suivis non organisés

Type 3. Fichiers non suivis non classés aka fichiers non suivis

  • Staged - Ceux qui sont déplacés vers la zone de transit / Ajouté à l'index
  • Suivi - fichiers modifiés
  • UnTracked - nouveaux fichiers. Toujours sans mise en scène. S'ils sont organisés, cela signifie qu'ils sont suivis.

Que fait chaque commande:

  1. git checkout . - Supprime UNIQUEMENT les fichiers suivis non classés [Type 2]

  2. git clean -f - Supprime les fichiers non suivis non suivis UNIQUEMENT [Type 3]

  3. git reset --hard - Supprime UNIQUEMENT les fichiers suivis par étapes et suivis par étapes [Type 1, Type 2]

  4. git stash -u - Supprime toutes les modifications [Type 1, Type 2, Type 3]

Conclusion:

Il est clair que nous pouvons utiliser soit

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

OU

(2) `git stash -u`

pour atteindre le résultat souhaité.

Remarque: Stashing, car le mot signifie «stocker (quelque chose) en toute sécurité et secrètement dans un endroit spécifié». Cela peut toujours être récupéré à l'aide de git stash pop. Donc, choisir entre les deux options ci-dessus est l'appel du développeur.

Merci Christoph et Frederik Schøning.

Modifier: 27/03

Je pensais que la valeur de ce mettre la « attention note » àgit clean -f

git clean -f

il n'y a pas de retour en arrière. Utilisez -nou --dry-runpour prévisualiser les dégâts que vous causerez.

Si vous souhaitez également supprimer des répertoires, exécutez git clean -f -d

Si vous souhaitez simplement supprimer les fichiers ignorés, exécutez git clean -f -X

Si vous souhaitez supprimer les fichiers ignorés et non ignorés, exécutez git clean -f -x

référence: plus d'informations sur git clean: Comment supprimer les fichiers locaux (non suivis) de l'arborescence de travail Git actuelle?

Modifier: 20/05/15

Suppression de tous les commits locaux sur cette branche [Suppression des commits locaux]

Afin de supprimer tous les commits locaux sur cette branche, pour rendre la branche locale identique à "l'amont" de cette branche, exécutez simplement git reset --hard @{u}

Référence: http://sethrobertson.github.io/GitFixUm/fixup.html

ou faites git reset --hard origin/master[si la succursale locale est master]

Remarque: 06/12/2015 Ce n'est pas un doublon de l'autre question SO marquée comme doublon. Cette question porte sur la façon de supprimer les modifications GIT locales [supprimer un fichier ajouté, supprimer les modifications ajoutées au fichier existant, etc. et les différentes approches; Où, dans l'autre thread SO, uniquement comment supprimer la validation locale. Si vous avez ajouté un fichier et que vous souhaitez le supprimer seul, l'autre thread SO n'en discute pas. Par conséquent, ce n'est pas un doublon de l'autre]

Modifier: 23/06/15

Comment rétablir un commit déjà poussé vers un référentiel distant?

$ git revert ab12cd15

Modifier: 09/01/2015

Supprimer une validation précédente de la branche locale et de la branche distante

Cas: Vous venez de commettre un changement dans votre branche locale et vous avez immédiatement poussé vers la branche distante, réalisez soudain, Oh non! Je n'ai pas besoin de ce changement. Maintenant quoi faire?

git reset --hard HEAD~1 [pour supprimer ce commit de la branche locale]

git push origin HEAD --force[les deux commandes doivent être exécutées. Pour supprimer de la branche distante]

Quelle est la branche? C'est la branche actuellement vérifiée.

Modifier le 09/08/2015 - Supprimer la fusion git locale :

Je suis en mastersuccursale et j'ai fusionné masteravec une nouvelle succursalephase2

$ git status
# On branch master

$ git merge phase2

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

Q: Comment se débarrasser de cette fusion? Essayé git reset --hard et les git clean -d -f deux n'ont pas fonctionné.

La seule chose qui a fonctionné est l'une des suivantes:

$ git reset --hard origin/master

ou

$ git reset --hard HEAD~8

ou

$ git reset --hard 9a88396f51e2a068bb7 [sha commit code - c'est celui qui était présent avant que toutes vos validations de fusion ne se produisent]

homme araignée
la source
1
Je suppose que ce fil pourrait répondre à vos questions: stackoverflow.com/questions/1146973/…
Saucier
1
"git stash" supprimera toutes les modifications que vous avez apportées.
John Ballinger
1
Joli résumé! J'ajouterais une autre catégorie de fichiers: "Type 4. Fichiers ignorés". git stash -a[ou --all] stockera également les fichiers ignorés et non suivis. git clean -xnettoiera également les fichiers ignorés. git clean -Xne nettoiera que les fichiers ignorés.
Jerry101
2
@JavaDev Votre question ressemblait plus à une réponse .. appréciez que vous ayez continué à éditer et compilé toutes les réponses.
Bhavuk Mathur
1
merci d'avoir exécuté vos 4 commandes pour inverser les changements locaux
Vincent Tang

Réponses:

505

Tout dépend exactement de ce que vous essayez d'annuler ou de rétablir. Commencez par lire l'article dans le lien d'Ube . Mais pour tenter une réponse:

Réinitialisation matérielle

git reset --hard [HEAD]

supprimer complètement toutes les modifications échelonnées et non échelonnées des fichiers suivis.

Je me retrouve souvent à utiliser une réinitialisation difficile, quand je me dis "juste tout annuler comme si j'avais fait un re-clone complet depuis la télécommande". Dans votre cas, où vous voulez juste que votre repo soit vierge, cela fonctionnerait.

Nettoyer

git clean [-f]

Supprimez les fichiers qui ne sont pas suivis.

Pour supprimer les fichiers temporaires, mais conserver les modifications par étapes et non par étapes des fichiers déjà suivis. La plupart du temps, je finirais probablement par faire une règle d'ignorer au lieu de nettoyer à plusieurs reprises - par exemple pour les dossiers bin / obj dans un projet C #, que vous voudriez généralement exclure de votre référentiel pour économiser de l'espace, ou quelque chose comme ça.

L'option -f (forcer) supprimera également les fichiers qui ne sont pas suivis et sont également ignorés par git via ignore-rule. Dans le cas ci-dessus, avec une règle ignore pour ne jamais suivre les dossiers bin / obj, même si ces dossiers sont ignorés par git, l'utilisation de l'option force les supprimera de votre système de fichiers. J'ai vu sporadiquement une utilisation pour cela, par exemple lors du déploiement de scripts, et vous voulez nettoyer votre code avant de déployer, de zipper ou autre.

Git clean ne touchera pas les fichiers qui sont déjà en cours de suivi.

Commander "dot"

git checkout .

En fait, je n'avais jamais vu cette notation avant de lire votre message. J'ai du mal à trouver de la documentation pour cela (peut-être que quelqu'un peut aider), mais en jouant un peu, il semble que cela signifie:

msgstr "annuler toutes les modifications dans mon arbre de travail".

C'est-à-dire annuler les modifications non mises en scène dans les fichiers suivis. Apparemment, il ne touche pas aux modifications par étapes et laisse les fichiers non suivis seuls.

Stashing

Certaines réponses mentionnent la dissimulation. Comme le libellé l'indique, vous utiliserez probablement le stashing lorsque vous êtes au milieu de quelque chose (pas prêt pour une validation), et vous devez changer temporairement de branche ou travailler d'une manière ou d'une autre sur un autre état de votre code, pour revenir plus tard à votre "désordre" bureau". Je ne vois pas que cela s'applique à votre question, mais c'est certainement pratique.

Pour résumer

Généralement, si vous êtes sûr d'avoir commis et peut-être poussé à une modification importante à distance, si vous jouez simplement ou similaire, l'utilisation de git reset --hard HEADsuivi git clean -fnettoiera définitivement votre code à l'état, il serait dans, s'il venait d'être cloné et vérifié d'une succursale. Il est vraiment important de souligner que la réinitialisation supprimera également les modifications par étapes, mais non validées. Il effacera tout ce qui n'a pas été validé (sauf les fichiers non suivis, dans ce cas, utilisez clean ).

Toutes les autres commandes sont là pour faciliter des scénarios plus complexes, où une granularité de "défaire des trucs" est nécessaire :)

Je pense que votre question n ° 1 est couverte, mais enfin, pour conclure sur le n ° 2: la raison pour laquelle vous n'avez jamais trouvé la nécessité d'utiliser git reset --hardétait que vous n'aviez jamais rien mis en scène. Si vous aviez organisé un changement, ni git checkout .ne l' git clean -fauriez inversé.

J'espère que cela couvre.

Frederik Struck-Schøning
la source
Merci pour la raison derrière l'utilisation git reset --hard. Je l'ai essayé, et oui .. ces fichiers ajoutés à l'index (mise en scène) ont été supprimés seulement après git reset --hard, et je suppose que par défaut, git reset --hardc'est git reset --hard head. Ce lien a également été utile gitready.com/beginner/2009/01/18/the-staging-area.html
spiderman
J'ai amélioré ma réponse pourquoi je pense que git stash -uc'est plus logique ici.
Christoph
2
Merci à vous deux. J'ai résumé la réponse et intégré à ma question. Christoph m'a fait savoir ce git stash -uqu'il faisait et comment le faire apparaître, mais Frederik m'a fait savoir réinitialiser dur et en utilisant la combinaison de git reset --hardet git clean -f, et pourquoi pas stashest préféré dans certains scénarios. Maintenant, aidez-moi à choisir celle que je dois marquer comme réponse :), les deux sont mes réponses.
spiderman
3
.est une spécification de chemin faisant référence au répertoire de travail actuel, qui peut être la racine du dépôt. Depuis git-scm.com: git checkout [<tree-ish>] [--] <pathspec>…met à jour les chemins nommés dans l'arborescence de travail à partir du fichier d'index ou d'un <tree-ish> nommé.
Jerry101
3
Il n'est jamais assez souligné que les deux git reset --hardet git clean -dfxsimilaires sont destructeurs . Quoi qu'il en soit, veuillez corriger les minuscules headdans la réponse, elles doivent être en majuscules HEADou ne pas être présentes du tout.
Pavel Šimerda
25

Raison de l'ajout d'une réponse en ce moment:

Jusqu'à présent, j'ajoutais la conclusion et les «réponses» à ma question initiale elle-même, ce qui rendait la question très longue, donc je passais à une réponse distincte.

J'ai également ajouté des commandes git plus fréquemment utilisées qui m'aident sur git, pour aider quelqu'un d'autre aussi.

Fondamentalement, pour nettoyer tous les commits locaux $ git reset --hardet $ git clean -d -f


La première étape avant d'effectuer des validations consiste à configurer votre nom d'utilisateur et votre e-mail qui s'affichent avec votre validation.

#Définit le nom que vous souhaitez attacher à vos transactions de validation

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

#Définit l'e-mail que vous souhaitez joindre à vos transactions de validation

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

#List the global config

$ git config --list

#Lister l'URL distante

$ git remote show origin

#check status

git status

#Lister toutes les succursales locales et distantes

git branch -a

#créer une nouvelle branche locale et commencer à travailler sur cette branche

git checkout -b "branchname" 

ou, cela peut être fait comme un processus en deux étapes

créer une branche: git branch branchname travaillez sur cette branche:git checkout branchname

#commit local changes [processus en deux étapes: - Ajouter le fichier à l'index, c'est-à-dire l'ajouter à la zone de transfert . Validez ensuite les fichiers présents dans cette zone de transfert]

git add <path to file>

git commit -m "commit message"

#checkout autre branche locale

git checkout "local branch name"

#remove toutes les modifications dans la branche locale [Supposons que vous ayez apporté quelques modifications dans la branche locale comme l'ajout d'un nouveau fichier ou la modification d'un fichier existant, ou la création d'un commit local, mais que vous n'en avez plus besoin] git clean -d -fet git reset --hard [nettoyez toutes les modifications locales apportées à la branche locale sauf si validation locale]

git stash -u supprime également toutes les modifications

Remarque: Il est clair que nous pouvons utiliser soit (1) combinaison de git clean –d –fet git reset --hard OR (2) git stash -u pour obtenir le résultat souhaité.

Remarque 1: Stashing, car le mot signifie `` stocker (quelque chose) en toute sécurité et secrètement dans un endroit spécifié ''. Cela peut toujours être récupéré en utilisant git stash pop. Donc, choisir entre les deux options ci-dessus est l'appel du développeur.

Remarque 2: git reset --hardsupprimera les modifications du répertoire de travail. Assurez-vous de cacher toutes les modifications locales que vous souhaitez conserver avant d'exécuter cette commande.

# Passez à la branche principale et assurez-vous que vous êtes à jour.

git checkout master

git fetch [cela peut être nécessaire (en fonction de votre configuration git) pour recevoir des mises à jour sur l'origine / master]

git pull

# Fusionnez la branche de fonction dans la branche principale.

git merge feature_branch

# Réinitialise la branche principale à l'état d'origine.

git reset origin/master

#Accidentellement supprimé un fichier du local, comment le récupérer? Faire un git statuspour obtenir le chemin de fichier complet de la ressource supprimée

git checkout branchname <file path name>

c'est ça!

#Merge master branch avec someotherbranch

git checkout master
git merge someotherbranchname

#rename local branch

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

# supprimer la branche locale

git branch -D branch-name

#delete remote branch

git push origin --delete branchname

ou

git push origin :branch-name

#revert un commit déjà poussé vers un dépôt distant

git revert hgytyz4567

#branch à partir d'un commit précédent utilisant GIT

git branch branchname <sha1-of-commit>

#Modifier le message de validation de la dernière validation déjà envoyée à distance

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

# Supprimer toutes les validations locales sur cette branche [Supprimer les validations locales]

Afin de supprimer tous les commits locaux sur cette branche, pour rendre la branche locale identique à "l'amont" de cette branche, exécutez simplement

git reset --hard @{u}

Référence: http://sethrobertson.github.io/GitFixUm/fixup.html ou faites git reset --hard origin/master[si la branche locale est maître]

# Rétablir un commit déjà poussé vers un référentiel distant?

$ git revert ab12cd15

#Supprime une validation précédente de la branche locale et de la branche distante

Cas d'utilisation: Vous venez de valider un changement dans votre branche locale et vous avez immédiatement poussé vers la branche distante, soudainement réalisé, Oh non! Je n'ai pas besoin de ce changement. Maintenant quoi faire?

git reset --hard HEAD~1[pour supprimer ce commit de la branche locale. 1 indique le seul engagement que vous avez fait]

git push origin HEAD --force[les deux commandes doivent être exécutées. Pour supprimer de la branche distante]. La branche actuellement extraite sera désignée comme la branche où vous effectuez cette opération.

# Supprimez certaines des validations récentes du référentiel local et distant et conservez-les dans la validation que vous souhaitez. (une sorte de restauration des commits du local et du distant)

Supposons que vous ayez poussé 3 commits vers une branche distante nommée ' develop'

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

Pour revenir à l'ancien commit (pour changer l'état de la branche)

git log --oneline --decorate --graph // pour voir tous vos commitids

git clean -d -f // nettoie tous les changements locaux

git reset --hard commitid-1 // revenir localement à ce commitid

git push -u origin +develop// pousse cet état à distance. + pour forcer la poussée

# Supprimer la fusion locale de git: Cas: je suis sur la branche principale et la branche principale fusionnée avec une nouvelle branche de travail phase2

$ git status

Sur le maître de branche

$ git merge phase2 $ git status

Sur le maître de branche

Votre branche est en avance sur 'origine / master' de 8 commits.

Q: Comment se débarrasser de cette fusion git locale? Essayé git reset --hardet les git clean -d -fdeux n'ont pas fonctionné. La seule chose qui a fonctionné est l'une des suivantes:

$ git reset --hard origin / master

ou

$ git reset --hard HEAD ~ 8

ou

$ git reset --hard 9a88396f51e2a068bb7 [sha commit code - c'est celui qui était présent avant que toutes vos validations de fusion ne se produisent]

#create gitignore file

touch .gitignore // crée le fichier dans les utilisateurs mac ou unix

exemple de contenu .gitignore:

.project
*.py
.settings

Lien de référence vers la feuille de triche GIT: https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf

homme araignée
la source
1
Votre commande pour la suppression de la branche distante n'est peut-être pas la meilleure . Vous utilisez git push origin :branch-namecependant je recommande d'utilisergit push origin --delete branchname
vibs2006
D'accord, j'ai mis à jour votre suggestion, merci @ vibs2006
spiderman
21

Comme pour tout dans git, il existe plusieurs façons de le faire. Les deux commandes que vous avez utilisées sont une façon de le faire. Une autre chose que vous auriez pu faire est simplement de les ranger git stash -u. Le -uvérifie que les fichiers nouvellement ajoutés (non suivis) sont également inclus.

Ce qui est pratique c'est git stash -uque

  1. c'est probablement la commande la plus simple (seulement?) pour atteindre votre objectif
  2. si vous changez d'avis par la suite, vous récupérez tout votre travail git stash pop(c'est comme supprimer un e-mail dans gmail où vous pouvez simplement annuler si vous changez d'avis par la suite)

À partir de votre autre question git reset --hard, les fichiers non suivis ne seront pas supprimés, vous aurez donc toujours besoin de git clean -f. Mais un git stash -upourrait être le plus pratique.

Christoph
la source
git reset --hardne supprimera pas trassez fichiers en effet, mais il va supprimer les modifications non suivies, par exemple modifications apportées aux fichiers, qui sont déjà dans l'index. Je suis sûr que c'est ce que vous vouliez dire :)
Frederik Struck-Schøning
Quand j'ai utilisé git stash -u, j'ai vu cette réponse de git bash. "Répertoire de travail enregistré et état de l'index WIP sur {branchname}. Peut-être que celui-ci est ce que nous pourrions récupérer en utilisant git stash pop.
spiderman
Merci à vous deux. J'ai résumé la réponse et intégré à ma question. Christoph m'a fait savoir ce git stash -uqu'il faisait et comment le faire apparaître, mais Frederik m'a fait savoir réinitialiser dur et en utilisant la combinaison de git reset --hardet git clean -f, et pourquoi pas stashest préféré dans certains scénarios. Maintenant, aidez-moi à choisir celle que je dois marquer comme réponse :), les deux sont mes réponses.
spiderman
mais que faire s'il y a un fichier que j'ai ajouté à mon référentiel que je ne veux pas suivre? seulement dans mon repo. Si je l'ajoute à la liste des ignorés, j'ai un fichier .ignore à valider qui affectera tout le monde également.
user20358
7

1. Lorsque vous ne souhaitez pas conserver vos modifications locales.

git reset --hard

Cette commande supprimera complètement toutes les modifications locales de votre référentiel local. C'est le meilleur moyen d'éviter les conflits lors de la commande Pull, uniquement si vous ne souhaitez pas conserver vos modifications locales.

2. Lorsque vous souhaitez conserver vos modifications locales

Si vous souhaitez extraire les nouvelles modifications à distance et ignorer les modifications locales lors de cette extraction,

git stash

Il stockera toutes les modifications locales, vous pouvez maintenant extraire les modifications à distance,

git pull

Maintenant, vous pouvez ramener vos modifications locales en,

git stash pop
Actung
la source
1
git reset --hardne supprime pas toutes les modifications locales. Il supprime uniquement les modifications. Si vous souhaitez supprimer des ajouts, vous devez égalementgit clean -fd
John Henckel
4

Utilisation:

git checkout -- <file>

Pour ignorer les modifications dans le répertoire de travail.

Tadas Stasiulionis
la source
4

Je pense que git a une chose qui n'est pas clairement documentée. Je pense que c'était en fait négligé.

git checkout .

Mec, tu m'as sauvé la journée. J'ai toujours des choses que je veux essayer d'utiliser le code modifié. Mais les choses finissent parfois par gâcher le code modifié, ajouter de nouveaux fichiers non suivis, etc. Donc ce que je veux faire, c'est mettre en scène ce que je veux, faire les choses en désordre, puis nettoyer rapidement et valider si je suis content.

Il git clean -fdfonctionne bien pour les fichiers non suivis.

Il git resetsupprime ensuite simplement la mise en scène, mais git checkoutest un peu trop lourd. Spécifier un fichier un par un ou utiliser des répertoires n'est pas toujours idéal. Parfois, les fichiers modifiés dont je veux me débarrasser se trouvent dans des répertoires que je souhaite conserver. Je souhaitais cette commande qui supprime simplement les modifications non mises en scène et vous voici. Merci.

Mais je pense qu'ils devraient juste avoir git checkoutsans aucune option, supprimer tous les changements non mis en scène et ne pas toucher le mis en scène. C'est un peu modulaire et intuitif. Plus comme quoi git reset. git cleandevrait également faire de même.

Emmanuel Mahuni
la source
2

La meilleure façon est de vérifier les modifications.

En modifiant le fichier pom.xml dans un projet nommé project-name, vous pouvez le faire:

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
la source
2

Pour défausse tous j'aime cacher et laisser tomber cette planque, il est le meilleur moyen de jeter tout, surtout si vous travaillez entre plusieurs prises en pension.

Cela stockera toutes les modifications de {0}clé et les supprimera instantanément de{0}

git stash && git stash drop

Tatarin
la source
1

Tout d'abord, vérifiez si votre changement important est enregistré ou non par:

$ git status

que d'essayer

$ git reset --hard

il réinitialisera votre branche par défaut

mais si vous avez juste besoin d'annuler:

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


En savoir plus >> https://git-scm.com/docs/git-reset

Rizo
la source
Note latérale: réinitialiser --hard est une commande dangereuse qui supprimera toutes les modifications et ne peut pas être annulée. L'utilisateur doit être conscient lors de l'utilisation de la réinitialisation matérielle.
danglingpointer