gitignore: ignorer tous les fichiers dans la hiérarchie des dossiers sauf un type de fichier spécifique

je voudrais ignorer tous les fichiers ci-dessous et dans un dossier à l'exception d'un type de fichier spécifique qui pourrait être quelque part dans la hiérarchie des dossiers:

exemple

/Test
/Test/unknown/folder/structure/below

maintenant je voudrais ignorer tous les fichiers dans et sous le dossier Test sauf un certain fichier css nommé layout.css , par exemple:

/Test/layout.css
/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/layout.css
/Test/in/a/unknown/folder/ignore.me

.gitignore devrait ignorer

/Test/fileto.ignore
/Test/another/folder/ig.nore
/Test/in/a/unknown/folder/ignore.me

My .le fichier gitignore ne fonctionne pas:

Test/
!layout.css

des suggestions?

24
demandé sur Cœur 2011-10-18 11:16:09

3 réponses

j'ai pu faire fonctionner votre exemple en mettant un fichier .gitignore dans le répertoire Test/ avec les contenus suivants.

*
!*/
!.gitignore
!layout.css
26
répondu David Alber 2011-10-18 08:07:05

pour accomplir ce que vous voulez, vous aurez besoin d'utiliser quelques exclusions négatives.

l'idée de base est que vous devez exclure chaque répertoire parent de n'importe quel fichier que vous voulez unignored.

Donc, si vous voulez /Test/en/un/inconnu/dossier/mise en page.css d'être ajouté à votre repo git, alors vous aurez à unignore /Test/, /Test/en/, /Test/en/a/, /Test/en/un/inconnu/, et /Test/en/un/inconnu/dossier/.

alors, quand vous pour finir, accédez au répertoire avec quelques fichiers ignorés et quelques fichiers non marqués, vous devrez spécifier chacun individuellement comme suit:

# Fille: .gitignore
!Test/
Test/*
!Test/layout.css
Test/fileto.ignore
!Test/another/
Test/another/*
!Test/another/folder/
Test/another/folder/*
!Test/in/
Test/in/*
!Test/in/a/
Test/in/a/*
!Test/in/a/unknown/
Test/in/a/unknown/*
!Test/in/a/unknown/folder/
Test/in/a/unknown/folder/ignore.me
!Test/in/a/unknown/folder/layout.css

donc quand vous lancerez $ git add-all vous verrez les résultats souhaités:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   .gitignore
    new file:   Test/in/a/unknown/folder/layout.css
    new file:   Test/layout.css

Note: Vous pouvez trouver une explication de pourquoi git add-all est la meilleure façon d'ajouter des fichiers à un git repo à http://lexsheehan.blogspot.com/2014/05/git-add-update.html

11
répondu l3x 2015-02-12 23:13:41

question assez vieille mais puisque je me débattais avec cette question même maintenant j'ai pensé que je partagerais la solution réelle au problème.

la chose est que tant que vous ne pouvez pas propager des répertoires vides dans Git comme s'ils étaient ignorés, cette règle ne s'applique pas à .gitignore .

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

Une fuite "/**" correspond à tout à l'intérieur . Par exemple, " abc/**" correspond à tous les fichiers dans le répertoire "abc", relatif à l'emplacement de le. dossier gitignore, avec une profondeur infinie.

un slash suivi de deux astérisques consécutifs puis un slash matches zéro ou plus de répertoires. Par exemple, "/**/b" correspond à "a/b", "a/x/b", "a/x/y/b" et ainsi de suite.

** Correspond tout à l'intérieur - litéralement tout les fichiers ET les répertoires.

ce nous amène à un autre point dans gitignore docs:

Un préfixe facultatif "!"qui annule le motif; tout fichier correspondant exclu par un schéma antérieur sera de nouveau inclus. il n'est pas possible de ré-inclure un fichier si un répertoire parent du fichier est exclure. Git ne Liste pas les répertoires exclus pour la performance raisons, de sorte que tous les modèles sur les fichiers contenus n'ont aucun effet, peu importe où elles sont définies. Mettre un barre oblique inverse ("\") en face de la première "!"pour les modèles qui commencent par un caractère "!", exemple, "!important!.txt".

si le motif se termine par une barre oblique, elle est enlevée aux fins de la suivant la description, mais il ne trouverait une correspondance avec un répertoire. En d'autres termes, foo / va correspondre à un répertoire foo et des chemins en dessous, mais ne peut pas correspondre à un fichier ou un lien symbolique foo (ceci est cohérent avec la façon dont pathspec fonctionne en général dans Git.)

maintenant, disons que nous avons une structure dir suivante:

/path/to/git/repo
|-- .gitignore
|-- /cache
    |-- somefile
    |-- README    
    |-- /dir
        |-- somefile2
        |-- README

et nous voulons ignorer tous les fichiers à l'intérieur de cache/ sauf les fichiers README.

si nous spécifions gitignore comme ceci:

/cache/**
!README

Git ignorera tout sauf /cache/README . L'autre README n'apparaîtra pas parce que son répertoire /cache/dir a été exclu avec /cache/** et !README ne sera pas même s'appliquer à elle. Pour résoudre le problème, nous devons spécifier gitignore comme ceci:

# Ignore everything inside cache/ dir
/cache/**
# Except for subdirectories(won't be commited anyway if there is no commited file inside)
!/cache/**/
# And except for README files
!README
7
répondu Aleksander Stelmaczonek 2016-12-13 00:54:02