Faire en sorte que .gitignore ignore tout sauf quelques fichiers

1702

Je comprends qu'un fichier .gitignore masque les fichiers spécifiés du contrôle de version de Git. J'ai un projet (LaTeX) qui génère beaucoup de fichiers supplémentaires (.auth, .dvi, .pdf, logs, etc.) pendant son exécution, mais je ne veux pas que ceux-ci soient suivis.

Je suis conscient que je pourrais (devrait peut-être) faire en sorte que tous ces fichiers soient placés dans un sous-dossier séparé dans le projet, car je pourrais alors simplement ignorer le dossier.

Cependant, existe-t-il un moyen possible de conserver les fichiers de sortie à la racine de l'arborescence du projet et d'utiliser .gitignore pour ignorer tout sauf les fichiers que je suis avec Git? Quelque chose comme

# Ignore everything
*

# But not these files...
script.pl
template.latex
# etc...
Andrew
la source
12
Duplicata de stackoverflow.com/q/9162919/321973 (je sais que c'est plus récent, mais la réponse est plus correcte). En fait, cette réponse est probablement la meilleure
Tobias Kienzler

Réponses:

2444

Un préfixe facultatif !qui annule le modèle; tout fichier correspondant exclu par un modèle précédent sera à nouveau inclus. Si un modèle annulé correspond, cela remplacera les sources de modèles de priorité inférieure.

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# ...even if they are in subdirectories
!*/

# if the files to be tracked are in subdirectories
!*/a/b/file1.txt
!*/a/b/c/*
Joakim Elofsson
la source
14
Il semble que cela «ignore» également les sous-dossiers, de sorte que tous les fichiers nommés «script.pl» dans autre chose que le répertoire racine ne seront pas trouvés de toute façon. J'utilise ceci maintenant (avec * .pl) et tous les fichiers * .pl sont ignorés même s'il y en a beaucoup dans les sous-répertoires sous le fichier
.gitignore
38
@PandaWood Ce problème a été évoqué ici (stackoverflow.com). Cela est dû à la première expression correspondant à tout, y compris les répertoires, que vous ne niez jamais. Pour corriger, ajoutez (! * /), Qui correspond à tous les sous-répertoires (récursivement) du répertoire actuel. Cela n'aidera pas la réponse du parent, qui est la liste blanche de fichiers spécifiques (s'ils sont dans des sous-répertoires, vous voudrez probablement spécifier manuellement le chemin complet ou utiliser des fichiers .gitignore spécifiques au répertoire).
simont
40
Je n'ai pas pu faire fonctionner ça. J'ignore un dossier (par exemple wp/) mais je ne veux PAS ignorer certains fichiers au fond de ce dossier (par exemple wp/path/to/some/location/*). La seule façon de le faire fonctionner était de le fairegit add -f wp/path/to/some/location/*
trusktr
13
@trusktr Utiliser l' !*/exception de simont
Tobias Kienzler
7
Décidément cette dernière règle: !*/fait toute la différence dans mes tentatives futiles de faire en sorte qu'un .gitignorefichier fonctionne. Merci beaucoup.
racl101 du
630

Si vous souhaitez ignorer tout le contenu d'un répertoire, sauf un fichier à l'intérieur, vous pouvez écrire une paire de règles pour chaque répertoire dans le chemin du fichier. Par exemple .gitignore pour ignorer le dossier pippo sauf de pippo / pluto / paperino.xml

.gitignore

pippo/*
!pippo/pluto
pippo/pluto/*
!pippo/pluto/paperino.xml
Giuseppe Galano
la source
58
Excellente réponse, mais cela vaut la peine d'être noté pour tous ceux qui viendront plus tard fooet qui nefoo/* sont pas les mêmes. Pour que cela fonctionne, vous devez utiliser foo/*le dossier de base
thislooksfun
20
@ Mayank Pippo est Dingo en italien tandis que Paperino est Donald Duck et Pluton est le même qu'en anglais. Ils étaient autrefois un triplet très commun de noms de variables pour la programmation d'échantillons à l'époque. C'était agréable de les relire .. :)
Ghidello
Ce que @thislooksfun dit est important si vous voulez "exclure un dossier sauf le fichier x".
Czechnology
8
ne fonctionne pas pour moi: node_modules / *! node_modules / bootstrap
SuperUberDuper
1
@simple_human Ce serait vrai s'il ignorait tout dans la racine du référentiel, ou s'il avait un fichier .gitignore à prendre en compte, dans les répertoires mentionnés.
xZero
245

Vous souhaitez utiliser à la /*place *ou */dans la plupart des cas

L'utilisation *est valide, mais elle fonctionne récursivement. Il ne cherchera plus dans les répertoires à partir de ce moment. Les gens recommandent d'utiliser !*/à nouveau la liste blanche des répertoires, mais il est en fait préférable de mettre sur liste noire le dossier de plus haut niveau avec/*

# Blacklist files/folders in same directory as the .gitignore file
/*

# Whitelist some files
!.gitignore
!README.md

# Ignore all files named .DS_Store or ending with .log
**/.DS_Store
**.log

# Whitelist folder/a/b1/ and folder/a/b2/
# trailing "/" is optional for folders, may match file though.
# "/" is NOT optional when followed by a *
!folder/
folder/*
!folder/a/
folder/a/*
!folder/a/b1/
!folder/a/b2/
!folder/a/file.txt

# Adding to the above, this also works...
!/folder/a/deeply
/folder/a/deeply/*
!/folder/a/deeply/nested
/folder/a/deeply/nested/*
!/folder/a/deeply/nested/subfolder

Le code ci - dessus ne tiendrait pas compte de tous les fichiers à l' exception .gitignore, README.md, folder/a/file.txt, folder/a/b1/et folder/a/b2/et tout le contenu de ces deux derniers dossiers. (Et les fichiers .DS_Storeet *.logseraient ignorés dans ces dossiers.)

Évidemment, je pourrais faire par exemple !/folderou !/.gitignoretrop.

Plus d'informations: http://git-scm.com/docs/gitignore

Ryan Taylor
la source
3
Très intelligent, merci. OMI, c'est la meilleure façon de s'y prendre pour les sites WordPress avec le nombre minimum de règles d'inclusion. De plus, les nouveaux plugins, thèmes ou mises à jour WP ne sont pas supprimés ou ajoutés sans votre autorisation expresse. Lorsque j'utilise GitHub Desktop, je trouve que les .DS_Storefichiers ne sont pas ignorés, mais via la ligne de commande, ce n'est pas un problème. Pour contourner cela, j'ai dû déplacer les **/.DS_Storerègles ci - dessous.
Jibran
7
Mon surligneur de syntaxe interne a une réaction étrange au titre de votre message.
itsadok
3
Gracias! vous pouvez également mettre en liste blanche un fichier dans un dossier ..! /some/folder/file.txt
PodTech.io
Génial, utiliser / * au lieu de * a résolu tous mes problèmes lorsque les réponses ci-dessus ne l'ont pas été. Ma seule question est maintenant quelle est la différence entre! / Dossier et! / Dossier / *? Si j'utilise le dossier! / Sans le *, il reprend toujours les modifications apportées à tous les fichiers du dossier pour autant que je sache.
dallin
1
@dallin il n'y a pas de différence. L'un met en liste blanche un dossier et l'autre met en liste blanche les enfants de ce dossier, ce qui fait la même chose. Le seul problème est que le parent d'un dossier ou d'un fichier doit être mis sur liste blanche avant de pouvoir être mis sur liste blanche, donc vous ne pouvez pas faire /*ensuite !/nested/folder/*(ou l'équivalent !/nested/folder) sans faire !/nested/ou d' !/nestedabord! (et probablement /nested/*entre les deux). Une astuce à retenir est que si vous ajoutez à la liste blanche un sous-dossier profondément imbriqué, vous devez noircir complètement les enfants dans chaque sous-dossier, et ces listes noires se termineront par la "barre oblique" ...
Ryan Taylor
75

