Lorsque vous utilisez
git rm --cached myfile
il ne supprime pas du système de fichiers local, ce qui est l'objectif. Mais si vous avez déjà versionné et validé le fichier, l'avez poussé dans un référentiel central et l'avez extrait dans un autre référentiel avant d'utiliser la commande, cela supprimera le fichier de ce système.
Existe-t-il un moyen de supprimer simplement le fichier de la gestion des versions sans le supprimer de tout système de fichiers?
Edit: Clarifié, j'espère.
git
version-control
gitignore
git-rm
Fletcher Moore
la source
la source
Réponses:
Je ne pense pas qu'un commit Git puisse enregistrer une intention comme "arrêter le suivi de ce fichier, mais ne le supprimez pas".
La mise en œuvre d'une telle intention nécessitera une intervention en dehors de Git dans tous les référentiels qui fusionnent (ou rebasent sur) un commit qui supprime le fichier.
Enregistrer une copie, appliquer la suppression, restaurer
La chose la plus simple à faire est probablement de dire à vos utilisateurs en aval d'enregistrer une copie du fichier, d'extraire votre suppression, puis de restaurer le fichier. S'ils tirent via rebase et "portent" des modifications au fichier, ils obtiendront des conflits. Pour résoudre de tels conflits, utilisez
git rm foo.conf && git rebase --continue
(si la validation en conflit comporte des modifications en plus de celles du fichier supprimé) ougit rebase --skip
(si la validation en conflit n'a été modifiée que sur le fichier supprimé).Restaurer le fichier comme non suivi après avoir extrait un commit qui le supprime
S'ils ont déjà récupéré votre validation de suppression, ils peuvent toujours récupérer la version précédente du fichier avec git show :
Ou avec git checkout (par commentaire de William Pursell; mais n'oubliez pas de le retirer de l'index!):
S'ils ont pris d'autres mesures depuis le retrait de votre suppression (ou s'ils tirent avec rebase dans une HEAD détachée), ils peuvent avoir besoin d'autre chose que
@{1}
. Ils pourraient utilisergit log -g
pour trouver le commit juste avant de retirer votre suppression.Dans un commentaire, vous mentionnez que le fichier que vous souhaitez «décompresser, mais conserver» est une sorte de fichier de configuration nécessaire à l'exécution du logiciel (directement à partir d'un référentiel).
Conserver le fichier par défaut et l'activer manuellement / automatiquement
S'il n'est pas totalement inacceptable de continuer à maintenir le contenu du fichier de configuration dans le référentiel, vous pourrez peut-être renommer le fichier suivi de (par exemple)
foo.conf
àfoo.conf.default
, puis indiquer à vos utilisateurs aprèscp foo.conf.default foo.conf
avoir appliqué la validation de changement de nom. Ou, si les utilisateurs utilisent déjà une partie existante du référentiel (par exemple un script ou un autre programme configuré par le contenu du référentiel (par exempleMakefile
ou similaire)) pour lancer / déployer votre logiciel, vous pouvez incorporer un mécanisme par défaut dans le lancement / processus de déploiement:Avec un tel mécanisme défaillant en place, les utilisateurs devraient être en mesure de tirer un commettras qui renomme
foo.conf
àfoo.conf.default
sans avoir à faire un travail supplémentaire. De plus, vous évitez d'avoir à copier manuellement un fichier de configuration si vous effectuez des installations / référentiels supplémentaires à l'avenir.La réécriture de l'historique nécessite de toute façon une intervention manuelle…
S'il est inacceptable de conserver le contenu dans le référentiel, vous voudrez probablement l'éliminer complètement de l'historique avec quelque chose comme
git filter-branch --index-filter …
. Cela revient à réécrire l'historique, ce qui nécessitera une intervention manuelle pour chaque branche / référentiel (voir la section «Récupération à partir de la rebase en amont» dans la page de manuel git rebase ). Le traitement spécial requis pour votre fichier de configuration serait juste une autre étape à effectuer lors de la récupération de la réécriture:Ignorez-le pour éviter la récurrence
Quelle que soit la méthode que vous utilisez, vous souhaiterez probablement inclure le nom du fichier de configuration dans un
.gitignore
fichier du référentiel afin que personne ne puisse àgit add foo.conf
nouveau par inadvertance (c'est possible, mais nécessite-f
/--force
). Si vous avez plus d'un fichier de configuration, vous pouvez envisager de les `` déplacer '' tous dans un seul répertoire et d'ignorer le tout (en `` déplaçant '', je veux dire changer l'endroit où le programme s'attend à trouver ses fichiers de configuration, et obtenir les utilisateurs (ou le mécanisme de lancement / déploiement) pour copier / déplacer les fichiers vers leur nouvel emplacement; vous ne voudriez évidemment pas git mv un fichier dans un répertoire que vous ignorerez).la source
--{,no-}assume-unchanged
est purement local: son état n'est pas directement enregistré dans les commits. Cela peut aider à empêcher un référentiel de valider de nouvelles modifications dans le fichier, mais il ne le supprime pas du contrôle de version. Si vous pouvez le définir pour tous vos référentiels pertinents, liés et non dénudés, cela peut améliorer votre situation, mais ce n'est pas quelque chose que vous pouvez directement pousser + tirer / rebaser dans d'autres référentiels connexes et non nus (en particulier ceux qui vous ne contrôlez pas, selon les commentaires de clarification du demandeur initial sur la question: voir «systèmes des gens» / «systèmes étrangers»).I do not think a Git commit can record an intention like “stop tracking this file, but do not delete it”.
- maintenant il peut, avecgit rm --cached foo.conf
J'ai eu le même problème cette semaine lorsque j'ai commis accidentellement, puis essayé de supprimer un fichier de construction d'un référentiel partagé, et ceci:
http://gitready.com/intermediate/2009/02/18/temporately-ignoring-files.html
a bien fonctionné pour moi et n'a pas été mentionné jusqu'à présent.
Pour supprimer le fichier qui vous intéresse du contrôle de version, utilisez toutes vos autres commandes comme d'habitude.
Si jamais vous avez voulu le remettre.
Edit: veuillez consulter les commentaires de Chris Johnsen et de KPM, cela ne fonctionne que localement et le fichier reste sous contrôle de version pour les autres utilisateurs s'ils ne le font pas également. La réponse acceptée donne des méthodes plus complètes / correctes pour gérer cela. Aussi quelques notes du lien si vous utilisez cette méthode:
la source
Pour supprimer le fichier de l'index, utilisez:
Cela ne devrait pas affecter votre copie locale ou celle de quelqu'un d'autre.
la source
reset
ne supprime le fichier de l'index que si le fichier n'est pas dans la validation HEAD actuelle, sinon il rétablit simplement la version d'index à la version HEAD actuelle.git rm --cached remove_file
git add .gitignore
git commit -m "Excluding"
la source
Après avoir exécuté la
git rm --cached
commande, essayez d'ajoutermyfile
au.gitignore
fichier (créez-en un s'il n'existe pas). Cela devrait dire à git d'ignorermyfile
.Le
.gitignore
fichier est versionné, vous devrez donc le valider et le pousser vers le référentiel distant.la source
Ma solution est de tirer sur l'autre copie de travail, puis de faire:
qui dit obtenir tous les chemins de fichiers dans le dernier commentaire et les extraire du parent de HEAD. Travail accompli.
la source
Les solutions ci-dessus fonctionnent correctement dans la plupart des cas. Cependant, si vous devez également supprimer toutes les traces de ce fichier (c'est-à-dire les données sensibles telles que les mots de passe), vous voudrez également le supprimer de tout votre historique de validation, car le fichier pourrait encore être récupéré à partir de là.
Voici une solution qui supprime toutes les traces du fichier de tout votre historique de validation, comme s'il n'avait jamais existé, tout en maintenant le fichier en place sur votre système.
https://help.github.com/articles/remove-sensitive-data/
Vous pouvez en fait passer à l'étape 3 si vous êtes dans votre référentiel git local et que vous n'avez pas besoin d'effectuer une analyse à sec. Dans mon cas, je n'avais besoin que des étapes 3 et 6, car j'avais déjà créé mon fichier .gitignore et j'étais dans le référentiel sur lequel je voulais travailler.
Pour voir vos modifications, vous devrez peut-être accéder à la racine GitHub de votre référentiel et actualiser la page. Naviguez ensuite à travers les liens pour accéder à un ancien commit qui avait autrefois le fichier, pour voir qu'il a maintenant été supprimé. Pour moi, le simple fait d'actualiser l'ancienne page de validation n'a pas montré le changement.
Cela avait l'air intimidant au début, mais vraiment, c'était facile et fonctionnait comme un charme! :-)
la source