Comment puis-je supprimer un fichier d'un référentiel Git?

1924

J'ai ajouté un fichier nommé "file1.txt"à un référentiel Git. Après cela, je l'ai validé, j'ai ajouté quelques répertoires appelés dir1et dir2et les ai validés dans le référentiel Git.

Maintenant , le dépôt actuel a "file1.txt", dir1et dir2. Comment puis-je supprimer "file1.txt"sans affecter les autres, comme dir1et dir2?

webminal.org
la source
85
git rmest la bonne réponse, mais rappelez-vous que le fichier sera toujours là dans l'historique. Si vous souhaitez supprimer un fichier car il contenait des informations sensibles, vous devrez faire quelque chose de plus radical. (Changer l'historique, en particulier pour le contenu que vous avez déjà poussé, est une action drastique et devrait être évitée si possible.)
Keith Thompson
8
Remarque: sur GitHub, vous pouvez désormais supprimer directement un fichier de l'interface Web (sans même avoir à cloner le dépôt). Voir ma réponse ci-dessous .
VonC
4
@KeithThompson quelles étapes cela pourrait-il être si je veux désespérément le faire?
lessthanl0l
5
@ lessthanl0l: stackoverflow.com/q/872565/827263
Keith Thompson
connexes help.github.com/articles/...
Trevor Boyd Smith

Réponses:

3225

Utilisez git rm.

Si vous souhaitez supprimer le fichier du référentiel Git et du système de fichiers , utilisez:

git rm file1.txt
git commit -m "remove file1.txt"

Mais si vous souhaitez supprimer le fichier uniquement du référentiel Git et non le supprimer du système de fichiers, utilisez:

git rm --cached file1.txt
git commit -m "remove file1.txt"

Et pour pousser les modifications au repo à distance