Un peu plus précis:

Exemple: Ignorez tout webroot/cache- mais gardez webroot/cache/.htaccess.

Remarquez la barre oblique (/) après le cachedossier:

ÉCHOUE

webroot/cache*
!webroot/cache/.htaccess

TRAVAUX

webroot/cache/*
!webroot/cache/.htaccess
Nik
la source
Si vous utilisez VS Code, veillez à ne pas lire mal la coloration du fichier après l'avoir appliqué à un dossier avec .gitkeep car le nom du dossier deviendra vert mais le fichier .gitkeep deviendra gris comme tous les autres fichiers ignorés; .gitkeep ressemblera à son ignoré mais vous devriez voir qu'il y a un 'U' sur le côté droit, indiquant qu'il a été détecté
OzzyTheGiant
55
# ignore these
*
# except foo
!foo
Suvesh Pratapa
la source
28

Pour ignorer certains fichiers d'un répertoire, vous devez le faire dans le bon ordre :

Par exemple, ignorez tout dans le dossier "application" sauf index.php et le dossier "config" faites attention à la commande .

Vous devez nier ce que vous voulez d'abord.

ÉCHOUE

application/*

!application/config/*

!application/index.php

TRAVAUX

!application/config/*

!application/index.php

application/*

slatunje
la source
38
Faux. Vous niez après le "tout ignorer".
Carlos
2
Ne vous laissez pas berner par git statusvérifier si vos changements .gitignorefonctionnent comme prévu
Philippe Rathé
10
Si git statusne va pas vous dire ce qu'il regarde et ce qui est ignoré, alors comment savoir si cela fonctionne?
kris
1
@kris Vider d'abord le cache git. Faites d'abord un "git rm --cached *" puis vous pouvez faire un "git add --all" puis un "état git" vous montrera toutes les nouvelles modifications de gitignore.
Mark McCorkle
20

Vous pouvez utiliser git config status.showUntrackedFiles noet tous les fichiers non suivis vous seront cachés. Voir man git-configpour plus de détails.

Robert Munteanu
la source
C'est génial si vous ne souhaitez valider que quelques fichiers sur plusieurs!
Josh M.
16

Pour exclure un dossier de .gitignore, les opérations suivantes peuvent être effectuées.

!app/

app/*
!app/bower_components/

app/bower_components/*
!app/bower_components/highcharts/

Cela ignorera tous les fichiers / sous-dossiers à l'intérieur à l' bower_componentsexception de /highcharts.

Guy Baskin
la source
14

Il y a un tas de questions similaires à ce sujet, donc je posterai ce que j'ai écrit avant:

La seule façon de faire fonctionner cela sur ma machine était de le faire de cette façon:

# Ignore all directories, and all sub-directories, and it's contents:
*/*

