«Git rm --cached x» vs «git reset head - x»?

163

GitRef.org - Basique :

git rmsupprimera les entrées de la zone de transit. C'est un peu différent de git reset HEADcelui des fichiers "désétapes". Par "unstage", je veux dire que cela ramène la zone de préparation à ce qui était là avant que nous commencions à modifier les choses. git rmd'un autre côté, il suffit de lancer complètement le fichier de la scène, de sorte qu'il ne soit pas inclus dans l'instantané de validation suivant, le supprimant ainsi efficacement.

Par défaut, a git rm filesupprimera entièrement le fichier de la zone de préparation et également de votre disque> (le répertoire de travail). Pour laisser le fichier dans le répertoire de travail, vous pouvez utiliser git rm --cached.

Mais quelle est exactement la différence entre git rm --cached asdet git reset head -- asd?

Pacerier
la source

Réponses:

219

Il y a trois endroits où un fichier, par exemple, peut être - l'arborescence, l'index et la copie de travail. Lorsque vous ajoutez simplement un fichier à un dossier, vous l'ajoutez à la copie de travail.

Lorsque vous faites quelque chose comme git add filevous l'ajoutez à l'index. Et lorsque vous le validez, vous l'ajoutez également à l'arbre.

Cela vous aidera probablement à connaître les trois indicateurs les plus courants dans git reset:

git reset [- <mode>] [ <commit>]

Ce formulaire réinitialise la tête de branche actuelle <commit>et met éventuellement à jour l'index (en le réinitialisant dans l'arborescence de <commit>) et l'arbre de travail en fonction de <mode>, qui doit être l'un des suivants:
--soft

Ne touche pas du tout le fichier d'index ni l'arborescence de travail (mais réinitialise la tête sur <commit>, comme tous les modes le font). Cela laisse tous vos fichiers modifiés "Modifications à valider", comme le dirait l'état git.

--mixte

Réinitialise l'index mais pas l'arborescence de travail (c'est-à-dire que les fichiers modifiés sont conservés mais pas marqués pour la validation) et signale ce qui n'a pas été mis à jour. C'est l'action par défaut.

--dur

Réinitialise l'index et l'arborescence de travail. Toutes les modifications apportées aux fichiers suivis dans l'arborescence de travail depuis <commit>sont ignorées.

Maintenant, quand vous faites quelque chose comme git reset HEAD- ce que vous faites réellement est git reset HEAD --mixedet cela "réinitialise" l'index à l'état où il était avant de commencer à ajouter des fichiers / ajouter des modifications à l'index (via git add) Dans ce cas, la copie de travail et le index (ou staging) étaient synchronisés, mais vous avez fait en sorte que HEAD et l'index soient synchronisés après la réinitialisation.

git rmd'autre part, supprime un fichier du répertoire de travail et de l'index et lorsque vous validez, le fichier est également supprimé de l'arborescence. git rm --cachedcependant supprime le fichier de l'index seul et le conserve dans votre copie de travail. C'est exactement le contraire de git add file Dans ce cas, vous avez fait que l'index soit différent de la tête et du travail, en ce que la tête a la version précédemment validée du fichier, la copie de travail a eu la dernière modification, le cas échéant, ou le contenu de HEAD de le fichier et vous avez supprimé le fichier de l'index. Un commit maintenant synchronisera l'index et l'arborescence et le fichier sera supprimé.

manojlds
la source
Je remarque qu'après git rm --cachedla git diffcommande ne montre aucun diff, mais git diff --cachedmontre le diff, comme s'il était toujours en cache. Le git statuscependant montre le fichier comme étant Untracked. Cela semble un peu incohérent.
haridsv
7
Qu'à cela ne tienne ... j'aurais dû l'utiliser git reset --mixed. J'étais un peu confus par la déclaration qui git rm --cachedest le contraire de git add. Pris à la lettre, il est incorrect et pourrait causer des dommages. Dans mon cas, j'avais l'habitude git addd'ajouter un fichier modifié à la zone de transit et je voulais le contraire de "qui ajoute" et non l'ajout initial du fichier. + La réponse de Greg Hewgill m'a aidé à avoir une image plus claire.
haridsv
12
Je trouve l'utilisation de la copie de travail, de l'arbre et de l'arbre de travail un peu déroutante. L'arbre de travail est-il la copie de travail ou l'arbre?
Nealv
3
Comme @haridsv l'a mentionné, dire git rm --cached«est exactement le contraire de git add file» est trompeur. git reset fileest plus proche de l'opposé de git add file.
Matt Browne
@Nealv tardivement, mais pour les autres qui trouvent ce fil: copie de travail, arbre et arbre de travail font tous référence à la même chose (dans le contexte de git).
De Novo
83

Peut-être qu'un exemple vous aidera:

git rm --cached asd
git commit -m "the file asd is gone from the repository"

contre

git reset HEAD -- asd
git commit -m "the file asd remains in the repository"

Notez que si vous n'avez rien changé d' autre , le deuxième commit ne fera rien.

Greg Hewgill
la source
3
Pouvez-vous me dire ce que signifie réellement ce double trait d'union - après HEAD?
yuva
30
@yuva: Le --est utilisé pour séparer les options de commande des noms de fichiers. S'il y avait à la fois une branche et un fichier nommés asd, alors ce git reset HEAD asdserait ambigu. Le --dit "tout ce qui suit est un nom de fichier".
Greg Hewgill
Est-ce git reset HEAD <file>exactement la même chose que git rm --cached <file>et alors git add --intent-to-add <file>?
alcool est mauvais
1
@alcoholisevil non, sauf cas particulier. Voyez cette excellente réponse succincte.
De Novo
45

git rm --cached fileva supprimer le fichier de la scène. Autrement dit, lorsque vous validez, le fichier sera supprimé. git reset HEAD -- fileréinitialisera simplement le fichier dans la zone de préparation à l'état où il était lors de la validation HEAD, c'est-à-dire annulera toutes les modifications que vous y avez apportées depuis la dernière validation. Si ce changement vient d'ajouter le fichier, alors ils seront équivalents.

youriks
la source
7
En conjonction avec la notion (comme mentionné dans d'autres réponses) qui git rm --cached fileest un peu le contraire de git add, cette réponse avait beaucoup de sens pour moi et était assez succincte. Presque aussi court que ce commentaire;)
rbatt
2
@rbatt juste pour mettre le commentaire ici aussi, et clarifier, git rm --cached filen'est pas le contraire degit add file . Le comportement se trouve être le contraire du git add filecas spécifique où vous avez ajouté un nouveau fichier, précédemment non suivi. Dans tous les autres cas, l'opposé de git add fileest git reset HEAD file. git reset HEAD fileinverse également git add filedans le premier cas (ajout d'un fichier non suivi), et dans tous les cas, c'est pourquoi c'est ce que git suggère de faire si vous voulez inverser un git add.
De Novo