En plus de la réponse acceptée, si votre fichier ajouté par erreur était énorme, vous remarquerez probablement que, même après l'avoir supprimé de l'index avec ' git reset
', il semble toujours occuper de l'espace dans le .git
répertoire.
Ce n'est rien à craindre; le fichier est en effet toujours dans le référentiel, mais uniquement comme un "objet lâche". Il ne sera pas copié dans d'autres référentiels (via clone, push), et l'espace sera finalement récupéré - mais peut-être pas très bientôt. Si vous êtes anxieux, vous pouvez exécuter:
git gc --prune=now
Mise à jour (ce qui suit est ma tentative de dissiper une certaine confusion qui peut résulter des réponses les plus votées):
Alors, qui est le véritable undo de git add
?
git reset HEAD <file>
?
ou
git rm --cached <file>
?
À proprement parler, et si je ne me trompe pas: aucun .
git add
ne peut pas être annulé - en toute sécurité, en général.
Rappelons d'abord ce que git add <file>
fait réellement:
S'il <file>
n'a pas été suivi auparavant , l' git add
ajoute au cache , avec son contenu actuel.
Si <file>
a déjà été suivi , git add
enregistre le contenu actuel (instantané, version) dans le cache. Dans Git, cette action est toujours appelée add , (pas simplement la mettre à jour ), car deux versions différentes (instantanés) d'un fichier sont considérées comme deux éléments différents: par conséquent, nous ajoutons effectivement un nouvel élément au cache, pour être finalement commis plus tard.
À la lumière de cela, la question est légèrement ambiguë:
J'ai par erreur ajouté des fichiers en utilisant la commande ...
Le scénario de l'OP semble être le premier (fichier non suivi), nous voulons que le "défaire" supprime le fichier (pas seulement le contenu actuel) des éléments suivis. Si tel est le cas, vous pouvez exécuter git rm --cached <file>
.
Et nous pourrions également courir git reset HEAD <file>
. C'est généralement préférable, car cela fonctionne dans les deux scénarios: il effectue également l'annulation lorsque nous avons ajouté à tort une version d'un élément déjà suivi.
Mais il y a deux mises en garde.
Premièrement: il n'y a (comme indiqué dans la réponse) qu'un seul scénario dans lequel git reset HEAD
cela ne fonctionne pas, mais git rm --cached
fonctionne: un nouveau référentiel (pas de commit). Mais, vraiment, c'est un cas pratiquement hors de propos.
Deuxièmement: sachez que git reset HEAD
vous ne pouvez pas récupérer par magie le contenu du fichier précédemment mis en cache, il le resynchronise simplement à partir de HEAD. Si notre erreur a git add
remplacé une version précédente non validée par étapes, nous ne pouvons pas la récupérer. C'est pourquoi, à proprement parler, nous ne pouvons pas annuler [*].
Exemple:
$ git init
$ echo "version 1" > file.txt
$ git add file.txt # First add of file.txt
$ git commit -m 'first commit'
$ echo "version 2" > file.txt
$ git add file.txt # Stage (don't commit) "version 2" of file.txt
$ git diff --cached file.txt
-version 1
+version 2
$ echo "version 3" > file.txt
$ git diff file.txt
-version 2
+version 3
$ git add file.txt # Oops we didn't mean this
$ git reset HEAD file.txt # Undo?
$ git diff --cached file.txt # No dif, of course. stage == HEAD
$ git diff file.txt # We have irrevocably lost "version 2"
-version 1
+version 3
Bien sûr, ce n'est pas très critique si nous suivons simplement le flux de travail paresseux habituel de faire `` git add '' uniquement pour ajouter de nouveaux fichiers (cas 1), et nous mettons à jour le nouveau contenu via la git commit -a
commande commit , .
* (Edit: ce qui précède est pratiquement correct, mais il peut toujours y avoir des moyens légèrement hack / alambiqués pour récupérer des modifications qui ont été mises en scène, mais non validées puis écrasées - voir les commentaires de Johannes Matokic et iolsmit)
HEAD
ouhead
peuvent désormais être utilisées@
à la placeHEAD
. Voir cette réponse (dernière section) pour savoir pourquoi vous pouvez le faire.