8412 votes

Comment faire pour que Git oublie un fichier qui a été suivi, mais qui est maintenant dans .gitignore ?

Il y a un fichier qui était suivi par Git, mais maintenant le fichier est sur le .gitignore liste. Cependant, ce fichier continue à apparaître dans git status après qu'il ait été édité. Comment puis-je forcer Git à l'oublier complètement ?

31 votes

git clean -X semble similaire, mais elle ne s'applique pas dans cette situation (lorsque les fichiers sont encore suivis par Git). J'écris ceci pour que les personnes qui cherchent une solution ne suivent pas la mauvaise voie.

54 votes

La seule vraie réponse à cette question se trouve en bas, voir git update-index --assume-unchanged . Cette solution 1) conserve le fichier sur le serveur (index), 2) vous permet de le modifier librement en local.

18 votes

Vous devez utiliser --skip-worktree voir : stackoverflow.com/questions/13630849/

9048voto

Charles Bailey Points 244082

.gitignore empêchera les fichiers non suivis d'être ajoutés (sans l'option add -f ) à l'ensemble des fichiers suivis par Git. Cependant, Git continuera à suivre tous les fichiers qui sont déjà suivis.

Pour arrêter de suivre un fichier, vous devez le supprimer de l'index. Ceci peut être réalisé avec cette commande.

git rm --cached <file>

Si vous voulez supprimer un dossier entier, vous devez supprimer tous les fichiers qu'il contient de manière récursive.

git rm -r --cached <folder>

La suppression du fichier de la révision principale aura lieu lors de la prochaine livraison.

AVERTISSEMENT : Bien que cette opération ne supprime pas le fichier physique de votre machine locale, elle supprimera les fichiers des machines des autres développeurs sur leur prochain git pull .

81 votes

Le processus qui a fonctionné pour moi était 1. commiter les changements en attente d'abord 2. git rm --cached <file> et commiter à nouveau 3. ajouter le fichier à .gitignore, vérifier avec git status et commiter à nouveau

155 votes

Ajout très important. Si un fichier ignoré est modifié (mais ne doit pas être validé), après la modification et l'exécution de la commande git add . il serait ajouté à l'index. Et le prochain commit le commettrait dans le référentiel. Pour éviter cette exécution juste après tout ce que Mataal a dit une commande de plus : git update-index --assume-unchanged <path&filename>

7 votes

Le commentaire de mataal est très important. Commencez par valider les changements en attente, PUIS git rm --cached et validez à nouveau. Si le rm fait partie d'un autre commit, cela ne fonctionnera pas comme prévu.

3508voto

Matt Frear Points 6287

La série de commandes ci-dessous va supprimer tous les éléments de l'index Git (pas du répertoire de travail ou du dépôt local), puis va mettre à jour l'index Git, tout en respectant les ignorances Git. PS. Index = Cache

D'abord :

git rm -r --cached .
git add .

Ensuite :

git commit -am "Remove ignored files"

Ou en une phrase :

git rm -r --cached . && git add . && git commit -am "Remove ignored files"

1 votes

Il faudrait un peu plus d'explications, mais oui, c'était la meilleure solution à mon problème.

280 votes

Pour mettre en évidence la différence entre cette réponse et celle qui est acceptée : En utilisant cette commande, vous n'avez pas besoin de connaître les fichiers concernés. (Imaginez un répertoire temporaire avec beaucoup de fichiers aléatoires qui devraient être effacés de l'index).

90 votes

Identique à la réponse acceptée. Les fichiers seront supprimés le git pull .

1942voto

Konstantin Points 856

git update-index fait le travail pour moi :

git update-index --assume-unchanged <file>

Note : Cette solution est en fait indépendante de .gitignore car gitignore ne concerne que les fichiers non suivis.


Mise à jour, une meilleure option

Depuis que cette réponse a été postée, une nouvelle option a été créée et il convient de la privilégier. Vous devez utiliser --skip-worktree qui est pour les fichiers suivis modifiés que l'utilisateur ne veut plus commettre et conserver. --assume-unchanged pour les performances, afin d'empêcher git de vérifier le statut des gros fichiers suivis. Voir https://stackoverflow.com/a/13631525/717372 pour plus de détails...

git update-index --skip-worktree <file>

Pour annuler

git update-index --no-skip-worktree <file>

263 votes

Ce site IS la vraie réponse. Génial en fait, très simple, ne pollue pas. git status et en fait très intuitif. Merci.

4 votes

J'ai opté pour la bonne solution rm [...] . car au moins je pouvais comprendre comment cela fonctionnait. Je n'ai pas trouvé de grande documentation sur ce que update-index & --assume-unchanged faire. Quelqu'un peut-il ajouter comment cela se compare à l'autre, dans la mesure où je voudrais supprimer tous les fichiers qui auraient été ignorés ? (Ou un lien vers une explication claire ?)