#Now ignore all files in the current directory 
#(This fails to ignore files without a ".", for example 
#'file.txt' works, but 
#'file' doesn't):
*.*

#Only Include these specific directories and subdirectories and files if you wish:
!wordpress/somefile.jpg
!wordpress/
!wordpress/*/
!wordpress/*/wp-content/
!wordpress/*/wp-content/themes/
!wordpress/*/wp-content/themes/*
!wordpress/*/wp-content/themes/*/*
!wordpress/*/wp-content/themes/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*
!wordpress/*/wp-content/themes/*/*/*/*/*

Remarquez comment vous devez autoriser explicitement le contenu pour chaque niveau que vous souhaitez inclure. Donc, si j'ai des sous-répertoires 5 sous les thèmes, je dois encore le préciser.

Ceci est du commentaire de @ Yarin ici: https://stackoverflow.com/a/5250314/1696153

Ces sujets étaient utiles:

J'ai aussi essayé

*
*/*
**/**

et **/wp-content/themes/**

ou /wp-content/themes/**/*

Rien de tout cela n'a fonctionné pour moi non plus. Beaucoup de traces et d'erreurs!

Katie
la source
2
C'est la seule méthode qui fonctionne pour inclure exclusivement certaines extensions de fichier. Encore mieux, cela fait un grand art ASCII: gist.github.com/Wolfgange3311999/91c671f5e4d3c56cf5a1
Matthew D. Scholefield
10

J'ai eu un problème avec le sous-dossier.

Ne marche pas:

