La réponse acceptée ne "fait pas oublier à Git " un fichier ... "(historiquement). Cela ne fait que git ignorer le fichier dans le présent / futur.
Cette méthode permet git oublier complètement les fichiers ignorés ( passé / présent / futur), mais ne pas rien de suppression du répertoire de travail (même lorsqu'il est tiré de nouveau à distance).
Cette méthode nécessite l'utilisation de /.git/info/exclude
(préféré) OU un préexistant .gitignore
dans tous les commits qui ont des fichiers à ignorer / oublier. 1
Toutes les méthodes d'application de git ignorent le comportement après coup réécrivent efficacement l'historique et ont donc des ramifications importantes pour tout dépôt public / partagé / collaboratif qui pourrait être extrait après ce processus. 2
Conseil général: commencez par un dépôt propre - tout est validé, rien en attente dans le répertoire de travail ou l'index, et faites une sauvegarde !
De plus, l' historique des commentaires / révisions de cette réponse ( et l'historique des révisions de cette question ) peut être utile / éclairant.
#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"
#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached
#Commit to prevent working directory data loss!
#this commit will be automatically deleted by the --prune-empty flag in the following command
#this command must be run on each branch
git commit -m "ignored index"
#Apply standard git ignore behavior RETROACTIVELY to all commits from all branches (--all)
#This step WILL delete ignored files from working directory UNLESS they have been dereferenced from the index by the commit above
#This step will also delete any "empty" commits. If deliberate "empty" commits should be kept, remove --prune-empty and instead run git reset HEAD^ immediately after this command
git filter-branch --tree-filter 'git ls-files -z --ignored --exclude-standard | xargs -0 git rm -f --ignore-unmatch' --prune-empty --tag-name-filter cat -- --all
#List all still-existing files that are now ignored properly
#if this command returns nothing, it's time to restore from backup and start over
#this command must be run on each branch
git ls-files --other --ignored --exclude-standard
Enfin, suivez le reste de ce guide GitHub (à partir de l'étape 6) qui comprend des avertissements / informations importants sur les commandes ci-dessous .
git push origin --force --all
git push origin --force --tags
git for-each-ref --format="delete %(refname)" refs/original | git update-ref --stdin
git reflog expire --expire=now --all
git gc --prune=now
Les autres développeurs qui tirent du référentiel distant maintenant modifié devraient faire une sauvegarde, puis:
#fetch modified remote
git fetch --all
#"Pull" changes WITHOUT deleting newly-ignored files from working directory
#This will overwrite local tracked files with remote - ensure any local modifications are backed-up/stashed
git reset FETCH_HEAD
Notes de bas de page
1 Puisqu'il /.git/info/exclude
peut être appliqué à toutes les validations historiques en utilisant les instructions ci-dessus, les détails sur la manière d'obtenir un .gitignore
fichier dans les validations historiques qui en ont besoin dépassent le cadre de cette réponse. Je voulais qu'un correct .gitignore
soit dans le commit racine, comme si c'était la première chose que je faisais. D'autres peuvent ne pas s'en soucier car /.git/info/exclude
peuvent accomplir la même chose, peu importe où il .gitignore
existe dans l'historique de validation, et la réécriture claire de l'histoire est un sujet très délicat, même en étant conscient des ramifications .
FWIW, les méthodes potentielles peuvent inclure git rebase
ou git filter-branch
copier un externe .gitignore
dans chaque commit, comme les réponses à cette question
2 L' application du comportement ignorer git après coup en validant les résultats d'une git rm --cached
commande autonome peut entraîner une suppression de fichier nouvellement ignorée lors de futures extractions de la télécommande forcée. L' --prune-empty
indicateur dans la git filter-branch
commande suivante évite ce problème en supprimant automatiquement la validation d'index uniquement "supprimer tous les fichiers ignorés" précédente. La réécriture de l'historique de git modifie également les hachages de validation, ce qui fera des ravages sur les futurs tirages des dépôts publics / partagés / collaboratifs. Veuillez bien comprendre les ramifications avant de procéder à un tel dépôt. Ce guide GitHub spécifie les éléments suivants:
Dites à vos collaborateurs de rebaser , et non de fusionner, toutes les branches qu'ils ont créées à partir de votre ancien historique (corrompu) du référentiel. Un commit de fusion pourrait réintroduire une partie ou la totalité de l'historique entaché que vous venez de prendre la peine de purger.
Des solutions alternatives qui n'affectent pas le dépôt à distance sont git update-index --assume-unchanged </path/file>
ou git update-index --skip-worktree <file>
, dont des exemples peuvent être trouvés ici .
git clean -X
semble similaire, mais il ne s'applique pas dans cette situation (lorsque les fichiers sont toujours suivis par Git). J'écris ceci pour quiconque cherche une solution pour ne pas suivre la mauvaise route.