Question Pourquoi y a-t-il 2 façons de désactiver un fichier dans git?


Parfois git suggère git rm --cached pour dénicher un fichier, parfois git reset HEAD file. Quand devrais-je utiliser quoi?

MODIFIER:

D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       a
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add a

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 a

D:\code\gt2>touch b

D:\code\gt2>git status
# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       b
nothing added to commit but untracked files present (use "git add" to track)

D:\code\gt2>git add b

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

833
2017-08-02 21:50


origine


Réponses:


git rm --cached <filePath>  ne se déconnecte pas un fichier, en fait étapes la suppression du (des) fichier (s) à partir du repo (en supposant qu'il a déjà été commis auparavant) mais laisse le fichier dans votre arbre de travail (vous laissant avec un fichier non suivi).

git reset <filePath> volonté désynchroniser des changements par étapes pour le (s) fichier (s) donné (s).

Cela dit, si vous avez utilisé git rm --cached Sur un nouveau fichier qui est mis en scène, il semblerait que vous l'ayez simplement désynchronisé car il n'avait jamais été engagé auparavant.


1361
2017-08-02 22:03



git rm --cached est utilisé pour supprimer un fichier de l'index. Dans le cas où le fichier est déjà dans le repo, git rm --cached va supprimer le fichier de l'index, le laissant dans le répertoire de travail et un commit le supprimera également du repo. Fondamentalement, après le commit, vous auriez décomprimé le fichier et gardé une copie locale.

git reset HEAD file (qui par défaut utilise le --mixed flag) est différent en ce sens que dans le cas où le fichier est déjà dans le repo, il remplace la version index du fichier par celle de repo (HEAD), ce qui désactive modifications à lui.

Dans le cas d'un fichier non versionné, il va désassembler le fichier entier car le fichier n'était pas présent dans la HEAD. Dans cet aspect git reset HEAD file et git rm --cached sont identiques, mais ils ne sont pas identiques (comme expliqué dans le cas de fichiers déjà dans le repo)

À la question de Why are there 2 ways to unstage a file in git? - Il n'y a jamais vraiment qu'une seule façon de faire quoi que ce soit en git. c'est la beauté :)


303
2017-08-02 23:00



Tout simplement:

  • git rm --cached <file>  Git arrêter le suivi du fichier complètement (en laissant dans le système de fichiers, contrairement à la plaine git rm*)
  • git reset HEAD <file>  désinstalle les modifications apportées au fichier depuis le dernier commit (mais ne les retourne pas dans le système de fichiers, contrairement à ce que le nom de la commande pourrait suggérer **). Le fichier reste sous contrôle de révision.

Si le fichier ne faisait pas l'objet d'un contrôle de révision auparavant (c'est-à-dire que vous supprimez un fichier que vous venez de git added pour la première fois), alors les deux commandes ont le même effet, d'où l'apparition de celles-ci étant "deux façons de faire quelque chose".

* Gardez à l'esprit l'avertissement @DrewT mentions dans sa réponse, concernant git rm --cached d'un fichier qui était précédemment engagé au référentiel. Dans le contexte de cette question, d'un fichier ajouté et non encore engagé, il n'y a pas de quoi s'inquiéter.

** J'ai eu très peur d'utiliser la commande git reset à cause de son nom, et aujourd'hui encore, je vérifie souvent la syntaxe pour m'assurer que je ne bousille pas. (mettre à jour: J'ai finalement pris le temps de résumer l'utilisation de git reset dans une page tldr, alors maintenant j'ai un meilleur modèle mental de comment ça marche, et une référence rapide pour quand j'oublie un détail.)


86
2017-10-17 21:16



Ce fil est un peu ancien, mais je veux quand même ajouter une petite démonstration car ce n'est toujours pas un problème intuitif:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD(sans pour autant -q) donne un avertissement sur le fichier modifié et son code de sortie est 1, ce qui sera considéré comme une erreur dans un script.

Modifier: git checkout HEAD to-be-modified to-be-removed fonctionne également pour unstaging, mais supprime complètement le changement de l'espace de travail


35
2018-04-16 19:00



Si vous avez accidentellement mis en scène des fichiers que vous n'aimeriez pas valider, et que vous voulez être certain de conserver les modifications, vous pouvez également utiliser:

git stash
git stash pop

ceci effectue une réinitialisation de HEAD et applique à nouveau vos modifications, ce qui vous permet de réétablir des fichiers individuels pour validation. Ceci est également utile si vous avez oublié de créer une branche de fonctionnalité pour les demandes de pull (git stash ; git checkout -b <feature> ; git stash pop).


27
2018-02-10 17:06



Ces 2 commandes ont plusieurs différences subtiles si le fichier en question est déjà dans le repo et sous le contrôle de version (précédemment engagé, etc.):

  • git reset HEAD <file> désinstalle le fichier dans le commit actuel.
  • git rm --cached <file> désinstalle le fichier pour les futurs commits aussi. Il n'est pas stocké jusqu'à ce qu'il soit ajouté à nouveau avec git add <file>.

Et il y a une différence plus importante:

  • Après avoir couru git rm --cached <file> et poussez votre branche vers la télécommande, n'importe qui tirant votre branche de la télécommande obtiendra le dossier RÉELLEMENT supprimé de leur dossier, même si dans votre groupe de travail local, le fichier n'est pas suivi (c'est-à-dire qu'il n'est pas physiquement supprimé du dossier).

Cette dernière différence est importante pour les projets qui incluent un fichier de configuration dans lequel chaque développeur de l'équipe a une config différente (c'est-à-dire une URL de base différente, un ip ou un paramètre de port) donc si vous utilisez git rm --cached <file> toute personne qui tire votre branche devra recréer manuellement la config, ou vous pouvez les envoyer les vôtres et ils peuvent les ré-éditer dans leurs paramètres ip (etc.), parce que la suppression n'affecte que les personnes qui tirent votre branche de la télécommande .


14
2017-08-10 20:04



Disons toi stage un répertoire entier via git add <folder>, mais vous souhaitez exclure un fichier de la liste intermédiaire (c'est-à-dire la liste générée lors de l'exécution git status) et garder les modifications dans le fichier exclu (vous travailliez sur quelque chose et ce n'est pas prêt pour le commit, mais vous ne voulez pas perdre votre travail ...). Vous pouvez simplement utiliser:

git reset <file>

Lorsque vous courez git status, vous verrez que quel que soit le fichier reset sont unstaged et le reste des fichiers vous added sont toujours dans le staged liste.


8
2017-08-28 16:08