web-dev-qa-db-fra.com

Liste blanche .gitignore sur le répertoire et son contenu

J'essaie d'ajouter le répertoire (et son contenu) à la liste blanche SupplierName dans le répertoire de mon fournisseur Zend Framework 2.

Le fichier .gitignore d'origine dans/vendor se présente comme suit:

# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*

J'aimerais maintenant ajouter à la liste blanche le répertoire SupplierName, ce qui ne devrait pas être trop difficile, pensais-je. J'ai lu la documentation sur gitignore et essayé les configurations suivantes:

Premier essai, ajoutez! SupplierName juste après le commentaire qui indique que je dois ajouter le chemin de la liste blanche ici.

# Add here the vendor path to be whitelisted
!SupplierName
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*

Juste après, j'ai exécuté git status qui n'affichait pas le répertoire vendor/SupplierName. git add vendor/SupplierName a montré le message suivant: 

Les chemins suivants sont ignorés par l’un de vos fichiers .gitignore: vendor/SupplierName

Deuxième essai

# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!SupplierName
!.gitignore
*

Juste après, j'ai exécuté git status qui n'affichait pas le répertoire vendor/SupplierName. git add vendor/SupplierName a montré le message suivant: 

Les chemins suivants sont ignorés par l’un de vos fichiers .gitignore: vendor/SupplierName

Troisième essai

# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
!.gitignore
*
!SupplierName

Juste après, j'ai exécuté git status qui n'affichait pas le répertoire vendor/SupplierName. git add vendor/SupplierNamesemble fonctionner. Mais maintenant, lorsque je veux ajouter le fichier Module.php (et quelques autres fichiers, sous-répertoires, etc.), voici ce qui se passe. git add vendor/SupplierName/Module.php -> 

Les chemins suivants sont ignorés par l’un de vos fichiers .gitignore: vendor/SupplierName/Module.php

# Add here the vendor path to be whitelisted
# Ex: for composer directory write here "!composer" (without quotes)
*
!.gitignore
!SupplierName
!SupplierName/
!SupplierName/*

Me permet d’ajouter des fichiers directement dans vendor/SupplierName, mais git add vendor/SupplierName/config/module.config.php a toujours pour résultat 

Les chemins suivants sont ignorés par l’un de vos fichiers .gitignore: vendor/SupplierName/config/module.config.php

Je cherchais des problèmes de liste blanche récursive, parce que cela semble être le problème, mais rien n’a été soulevé.

26
Ivo van Beek

Vous pouvez utiliser 2 fichiers .gitignore pour obtenir le résultat souhaité:

# vendor/.gitignore
*
!.gitignore
!SupplierName/
!SupplierName/*

# vendor/SupplierName/.gitignore
!*

J'ai testé cela avec un référentiel de test et semble fonctionner pour moi en ajoutant des fichiers avec autant de niveaux situés sous le répertoire vendor/SupplierName.

$ git add .

$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   vendor/.gitignore
#   new file:   vendor/SupplierName/.gitignore
#   new file:   vendor/SupplierName/a
#   new file:   vendor/SupplierName/b
#   new file:   vendor/SupplierName/c
#   new file:   vendor/SupplierName/d
#   new file:   vendor/SupplierName/dir1/d
#   new file:   vendor/SupplierName/dir1/dir4/dir5/dir6/dir7/dir8/dir9/dir10/somefile
#   new file:   vendor/SupplierName/dir1/dir4/f1
#   new file:   vendor/SupplierName/dir1/dir4/f2
#   new file:   vendor/SupplierName/dir1/dir4/f3
#   new file:   vendor/SupplierName/dir1/dir4/f4
#   new file:   vendor/SupplierName/dir1/e
#   new file:   vendor/SupplierName/dir1/f
#   new file:   vendor/SupplierName/dir3/dir6/f5
#   new file:   vendor/SupplierName/dir3/dir6/f6
#   new file:   vendor/SupplierName/dir3/dir6/f7
#   new file:   vendor/SupplierName/dir3/dir7/f8
#   new file:   vendor/SupplierName/e
#
32
Tuxdude

Vous pouvez également y parvenir avec un seul fichier .gitignore (à la racine de votre projet):

/*
!/.gitignore
!/vendor
/vendor/*
!/vendor/SupplierName
13
Chronial

J'ai trouvé un article intéressant: https://jasonstitt.com/gitignore-whitelisting-patterns

Tous les crédits à Jason Stitt. Les textes sont copiés à partir du site ci-dessus:

Ignorer tout, puis ajouter des sous-arbres spécifiques

# Ignore everything
*
# But descend into directories
!*/
# Recursively allow files under subtree
!/subtree/**
# You can be specific with these rules
!/some/other/deep/path/**
!.gitignore 

La règle !*/ permet d'ignorer tous les répertoires. Mais Git ne suit pas les répertoires, mais uniquement les fichiers, donc !*/ lui-même ne fera que permettre la descente dans l'arborescence de répertoires complète; il ne permettra pas réellement n'importe quoi dans le repo. Avec cette règle en place, vous n’avez besoin que d’un seul règle utilisant le caractère générique récursif ** afin d'inclure un sous-arbre.

