50 votes

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

J'essaie de mettre sur liste blanche le répertoire (et son contenu) SupplierName dans mon répertoire fournisseur de Zend Framework 2.

Le fichier .gitignore original dans /vendor ressemble à ceci :

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

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

Premier essai ajoutez !SupplierName juste après le commentaire qui dit que je dois ajouter le chemin d'accès à 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'a pas montré le répertoire vendor/SupplierName. git add vendor/SupplierName a affiché 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'a pas montré le répertoire vendor/SupplierName. git add vendor/SupplierName a affiché 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'a pas montré le répertoire vendor/SupplierName. git add vendor/SupplierName semble fonctionner . Mais maintenant, lorsque je veux ajouter le fichier Module.php (et d'autres fichiers, sous-répertoires, etc.), il se passe ce qui suit. 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/*

Permet d'ajouter des fichiers directement dans vendor/SupplierName, mais git add vendor/SupplierName/config/module.config.php entraîne toujours

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

J'ai cherché des problèmes concernant la mise en liste blanche récursive, car cela semble être le problème, mais je n'ai rien trouvé.

2voto

Ryan Feeley Points 72

Cette technique est liée à la première technique de @Simon Lang (avec le crédit de Jason Stitt), mais elle est applicable à une plus grande variété de cas.

Supposons que vous voulez avoir un seul .gitignore dans votre racine de projet, et supposons que vous voulez ignorer la majeure partie d'un sous-répertoire de votre projet, mais autoriser une petite partie. Par exemple, supposons que votre repo inclut un /vendor/ avec une dépendance d'une tierce partie que vous avez choisi de garder en grande partie intacte, mais à laquelle vous ferez quelques ajustements légers que vous voulez que git suive, peut-être pour aider au portage lorsque l'inévitable nouvelle version apparaîtra.

Vous pouvez alors faire ce qui suit dans votre Racine .gitignore archivo:

# ignore all files and folders in `/vendor/` and in its descendants
/vendor/**

# negated pattern to un-exclude all *folders* at any depth relative to `vendor/`
# as always git will ultimately ignore the folders for which you don't
# subsequently un-exclude any *files*.
!/vendor/**/

# negated pattern to un-exclude all files and folders at any depth below the deep
# path that contains files you want in git
!/vendor/supplier/version/module/component/src/**

Chaque occurrence du double astérisque est critique. Par exemple, un vendor/** correspond à tout ce qui se trouve à l'intérieur -- tous les fichiers et répertoires dans vendor avec une profondeur infinie, et exclut ainsi tous ses descendants.

Dans une règle gitignore joker "normale" comme *.exe o * la correspondance avec le métacaractère glob permet de découvrir n'importe quel fichier dans n'importe quel répertoire, puisque le chemin d'accès n'est pas contraint. C'est le chemin non contraint qui fait le gros du travail ici, pas l'expansion du caractère générique. Dès que vous essayez de restreindre l'étendue de l'ignorance à un sous-répertoire de votre racine, ce levier lourd disparaît et vous vous heurtez immédiatement à l'incapacité de * pour descendre dans l'arbre.

La réponse de Simon fonctionne en gardant l'extrémité du chemin d'exclusion initial sans contrainte. Elle exclut initialement chaque fichier (à n'importe quelle profondeur) dans le répertoire qui contient le fichier .gitignore. Mine vous donne la possibilité d'appliquer cette approche d'exclusion à tous les sous-répertoires, en utilisant la méthode suivante ** pour faire une correspondance globale de / . Vous pouvez obtenir le même effet en ayant plusieurs fichiers .gitignore et en utilisant la technique de Simon dans un fichier .gitignore situé à l'adresse suivante /vendor/.gitignore mais c'est plus à entretenir.

Je ne sais pas s'il y a des implications en termes de performances à utiliser ** comme je l'ai fait ici. Cela pourrait être testé en comparant les performances d'un .gitignore qui ressemblerait à ceci

*
!*/
!a/b/c/d/**

à un qui ressemblait à ceci

/**
!**/
!a/b/c/d/**

dans une arborescence ayant beaucoup de fichiers. Je pense que le même contenu serait inclus et exclu, mais l'implémentation sous le capot pourrait être différente, tout comme les performances.

0voto

SilbinaryWolf Points 384

J'ai créé un simple snipscript JS qui peut être exécuté dans Node pour générer une règle de liste blanche car je trouvais l'écriture manuelle des règles un peu confuse et je voulais pouvoir modifier la règle plus tard 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'
);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X