/custom/*
!/custom/config/foo.yml.dist

Travaux:

/custom/config/*
!/custom/config/foo.yml.dist
Fabian Picone
la source
9

J'ai essayé toutes les réponses ci-dessus, mais aucune n'a fonctionné pour moi. Après avoir lu la documentation de gitignore ( ici ), j'ai découvert que si vous excluez d'abord un dossier, les noms de fichiers dans le sous-dossier ne sont pas indexés. Donc, si vous utilisez le point d'exclamation par la suite pour inclure un fichier, il ne se trouve pas dans l'index et n'est donc pas inclus dans votre client git.

C'était le moyen de trouver la solution. J'ai commencé par ajouter des exceptions pour tous les sous-dossiers de mon arborescence de dossiers pour le faire fonctionner, ce qui est un sacré travail. Par la suite, j'ai pu compacter la configuration détaillée dans la configuration ci-dessous, ce qui est un peu contraire à la documentation.

.Gitignore de travail:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' subfolder
/Pro/3rdparty/*
!Pro/3rdparty/domain/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

En conséquence, je vois dans mon client git que seuls les deux fichiers à l'intérieur du dossier Pro / 3rdparty / domain / modulename / sont mis en scène pour le prochain commit, et c'est exactement ce que je cherchais.

Et si vous devez ajouter à la liste blanche plusieurs sous-dossiers du même dossier, regroupez les lignes de point d'exclamation sous l'instruction exclude comme ceci:

# Ignore the 'Pro' folder, except for the '3rdparty' subfolder 
/Pro/*
!Pro/3rdparty/

# Ignore the '3rdparty' folder, except for the 'domain' & 'hosting' subfolders
/Pro/3rdparty/*
!Pro/3rdparty/domain/
!Pro/3rdparty/hosting/

# Ignore the 'domain' folder, except for the 'modulename' subfolder
Pro/3rdparty/domain/*
!Pro/3rdparty/domain/modulename/

# Ignore the 'hosting' folder, except for the 'modulename' subfolder
Pro/3rdparty/hosting/*
!Pro/3rdparty/hosting/modulename/

Sinon, cela ne fonctionnera pas comme prévu.

Tim B.
la source
Enfin une réponse qui a fonctionné. Je me demande quand je comprendrai comment .gitignore fonctionne réellement
David
8

C'est ce qui a fonctionné pour moi, je voulais engager un seul plugin Cordova dans le repo:

...
plugins/*
!plugins/cordova-plugin-app-customization
Dmitry Sokurenko
la source
8

Je sais que je suis en retard pour la fête, mais voici ma réponse.

Comme l'a dit @Joakim, pour ignorer un fichier, vous pouvez utiliser quelque chose comme ci-dessous.

# Ignore everything
*

# But not these files...
!.gitignore
!someFile.txt

mais si le fichier se trouve dans des répertoires imbriqués, il est un peu difficile d'écrire manuellement les règles.

Par exemple, si nous voulons ignorer tous les fichiers d'un gitprojet, mais pas ceux a.txtqui se trouvent dans aDir/anotherDir/someOtherDir/aDir/bDir/cDir. Ensuite, notre .gitignoresera quelque chose comme ça

# Skip all files
*

# But not `aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt`
!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Le .gitignorefichier donné ci-dessus sautera tous les répertoires et fichiers sauf!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Comme vous l'avez peut-être remarqué, il est difficile de définir ces règles.

Pour résoudre cet obstacle, j'ai créé une application console simple nommée git-do-not-ignore qui générera les règles pour vous. J'ai hébergé le projet dans github avec des instructions détaillées.

Exemple d'utilisation

java -jar git-do-not-ignore.jar "aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt"

Production

!aDir/
aDir/*
!aDir/anotherDir/
aDir/anotherDir/*
!aDir/anotherDir/someOtherDir/
aDir/anotherDir/someOtherDir/*
!aDir/anotherDir/someOtherDir/aDir/
aDir/anotherDir/someOtherDir/aDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/
aDir/anotherDir/someOtherDir/aDir/bDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/
aDir/anotherDir/someOtherDir/aDir/bDir/cDir/*
!aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

Il existe également une version Web simple disponible ici

Je vous remercie.

theapache64
la source
7

J'ai Jquery et Angular de bower. Bower les a installés dans

/public_html/bower_components/jquery/dist/bunch-of-jquery-files
/public_html/bower_components/jquery/src/bunch-of-jquery-source-files
/public_html/bower_components/angular/angular-files

Le jquery minimisé est à l'intérieur du distrépertoire et angular est à l'intérieur du angularrépertoire. Je n'avais besoin que de fichiers réduits pour être validés sur github. Quelques manipulations avec .gitignore et c'est ce que j'ai réussi à conjurer ...

/public_html/bower_components/jquery/*
!public_html/bower_components/jquery/dist
/public_html/bower_components/jquery/dist/*
!public_html/bower_components/jquery/dist/jquery.min.js
/public_html/bower_components/angular/*
!public_html/bower_components/angular/angular.min.js

J'espère que quelqu'un pourrait trouver cela utile.

Mario Legenda
la source
7

Voici comment je l'ai fait:

# Ignore everything
*

# Whitelist anything that's a directory
!*/

# Whitelist some files
!.gitignore

# Whitelist this folder and everything inside of it
!wordpress/wp-content/themes/my-theme/**

# Ignore this folder inside that folder
wordpress/wp-content/themes/my-theme/node_modules

# Ignore this file recursively
**/.DS_Store

Utilisez gig status -upour afficher les fichiers individuels dans les répertoires non suivis de manière récursive - avec git statusvous ne verriez que les dossiers, ce qui pourrait vous induire en erreur en pensant que tout ce qui s'y trouve a été suivi

zok
la source
5

Solution simple si vous devez tout ignorer sauf quelques fichiers et quelques dossiers racine :