git push origin branch_name  
Greg Hewgill
la source
93
Aussi pratique: git rm -r directory // Pour supprimer le répertoire et le contenu
Reg
10
Cela ne va cependant pas supprimer ce fichier dans d'autres validations.
VaTo
6
@SaulOrtega: C'est exact. Pour supprimer un fichier des validations précédentes (modification de l'historique passé), consultez la page d'aide de GitHub sur Supprimer les données sensibles .
Greg Hewgill
15
Notez que cela supprimera également le fichier localement. Si vous voulez seulement le supprimer du repo, faites: git rm --cached file1.txt
Weston Ganger
5
Il convient de noter que si ce fichier contient des informations sensibles (par exemple, les informations d'identification), vous devez modifier ces informations d'identification immédiatement . Pour citer GitHub "Une fois que vous avez poussé un commit vers GitHub, vous devez considérer que toutes les données qu'il contient sont compromises. Si vous avez validé un mot de passe, changez-le! Si vous avez validé une clé, générez-en un nouveau."
c1moore
608

git rm file.txtsupprime le fichier du référentiel mais le supprime également du système de fichiers local .

Pour supprimer le fichier du référentiel et ne pas le supprimer du système de fichiers local, utilisez:
git rm --cached file.txt

La situation exacte ci-dessous est celle où j'utilise git pour maintenir le contrôle de version du site Web de mon entreprise, mais le répertoire "mickey" était un dossier tmp pour partager du contenu privé avec un développeur CAO. Quand il avait besoin de fichiers ÉNORMES, j'ai créé un répertoire privé non lié et j'ai téléchargé les fichiers là-bas pour qu'il puisse les récupérer via le navigateur. Oubliant que je l'ai fait, j'ai ensuite effectué un à git add -Apartir du répertoire de base du site Web. Par la suite, a git statusmontré les nouveaux fichiers devant être validés. Maintenant, je devais les supprimer du suivi et du contrôle de version de git ...

L'exemple de sortie ci-dessous provient de ce qui m'est arrivé, où j'ai involontairement supprimé le .003fichier. Heureusement, je me fiche de ce qui est arrivé à la copie locale .003, mais certains des autres fichiers actuellement modifiés étaient des mises à jour que je viens d'apporter au site Web et il serait épique d'avoir été supprimés sur le système de fichiers local! "Système de fichiers local" = le site Web en direct (ce n'est pas une bonne pratique, mais c'est la réalité) .

[~/www]$ git rm shop/mickey/mtt_flange_SCN.7z.003
error: 'shop/mickey/mtt_flange_SCN.7z.003' has local modifications
(use --cached to keep the file, or -f to force removal)
[~/www]$ git rm -f shop/mickey/mtt_flange_SCN.7z.003
rm 'shop/mickey/mtt_flange_SCN.7z.003'
[~/www]$ 
[~/www]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    shop/mickey/mtt_flange_SCN.7z.003
#
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   shop/mickey/mtt_flange_SCN.7z.001
#   modified:   shop/mickey/mtt_flange_SCN.7z.002
[~/www]$ ls shop/mickey/mtt_flange_S*
shop/mickey/mtt_flange_SCN.7z.001  shop/mickey/mtt_flange_SCN.7z.002
[~/www]$ 
[~/www]$ 
[~/www]$ git rm --cached shop/mickey/mtt_flange_SCN.7z.002
rm 'shop/mickey/mtt_flange_SCN.7z.002'
[~/www]$ ls shop/mickey/mtt_flange_S*
shop/mickey/mtt_flange_SCN.7z.001  shop/mickey/mtt_flange_SCN.7z.002
[~/www]$ 
[~/www]$ 
[~/www]$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   deleted:    shop/mickey/mtt_flange_SCN.7z.002
#   deleted:    shop/mickey/mtt_flange_SCN.7z.003
#
# Changed but not updated:
#   modified:   shop/mickey/mtt_flange_SCN.7z.001
[~/www]$

Mise à jour: Cette réponse obtient un peu de trafic, j'ai donc pensé que je mentionnerais mon autre réponse Git partage quelques bonnes ressources: Cette page a un graphique qui aide à démystifier Git pour moi. Le livre "Pro Git" est en ligne et m'aide beaucoup.

Chris K
la source
6
Vous devrez ensuite valider cela avec quelque chose comme git commit -m "Just removing file1.txt", puis, si vous avez un référentiel distant, pousser la validation avec quelque chose comme git push origin master.
ban-geoengineering
77

Tout d'abord, si vous utilisez git rm, en particulier pour plusieurs fichiers, pensez que tout caractère générique sera résolu par le shell, et non par la gitcommande.

git rm -- *.anExtension
git commit -m "remove multiple files"

Mais, si votre fichier est déjà sur GitHub, vous pouvez (depuis juillet 2013) le supprimer directement de l'interface graphique Web!

Affichez simplement n'importe quel fichier dans votre référentiel, cliquez sur l'icône de la corbeille en haut et validez la suppression comme n'importe quelle autre modification Web.

Ensuite, " git pull" sur votre dépôt local, et cela supprimera également le fichier localement.
Qu'est-ce qui fait de cette réponse un moyen (détourné) de supprimer un fichier du git repo?
(Sans oublier qu'un fichier sur GitHub est dans un "git repo")


bouton supprimer

(le commit reflétera la suppression de ce fichier):

valider une suppression

Et juste comme ça, c'est parti.

Pour obtenir de l'aide sur ces fonctionnalités, assurez-vous de lire nos articles d'aide sur la création , le déplacement , le changement de nom et la suppression de fichiers.

Remarque: Étant donné qu'il s'agit d'un système de contrôle de version, Git a toujours votre dos si vous avez besoin de récupérer le fichier plus tard.

La dernière phrase signifie que le fichier supprimé fait toujours partie de l'historique, et vous pouvez le restaurer assez facilement (mais pas encore via l'interface Web GitHub):

Voir " Restaurer un fichier supprimé dans un référentiel Git ".

VonC
la source
4
Vous devez faire défiler vers le bas et appuyer sur "Valider les modifications" pour valider la suppression!
LevinsonTechnologies
1
Cela ne fonctionne pas pour les fichiers texte volumineux. Le serveur essaie de restituer le fichier comme dans la capture d'écran, puis échoue avec une erreur 500.
CapeCoder
9
Cette réponse fait référence à github, la question concerne un dépôt git. Pas comment utiliser l'interface github.
Peter Marshall
65

C'est la seule option qui a fonctionné pour moi.

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch *.sql'

Remarque: remplacez * .sql par votre nom ou type de fichier. Soyez très prudent car cela passera par chaque commit et arrachera ce type de fichier.

EDIT: faites attention - après cette commande, vous ne pourrez ni pousser ni tirer - vous verrez le rejet de «l'historique indépendant», vous pouvez utiliser «git push --force -u origin master» pour pousser ou tirer

Jason Glisson
la source
9
C'est une excellente réponse, mais notez que contrairement aux autres réponses, cette commande réécrit l'historique de validation et supprime toute trace des fichiers correspondant au modèle. Ceci est particulièrement utile si vous avez trouvé que vous avez accidentellement commis des informations sensibles (et, si nécessaire, pouvez utiliser avec succès --force pour réécrire l'historique de tous les dépôts distants vers lesquels vous avez été poussé).
yoniLavi
3
C'était exactement le problème que j'avais et il a fallu des essais et des erreurs pour bien faire les choses. Un gars avec qui je travaillais avait commis plusieurs gros vidages de base de données dans un référentiel en passant par de nombreux commits. C'est pourquoi j'ai utilisé .sql dans mon exemple. Mon repo est devenu tellement gonflé et grand que Github n'accepterait plus de push.
Jason Glisson
3
Si vous utilisez un maître distant, vous devez forcer un commit et le pousser avecgit push --force -u origin master
AlbertMarkovski
2
@AlbertMarkovski Désolé, je n'étais pas spécifique. Github n'accepterait en fait pas la poussée parce que le dépôt était au-delà de leur taille limite. Au moins plusieurs Go. Ils m'ont interrompu et m'ont envoyé un courriel à ce sujet. Donc, malheureusement, aucune force de poussée ne serait utile à ce stade.
Jason Glisson
2
@JasonGlisson J'ai également rencontré ce problème où une vidéo a été ajoutée à un référentiel par accident.
AlbertMarkovski
34

De plus, s'il s'agit d'un dossier à supprimer et qu'il s'agit de dossiers ou de fichiers enfants ultérieurs, utilisez:

git rm -r foldername
Raja
la source
2
Cela supprime également le dossier du local! Use git rm --cached -r <foldername>
Axe
24

Plus généralement, git helpaidera avec au moins des questions simples comme celle-ci:

zhasper@berens:/media/Kindle/documents$ git help
usage: git [--version] [--exec-path[=GIT_EXEC_PATH]] [--html-path] [-p|--paginate|--no-pager] [--bare] [--git-dir=GIT_DIR] [--work-tree=GIT_WORK_TREE] [--help] COMMAND [ARGS]

The most commonly used git commands are:
   add        Add file contents to the index
   :
   rm         Remove files from the working tree and from the index
James Polley
la source
6
Pour les choses plus complexes, je trouve git helpconfus, mais c'est bon pour les choses simples :)
James Polley
9
Ce n'est pas vraiment génial pour git noobs car "index" n'est pas un concept avec lequel git noobs est familier. Je parle d'expérience personnelle d'être un git noob :) De plus, je pense qu'il est beaucoup moins déroutant de dire que le rm fichier est supprimé plutôt que supprimé de l'index (bien que cela n'a toujours aucun sens pour les noobs).
Roman Starkov
D'accord avec romkyns: La description "Supprimer des fichiers de l'arborescence de travail et de l'index" ne me semble pas comme si c'était un moyen de supprimer le fichier du dépôt. Peut-être que si je comprenais mieux ce serait. Au lieu de cela, il semble que vous supprimiez simplement les fichiers (et les supprimez éventuellement de l'arborescence de travail - cela affecterait-il nécessairement le
dépôt
14

Si vous souhaitez supprimer le fichier du référentiel, mais le laisser dans le système de fichiers (ne sera pas suivi):

bykov@gitserver:~/temp> git rm --cached file1.txt
bykov@gitserver:~/temp> git commit -m "remove file1.txt from the repo"

Si vous souhaitez supprimer le fichier du référentiel et du système de fichiers, il existe deux options:

  1. Si le fichier ne comporte aucune modification dans l'index:

    bykov@gitserver:~/temp> git rm file1.txt
    bykov@gitserver:~/temp> git commit -m "remove file1.txt"
    
  2. Si le fichier comporte des modifications dans l'index:

    bykov@gitserver:~/temp> git rm -f file1.txt
    bykov@gitserver:~/temp> git commit -m "remove file1.txt"
    

la source
12

git rm ne supprimera désormais que le fichier de cette branche, mais il restera dans l'historique et git s'en souviendra.

La bonne façon de le faire est avec git filter-branch, comme d'autres l'ont mentionné ici. Il réécrira chaque commit dans l'historique de la branche pour supprimer ce fichier.

Mais, même après cela, git peut s'en souvenir car il peut y avoir des références dans reflog, télécommandes, balises et autres.

Si vous voulez l'effacer complètement en une seule étape, je vous recommande d'utiliser git forget-blob

https://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/

C'est facile, faites-le git forget-blob file1.txt.

Cela supprimera toutes les références, fera git filter-branch, et exécutera finalement le garbage collector git git gcpour se débarrasser complètement de ce fichier dans votre référentiel.

nachoparker
la source
10

Une autre façon si vous souhaitez supprimer le fichier de votre dossier local à l'aide de la commande rm, puis pousser les modifications sur le serveur distant.

rm file1.txt

git commit -a -m "Deleting files"

git push origin master
Suhaib
la source
10

Remarque: si vous souhaitez supprimer le fichier uniquement de git, utilisez ci-dessous:

git rm --cached file1.txt

Si vous souhaitez également supprimer du disque dur:

git rm file1.txt

Si vous souhaitez supprimer un dossier (le dossier peut contenir quelques fichiers), vous devez donc le supprimer à l'aide de la commande récursive, comme ci-dessous:

git rm -r foldername

Si vous souhaitez supprimer un dossier dans un autre dossier

git rm -r parentFolder/childFolder

Ensuite, vous pouvez commitet pushcomme d'habitude. Cependant, si vous souhaitez récupérer un dossier supprimé, vous pouvez suivre ceci: récupérer des fichiers supprimés de git est possible.

Du doc:

git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>…​

OPTIONS

<file>…​

Files to remove. Fileglobs (e.g. *.c) can be given to remove all matching files. If you want Git to expand file glob characters, you

peut avoir besoin de leur échapper. Un nom de répertoire principal (par exemple dir pour supprimer dir / file1 et dir / file2) peut être donné pour supprimer tous les fichiers du répertoire, et récursivement tous les sous-répertoires, mais cela nécessite que l'option -r soit explicitement donnée. -f --force

Override the up-to-date check.

-n --dry-run

Don’t actually remove any file(s). Instead, just show if they exist in the index and would otherwise be removed by the command.

-r

Allow recursive removal when a leading directory name is given.

--

This option can be used to separate command-line options from the list of files, (useful when filenames might be mistaken for

options de ligne de commande). --cached

Use this option to unstage and remove paths only from the index. Working tree files, whether modified or not, will be left alone.

--ignore-inégalé

Exit with a zero status even if no files matched.

-q --quiet

git rm normally outputs one line (in the form of an rm command) for each file removed. This option suppresses that output.

En savoir plus sur le doc officiel.

Blasanka
la source
7

Pour supprimer un fichier spécifique

git rm filename

Pour nettoyer tous les fichiers non suivis d'un répertoire de manière récursive en une seule fois

git clean -fdx

Sitesh
la source
5

Si vous avez l'application GitHub pour Windows, vous pouvez supprimer un fichier en 5 étapes faciles:

  • Cliquez sur Sync.
  • Cliquez sur le répertoire où se trouve le fichier et sélectionnez votre dernière version du fichier.
  • Cliquez sur les outils et sélectionnez «Ouvrir un shell ici».
  • Dans le shell, tapez: "rm {filename}" et appuyez sur Entrée.
  • Validez la modification et resynchronisez.
jushusted
la source
5

Dans mon cas, j'ai essayé de supprimer le fichier sur github après quelques validations mais de l'enregistrer sur l'ordinateur

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch file_name_with_path' HEAD
git push --force -u origin master

et plus tard, ce fichier a été ignoré

OlegV
la source
3
  1. Tout d'abord, supprimez les fichiers du référentiel local.

    git rm -r nom_fichier

    ou, supprimez les fichiers uniquement du référentiel local mais du système de fichiers

    git rm - nom de fichier caché

  2. Deuxièmement, validez les modifications dans le référentiel local.

    git commit -m "unwanted files or some inline comments"   
    
  3. Enfin, mettez à jour / transférez les modifications locales dans le référentiel distant.

    git push 
    
Ajay Kumar
la source
cela supprimerait-il tout ce qui concerne le fichier ajouté et poussé accidentellement?
bapors le
1

J'ai essayé beaucoup des options suggérées et aucune ne semblait fonctionner (je n'énumérerai pas les différents problèmes). Ce que j'ai fini par faire, qui a fonctionné, était simple et intuitif (pour moi) était:

  1. déplacer l'ensemble du dépôt local ailleurs
  2. cloner à nouveau le dépôt du maître sur votre disque local
  3. recopiez les fichiers / dossier de votre copie originale dans # 1 dans le nouveau clone de # 2
  4. assurez-vous que le fichier volumineux problème est absent ou exclu dans le fichier .gitignore
  5. faire le git add / git commit / git push habituel
jacanterbury
la source
1

Après avoir supprimé le fichier du référentiel avec, git rmvous pouvez utiliser BFG Repo-Cleaner pour effacer complètement et facilement le fichier de l'historique du référentiel.

glisu
la source
0

J'ai des fichiers obj et bin qui ont accidentellement fait partie du référentiel que je ne veux pas polluer ma liste de 'fichiers modifiés'

Après avoir remarqué qu'ils étaient allés dans la télécommande, je les ai ignorés en les ajoutant à.gitignore

/*/obj
/*/bin

Le problème est qu'ils sont déjà dans la télécommande et lorsqu'ils sont modifiés, ils apparaissent comme modifiés et polluent la liste des fichiers modifiés.

Pour ne plus les voir, vous devez supprimer l'intégralité du dossier du référentiel distant.

Dans une invite de commande:

  1. CD dans le dossier repo (ie C:\repos\MyRepo)
  2. Je veux supprimer SSIS \ obj. Il semble que vous ne puissiez supprimer qu'au niveau supérieur, vous devez donc maintenant insérer un CD dans SSIS: (c.-à-d. C:\repos\MyRepo\SSIS)
  3. Tapez maintenant l'incantation magique git rm -r -f obj
    • rm = supprimer
    • -r = supprimer récursivement
    • -f = signifie force, parce que tu le penses vraiment
    • obj est le dossier
  4. Maintenant, lancez git commit -m "remove obj folder"

J'ai reçu un message alarmant disant que 13 fichiers ont été supprimés 315222 suppressions

Ensuite, parce que je ne voulais pas avoir à rechercher la ligne CMD, je suis allé dans Visual Sstudio et j'ai fait une synchronisation pour l'appliquer à la télécommande

Nick.McDermaid
la source
0

Si vous devez supprimer des fichiers d'une extension déterminée (par exemple, des fichiers compilés), vous pouvez procéder comme suit pour les supprimer tous en même temps:

git remove -f *.pyc
Sergi Ramón
la source
0

Selon la documentation .

git rm --cached giant_file

En ce qui concerne les données sensibles, il vaut mieux ne pas dire que vous avez supprimé le fichier, mais plutôt l'inclure dans le dernier commit connu:

0. Modifier le dernier commit

git commit --amend -CHEAD

Si vous souhaitez supprimer le fichier de tout l'historique git, selon la documentation, vous devez procéder comme suit:

1. Supprimez-le de votre historique local

git filter-branch --force --index-filter \ "git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" \  --prune-empty --tag-name-filter cat -- --all
# Replace PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA with the path to the file you want to remove, not just its filename
  1. N'oubliez pas d'inclure ce fichier dans .gitignore (S'il s'agit d'un fichier que vous ne voulez jamais partager (comme les mots de passe ...):
echo "YOUR-FILE-WITH-SENSITIVE-DATA" >> .gitignore
git add .gitignore
git commit -m "Add YOUR-FILE-WITH-SENSITIVE-DATA to .gitignore"

3. Si vous devez retirer de la télécommande

git push origin --force --all

4. Si vous devez également le supprimer des versions de balises:

git push origin --force --tags
Tomas Baran
la source