web-dev-qa-db-fra.com

Faire en sorte que .gitignore ignore tout sauf quelques fichiers

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

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

Cependant, existe-t-il un moyen réaliste de conserver les fichiers de sortie à la racine de l'arborescence du projet et d'utiliser .gitignore pour tout ignorer, à l'exception des fichiers que je suis en train de suivre avec Git? Quelque chose comme

# Ignore everything
*

# But not these files...
script.pl
template.latex
# etc...
1447
Andrew

Un préfixe facultatif ! qui annule le motif; tout fichier correspondant exclu par un modèle précédent sera à nouveau inclus. Si un motif négatif correspond, cela remplacera les sources de motifs 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/*
2072
Joakim Elofsson

Si vous souhaitez ignorer tout le contenu d'un répertoire, à l'exception d'un fichier, 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 à l'exception de pippo/pluto/paperino.xml

.gitignore

pippo/*
!pippo/pluto
pippo/pluto/*
!pippo/pluto/paperino.xml
568
Giuseppe Galano

Vous voulez utiliser /* au lieu de * ou */ dans la plupart des cas

Utiliser * est valide, mais cela fonctionne de manière récursive. Il ne regardera plus dans les répertoires. Les gens recommandent d’utiliser !*/ pour ajouter de nouveau des répertoires à la liste blanche, mais il est en fait préférable de placer le dossier de niveau le plus élevé avec la liste noire 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 ignorerait tous les fichiers sauf .gitignore, README.md, folder/a/file.txt, folder/a/b1/ et folder/a/b2/ et tout ce qui se trouve dans ces deux derniers dossiers. (Et les fichiers .DS_Store et *.log seraient ignorés dans ces dossiers.)

Évidemment je pourrais faire par exemple !/folder ou !/.gitignore aussi.

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

204
Ryan Taylor

Un peu plus précis:

Exemple: Tout ignorer dans webroot/cache - mais conservez webroot/cache/.htaccess.

Notez la barre oblique (/) après le dossier cache:

ÉCHOUE

webroot/cache*
!webroot/cache/.htaccess

FONCTIONNE

webroot/cache/*
!webroot/cache/.htaccess
68
Nik
# ignore these
*
# except foo
!foo
53
Suvesh Pratapa

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

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

Vous devez d'abord nier ce que vous voulez.

ÉCHOUE

application/*

!application/config/*

!application/index.php

FONCTIONNE

!application/config/*

!application/index.php

application/*

25
slatunje

Vous pouvez utiliser git config status.showUntrackedFiles no et tous les fichiers non suivis seront masqués. Voir man git-config pour plus de détails.

19
Robert Munteanu

Pour exclure un dossier de .gitignore, vous pouvez effectuer les opérations suivantes.

!app/

app/*
!app/bower_components/

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

Ceci ignorera tous les fichiers/sous-dossiers de bower_components à l'exception de /highcharts.

14
Guy Baskin

Il y a beaucoup de questions similaires à ce sujet, je vais donc poster ce que j'ai écrit auparavant:

La seule façon pour moi que cela fonctionne 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/*/*/*/*/*

Notez que vous devez autoriser explicitement le contenu pour chaque niveau que vous souhaitez inclure. Donc, si j'ai des sous-répertoires 5 profonds sous thèmes, je dois quand même le préciser.

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

Ce sont des sujets 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 piste et d'erreur!

13
Katie

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
9
Fabian Picone

C'est ce qui a fonctionné pour moi. Je voulais engager un seul plugin Cordova dans le référentiel:

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

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

La requête réduite se trouve dans le répertoire dist et angular est dans le répertoire angular. Je n'avais besoin que de fichiers minimisés pour être envoyés à github. Quelques manipulations de .gitignore et c’est ce que j’ai réussi à évoquer ...

/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 pourra trouver cela utile.

7
Mario Legenda

J'ai essayé toutes les réponses données ci-dessus, mais aucune n'a fonctionné pour moi. Après avoir lu la documentation de gitignore ( here ), j’ai découvert que si vous excluez d’abord un dossier, les noms de fichiers du sous-dossier ne sont pas indexés. Donc, si vous utilisez le point d'exclamation pour inclure un fichier, celui-ci 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 afin de le faire fonctionner, ce qui est un sacré travail. Ensuite, j'ai pu compacter la configuration détaillée à la configuration ci-dessous, ce qui est un peu contraire à la documentation.

Travailler .gitignore:

# 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 du dossier Pro/3rdparty/domain/modulename/sont mis en scène pour le prochain commit, et c’est exactement ce que je recherchais.

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

# 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.

6
Tim B.

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

Comme @Joakim a dit, 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 est 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 projet git, mais pas a.txt qui se trouve dans aDir/anotherDir/someOtherDir/aDir/bDir/cDir. Ensuite, notre .gitignore ressemblera à ceci

# 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 fichier .gitignore donné ci-dessus ignorera tous les répertoires et fichiers sauf !aDir/anotherDir/someOtherDir/aDir/bDir/cDir/a.txt

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

Pour résoudre cet obstacle, j'ai créé une application console simple appelé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"

Sortie

!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

Une version Web simple est également disponible ici

Je vous remercie.

6
theapache64

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 -u pour afficher des fichiers individuels dans des répertoires non suivis de manière récursive. Avec git status, vous ne voyez que des dossiers, ce qui peut vous amener à penser que tout ce qui est à l'intérieur est suivi.

4
zok

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

/*
!.gitignore
!showMe.txt
!my_visible_dir

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

4
d.raev

J'ai également eu quelques problèmes avec la négation de fichiers individuels. J'ai pu les commettre, mais mon IDE (IntelliJ) s'est toujours plaint des fichiers ignorés, qui font l'objet d'un suivi.

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

Affiche les deux fichiers, que j'ai exclus de cette façon:

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

Finalement, cela a fonctionné pour moi:

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

La clé était la négation du dossiertypo3conf/ en premier.

En outre, il semble que l'ordre des déclarations importe pe. Au lieu de cela, vous devez explicitement nier tous les sous-dossiers avant de pouvoir nier des fichiers uniques.

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

Grand fil! Cette question m'a dérangé pendant un moment;)

3
Armin

Rien n’a fonctionné pour moi jusqu’à présent car j’essayais d’ajouter un bocal de lib.

Cela n'a pas fonctionné:

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

Cela a fonctionné:

build/*
!build/libs
3
Manish Bansal

J'ai ce travail

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

Il semble que j'ai 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, il 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 étend tous les fichiers et dossiers en dessous !subdir/**/*

0
Didier A.