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

parfois git suggère git rm --cached pour dégrafer un fichier, parfois git reset HEAD file . Quand dois-je utiliser?

EDIT:

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
#
885
demandé sur Nick Volynkin 2011-08-03 01:50:49
la source

10 ответов

git rm --cached <filePath> ne dégrafe pas un fichier, il en fait étapes le retrait du fichier(s) de la pension (en supposant qu'il a déjà été engagé avant), mais laisse le fichier dans votre arbre de travail (vous laissant avec un fichier non piraté).

git reset -- <filePath> sera unstage toute mise en scène de changements pour le fichier donné(s).

cela dit, si vous avez utilisé git rm --cached sur un nouveau fichier qui est mis en scène, on croirait que vous venez de le déballer car il n'a jamais été commis auparavant.

1454
répondu Ryan Stewart 2018-08-06 16:45:31
la source

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 supprimera le fichier de l'index, le laissant dans le répertoire de travail et un commit le supprimera aussi du repo. En gros, après la propagation, vous auriez désactivé le fichier et gardé une copie locale.

git reset HEAD file (qui par défaut utilise le drapeau --mixed ) est différent dans le cas où le fichier est déjà dans la repo, il remplace la version index du fichier par celle de la repo (HEAD), déballant effectivement les modifications à lui.

dans le cas d'un fichier non suivi en versions, il va dégrafer le fichier entier car le fichier n'était pas là dans la tête. Dans cet aspect git reset HEAD file et git rm --cached sont les mêmes, mais ils ne sont pas les mêmes ( comme expliqué dans le cas des 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 quelque chose en gitan. c'est la beauté de celui-ci :)

306
répondu manojlds 2011-08-03 03:00:25
la source

tout simplement:

  • git rm --cached <file> fait que git arrête complètement de suivre le fichier (le laissant dans le système de fichiers, contrairement au simple git rm *)
  • git reset HEAD <file> décompose toutes les modifications apportées au fichier depuis la dernière propagation (mais ne les inverse 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 n'était pas sous contrôle de révision auparavant (c'est-à-dire que vous déballez un fichier que vous venez de git add ed pour la première fois), alors les deux commandes ont le même effet, d'où l'apparence de celles-ci étant "deux façons de faire quelque chose".

* gardez à l'esprit la mise en garde @DrewT mentionnée dans sa réponse, concernant git rm --cached d'un fichier qui était déjà engagé dans le dépôt. Dans le contexte de cette question, d'un fichier qui vient d'être ajouté et qui n'est pas encore engagé, il n'y a pas de quoi s'inquiéter.

* * j'ai eu peur pendant une longue période embarrassante d'utiliser la commande de réinitialisation git à cause de son nom -- et encore aujourd'hui je regarde souvent la syntaxe pour m'assurer que je ne foire pas. ( update : j'ai finalement pris le temps de résumer l'usage de git reset dans une page tldr , donc maintenant j'ai un meilleur modèle mental de la façon dont cela fonctionne, et une référence rapide pour quand j'oublie certains détails.)

94
répondu waldyrious 2016-11-04 13:54:10
la source

ce fil est un peu vieux, mais je veux encore 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 -q ) donne un avertissement sur le fichier modifié et son code de sortie est 1 qui sera considéré comme une erreur dans un script.

Edit: git checkout HEAD to-be-modified to-be-removed fonctionne aussi pour unsaging, mais supprime complètement le changement de l'espace de travail

38
répondu Daniel Alder 2018-03-04 10:27:03
la source

si vous avez accidentellement mis en scène des fichiers que vous ne voudriez pas commettre, et que vous voulez être certain de garder les modifications, vous pouvez aussi utiliser:

git stash
git stash pop

ceci effectue une réinitialisation à la tête et ré-applique vos modifications, vous permettant de re-mettre en scène des fichiers individuels pour commit. c'est également utile si vous avez oublié de créer une branche pour tirer des demandes ( git stash ; git checkout -b <feature> ; git stash pop ).

27
répondu ives 2015-09-17 04:26:28
la source

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 (déjà engagé etc.):

  • git reset HEAD <file> décompose le fichier dans la propagation courante.
  • git rm --cached <file> dégrafera le fichier pour les futures commits aussi. Il est intact jusqu'à ce qu'il soit ajouté à nouveau avec git add <file> .

et il y a une autre différence importante:

  • après avoir lancé git rm --cached <file> et avoir poussé votre branche vers la télécommande, quiconque retirera votre branche de la télécommande récupérera le fichier réellement supprimé de son dossier, même si dans votre jeu de travail local le fichier devient tout simplement introuvable (c'est-à-dire non physiquement supprimé du dossier).

cette dernière différence est importante pour les projets qui comprennent un fichier de configuration où chaque développeur de l'équipe a une configuration différente (c'est-à-dire une url de base, une ip ou un port différents) donc si vous utilisez git rm --cached <file> , quiconque tire votre branche devra recréer manuellement la configuration, ou vous pouvez lui envoyer la vôtre et il pourra la ré-éditer à ses paramètres ip (etc.), parce que la suppression n'affecte que les personnes qui tirent votre branche de la télécommande.

15
répondu DrewT 2014-08-19 08:10:06
la source

disons que vous stage un répertoire entier via git add <folder> , mais vous voulez exclure un fichier de la liste mise en scène (c'est-à-dire la liste qui génère lors de l'exécution de git status ) et garder les modifications dans le fichier exclu (vous travailliez sur quelque chose et ce n'est pas prêt pour la propagation, mais vous ne voulez pas perdre votre travail...). Vous pouvez simplement utiliser:

git reset <file>

quand vous lancez git status , vous verrez que tout fichier(s) que vous reset sont unstaged et le reste des fichiers vous added sont encore dans le staged liste.

8
répondu jiminikiz 2015-08-28 19:08:05
la source

1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

(utiliser " git rm --cached ..."pour unstage)

  • git est un système de pointeurs

  • vous n'avez pas de commettre encore de changer le pointeur de votre souris

  • la seule façon de "retirer les fichiers du seau pointé vers" est de supprimer les fichiers que vous avez demandé à git de surveiller les changements

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

git commit -m a

  • vous engage, ' sauvé '

3.

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

(utiliser " Tête de réarmement git ..."pour unstage)

  • vous avez fait un commit dans votre code en ce moment
  • maintenant vous pouvez réinitialiser votre pointeur à votre commit ' revenir à la dernière enregistrer '
7
répondu Timothy L.J. Stewart 2016-09-08 19:26:07
la source

je suis surpris que personne n'ait mentionné le git refrog ( http://git-scm.com/docs/git-reflog ):

# git reflog
<find the place before your staged anything>
# git reset [email protected]{1}

le refrog est un historique git qui non seulement suit les changements à la repo, mais aussi les actions de l'utilisateur (par ex. tirer, passer à une autre branche, etc) et permet d'annuler les actions. Donc, au lieu de déballer le fichier qui a été mis en scène par erreur, où vous pouvez revenir au point où vous n'avez pas mis en scène les fichiers.

c'est similaire à git reset HEAD <file> mais dans certains cas peut être plus granulaire.

Désolé, pas vraiment répondre à votre question, mais il suffit de pointer encore une autre façon d'unstage fichiers que j'utilise assez souvent (j'ai pour l'une des réponses par Ryan Stewart et waldyrious très bien.) ;) J'espère que cela aide.

5
répondu Alex 2015-02-10 15:06:40
la source

il me semble que git rm --cached <file> supprime le fichier de l'index sans le supprimer du répertoire où un simple git rm <file> ferait les deux, tout comme un OS rm <file> supprimerait le fichier du répertoire sans supprimer son versioning.

3
répondu ernie.cordell 2014-01-24 14:55:30
la source

Autres questions sur git git-reset git-rm