Si vous n’avez pas utilisé !*/, vous aurez besoin de règles supplémentaires pour ne pas ignorer /subtree/et ses répertoires enfants.

Tout le monde n'aime pas !*/ car cela signifie que s'il y a une autre règle autorise un motif de nom de fichier trouvé dans un répertoire que vous ne voulez pas dans le repo, le répertoire lui-même ne sera pas bloqué. Vous devez utiliser règles spécifiques pour les fichiers à inclure avec celui-ci.

Ignorer le répertoire racine, puis ajouter des sous-arbres entiers

# Ignore everything in the root
/*
# Un-ignore all of subtree
!/subtree/
!.gitignore 

Ce modèle est un peu plus grossier que le précédent. La règle /* ignorera uniquement les éléments situés à la racine du fichier .__ du référentiel. structure de répertoires, donc dès que vous ajoutez à la liste blanche un répertoire, tous les fichiers le contenu du répertoire sera également autorisé, même sans utiliser les jokers * ou **.

Ignorer tout ce qui se trouve dans un répertoire, mais garder le répertoire vide

*
!.gitignore

Git ne veut pas inclure un répertoire vide dans un repo, car il suit les fichiers. Placez un fichier caché (tel que .gitignore) dans le fichier répertoire, et il sera enregistré. Mais garder le répertoire vide, même si vous avez des fichiers à des fins de test/développement, c’est un C'est une bonne idée d'ignorer tout sauf le fichier .gitignore lui-même.

4
Simon Lang

J'ai eu un problème similaire lors du passage de CVS à Git.

Contrairement à CVS, Git ne regarde pas les répertoires, il se concentre sur les fichiers.

Par exemple, vous ne pouvez pas ignorer le répertoire "a" mais vous ne pouvez pas ignorer tous les fichiers du répertoire "a" comme ceci:! A/*

La même chose est vraie pour les sous-répertoires.

Si le répertoire "a" a un sous-répertoire "b" et que vous ignorez "! A/*", vous aurez toujours tous les fichiers dans "a/b".

Donc, vous devez alors ignorer aussi "! A/b/*" et ainsi de suite pour tous les sous-répertoires pour lesquels vous souhaitez une liste blanche.

Vous n'avez besoin que d'un fichier .gitignore.

alors vous vous retrouvez avec quelque chose comme:

# ignore everything
*
# except for .gitignore files in the current directory
!.gitignore
# and all files in directory a
!a/*
#and all files in subdirectory b
!a/b/*

Avec cela, vous obtiendrez toujours des fichiers de a/c et a/b/c. Je ne sais pas s'il existe une solution de contournement pour les sous-répertoires récursifs.

2
Goran

Vous devez d'abord tout inclure dans la liste noire, puis créer chaque répertoire et sous-répertoire dans la liste blanche . Par exemple, je veux uniquement mettre DIR /opt/source/, DIR /opt/nginx/ et FILE /home/test/.opt/hello.txt dans la liste blanche, pourrait écrire un fichier .gitignore comme celui-ci travail:

/*
!/.gitignore
!/opt
/opt/*
!/opt/source/
!/opt/nginx/
!/home
/home/*
!/home/test
/home/test/*
!/home/test/.opt
/home/test/.opt/*
!/home/test/.opt/hello.txt
2
realhu

J'ai créé un simple script JS pouvant être exécuté dans Node pour générer une règle de liste blanche car je trouvais que l'écriture manuelle de règles était un peu déroutante et je voulais pouvoir la modifier ultérieurement si j'oubliais comment l'écrire à la main.

'use strict';

// Generating a "whitelist" wherein you only want a specific folder to be
// affected requires following .gitignore-style rules.
// https://github.com/prettier/prettier/issues/3328
//
// Handcrafting these rules is hard to reason about and error-prone, so I'm
// going to generate them.
// See: https://github.com/prettier/prettier/issues/3328
// And: https://git-scm.com/docs/gitignore
//

const path = require('path');

const whitelistDir = '/themes/simple/src/';

function generateIgnoreRule(dir) {
    let output = '# Auto-generated by ' + path.basename(__filename) + '\n';
    output += '# Exclude everything except `' + dir + '`\n';
    // Add exclude everything rule
    output += '/*' + '\n';

    // Split by path
    const parts = dir.split('/');
    if (parts[0] === '') {
        // Remove first item if its blank
        parts.shift();
    }
    if (parts[parts.length - 1] === '') {
        // Remove last item if its blank
        parts.pop();
    }

    let totalPart = '';
    for (let part of parts) {
        totalPart += '/' + part;
        output += '!' + totalPart + '\n';
        if (part !== parts[parts.length - 1]) {
            output += totalPart + '/*' + '\n';
        }
    }
    return output;
}

console.log(generateIgnoreRule(whitelistDir));
console.log(
    '\nCopy the above rules out of the console output and paste into your .gitignore / .prettierignore'
);
0
SilbinaryWolf