/*
!.gitignore
!showMe.txt
!my_visible_dir

La magie est /*(comme décrit ci-dessus), elle ignore tout dans le dossier (racine) MAIS PAS récursivement.

d.raev
la source
4

J'ai également eu quelques problèmes avec la négation de fichiers uniques. J'ai pu les valider, mais mon IDE (IntelliJ) s'est toujours plaint des fichiers ignorés, qui sont suivis.

git ls-files -i --exclude-from .gitignore

Affichage des deux fichiers, que j'ai exclus de cette façon:

public/
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

En fin de compte, cela a fonctionné pour moi:

public/*
!public/typo3conf/
public/typo3conf/*
!public/typo3conf/LocalConfiguration.php
!public/typo3conf/PackageStates.php

La clé était d'abord la négation du dossier typo3conf/ .

De plus, il semble que l'ordre des déclarations n'a pas d'importance . Au lieu de cela, vous devez annuler explicitement tous les sous-dossiers, avant de pouvoir annuler des fichiers uniques.

Le dossier !public/typo3conf/et le contenu du dossier public/typo3conf/*sont deux choses différentes pour .gitignore.

Excellent fil! Ce problème m'a dérangé pendant un certain temps;)

Armin
la source
3

Jusqu'à présent, rien n'a fonctionné pour moi car j'essayais d'ajouter un pot de lib.

Cela n'a pas fonctionné:

build/*
!build/libs/*
!build/libs/
!build/libs/myjarfile.jar 

Cela a fonctionné:

build/*
!build/libs
Manish Bansal
la source
3

J'ai ce travail

# Vendor
/vendor/braintree/braintree_php/*
!/vendor/braintree/braintree_php/lib
raftaar1191
la source
2

Avait le même problème que OP mais aucune des 10 meilleures réponses votées n'a vraiment fonctionné .
J'ai finalement découvert ce qui suit

Mauvaise syntaxe:

*
!bin/script.sh

Syntaxe correcte:

*
!bin
!bin/script.sh

Explication de la page de manuel de gitignore :

Un préfixe optionnel "!" ce qui annule le motif; tout fichier correspondant exclu par un modèle précédent sera à nouveau inclus. Il n'est pas possible de ré-inclure un fichier si un répertoire parent de ce fichier est exclu . Git ne répertorie pas les répertoires exclus pour des raisons de performances, donc tous les modèles sur les fichiers contenus n'ont aucun effet, peu importe où ils sont définis.

Exemple étendu:

$ arbre.

.
├── .gitignore
└── bin
    ├── ignore.txt
    └── sub
        └── folder
            └── path
                ├── other.sh
                └── script.sh

$ cat .gitignore

*
!.gitignore
!bin
!bin/sub
!bin/sub/folder
!bin/sub/folder/path
!bin/sub/folder/path/script.sh

$ git status --untracked-files --ignored

On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
        .gitignore
        bin/sub/folder/path/script.sh

Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
        bin/ignore.txt
        bin/sub/folder/path/other.sh

nothing added to commit but untracked files present (use "git add" to track)
frntn
la source
1

Essentiel

# Ignore everything
*

# But not these files...
!script.pl
!template.latex

Et probablement inclure:

!.gitignore

Référence

Depuis https://git-scm.com/docs/gitignore :

Un préfixe facultatif " !" qui annule le modèle; tout fichier correspondant exclu par un modèle précédent sera à nouveau inclus. Il n'est pas possible de ré-inclure un fichier si un répertoire parent de ce fichier est exclu. Git ne répertorie pas les répertoires exclus pour des raisons de performances, donc tous les modèles sur les fichiers contenus n'ont aucun effet, peu importe où ils sont définis. Mettez une barre oblique inversée (" \") devant le premier " !" pour les motifs qui commencent par un " !" littéral , par exemple, " \!important!.txt".

...

Exemple pour tout exclure sauf un répertoire spécifique foo/bar(notez le /*- sans la barre oblique, le caractère générique exclurait également tout ce qu'il contient foo/bar):

$ cat .gitignore
# exclude everything except directory foo/bar
/*
!/foo
/foo/*
!/foo/bar
Will Cain
la source
0

Il me semble avoir trouvé quelque chose qui a fonctionné pour moi et que personne d'autre n'a mentionné.

# Ignore everything
*

# But not these files...
!.gitignore
!script.pl
!template.latex
# etc...

# And if you want to include a sub-directory and all sub-directory and files under it, but not all sub-directories
!subdir/
!subdir/**/*

Fondamentalement, cela semble empêcher un sous-répertoire d'être ignoré, vous devez avoir deux entrées, une pour le sous-répertoire lui-même !subdir/, puis une autre qui s'étend à tous les fichiers et dossiers sous-jacents!subdir/**/*

Didier A.
la source