34 votes

git update-index --assume-unchanged <path> … fera en sorte que git ignore les changements dans le(s) chemin(s) spécifié(s), sans tenir compte de l'option .gitignore . Si vous tirez à partir d'un site distant et que ce dernier a modifié ce chemin, git échouera la fusion avec un conflit et vous devrez fusionner manuellement. git rm --cached <path> … fera en sorte que git arrête de suivre ce chemin. Si vous n'ajoutez pas le chemin à .gitignore vous verrez le chemin à l'avenir git status . La première option a moins de bruit dans l'historique des commits git et permet aux modifications du fichier "ignoré" d'être distribuées dans le futur.

391voto

thSoft Points 5513
git ls-files -c --ignored --exclude-standard -z | xargs -0 git rm --cached
git commit -am "Remove ignored files"

Ceci prend la liste des fichiers ignorés, les supprime de l'index, et commet les changements.

7 votes

Si vous devez également les supprimer du répertoire de travail, il vous suffit de lancer la commande git ls-files --ignored --exclude-standard | xargs git rm . Je crois que cette réponse est la meilleure ! Parce qu'elle est très claire, à la manière d'Unix, et qu'elle fait la chose voulue de manière directe, sans composer les effets secondaires d'autres commandes plus complexes.

6 votes

Excellente réponse ; cependant, la commande échouera si vous avez des chemins avec des espaces au milieu, par ex : "Mon répertoire/mon_fichier_ignoré.txt"

8 votes

Git ls-files --ignored --exclude-standard | sed 's/.*/"&"/' | xargs git rm --cached

74voto

Seth Robertson Points 13276

Si vous ne pouvez pas git rm un fichier suivi parce que d'autres personnes pourraient en avoir besoin (avertissement, même si vous git rm --cached si quelqu'un d'autre reçoit ce changement, ses fichiers seront supprimés dans son système de fichiers). Ces modifications sont souvent dues à des remplacements de fichiers de configuration, à des identifiants d'authentification, etc. Veuillez consulter https://gist.github.com/1423106 pour savoir comment les gens ont contourné le problème.

Pour résumer :

  • Demandez à votre application de rechercher un fichier ignoré config-overide.ini et de l'utiliser à la place du fichier config.ini (ou alternativement, recherchez ~/.config/myapp.ini, ou $MYCONFIGFILE).
  • Livrer le fichier config-sample.ini et ignorer le fichier config.ini, faire copier le fichier par un script ou similaire si nécessaire.
  • Essayez d'utiliser la magie de gitattributes clean/smudge pour appliquer et supprimer les changements pour vous, par exemple smudge le fichier de configuration en tant que checkout depuis une branche alternative et clean le fichier de configuration en tant que checkout depuis HEAD. C'est un travail délicat, je ne le recommande pas aux utilisateurs novices.
  • Conservez le fichier de configuration sur une branche de déploiement qui lui est dédiée et qui n'est jamais fusionnée à master. Lorsque vous voulez déployer/compiler/tester, vous fusionnez avec cette branche et obtenez ce fichier. C'est essentiellement l'approche smudge/clean, sauf qu'elle utilise des politiques de fusion humaines et des modules extra-git.
  • Anti-recommentation : N'utilisez pas assume-unchanged, cela ne se terminera qu'en larmes (parce que faire mentir git à lui-même provoquera de mauvaises choses, comme la perte définitive de votre modification).

7 votes

Git ne supprimerait pas le fichier, s'il était sale au moment de la suppression. Et s'il n'est pas sale, la récupération du fichier serait aussi simple que git checkout <oldref> -- <filename> - mais alors il serait vérifié et ignoré.

0 votes

En ce qui concerne votre dernière note (sur --assume-unchanged ) : soit c'est du cargo cult et il faut le rejeter, soit vous pouvez expliquer pourquoi (ce dont je suis convaincu) et cela devient utile.

1 votes

@RomainValeri : "Git échouera (gracieusement) au cas où il aurait besoin de modifier ce fichier dans l'index, par exemple lors de la fusion d'un commit ; ainsi, au cas où le fichier supposé non suivi serait modifié en amont, vous devrez gérer la situation manuellement". git-scm.com/docs/git-update-index . Vous vous engagez à : (1) sauvegarder le fichier hors de l'arbre ; (2) réinitialiser le bit a.-u. ; (3) réinitialiser le fichier à son contenu original. git checkout -- file (4) git pull ou merge, qui va maintenant réussir ; (5) recopier le fichier et examiner les changements ; (6) remettre le bit a.-u. en place. C'est une définition de PITA dans mon livre, mais YMMV. :)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X