Liste blanche et sous-répertoires dans Git

90

J'ai créé une liste blanche pour les fichiers texte uniquement.

*
!*.txt

Maintenant, j'ai un fichier texte non suivi dans un sous-répertoire - sub/dir/file.txt, et cela n'est PAS affiché (il est ignoré). Cependant, les fichiers texte du répertoire racine sont affichés.

Pourquoi cela et comment résoudre ce problème?

Nate
la source
1
En relation: stackoverflow.com/q/987142/78845
Johnsyweb
Les fichiers que vous souhaitez inclure dans un sous-répertoire? Si tel est le cas, ce sous-répertoire peut déjà être ignoré par la première étoile de votre fichier .gitignore.
fajran
Oui. Ces fichiers seront aussi bas dans la structure de répertoires que le dossier 11.1.102.55 dans mon exemple. L'imbrication n'est pas toujours la même entre les dossiers / produits.
Nate le
1
Je connais cette fonctionnalité. Nous avons des centaines d'annuaires. Il serait plus rapide d'ignorer explicitement les types de fichiers que nous ne voulons pas que de créer un gitignore pour chaque répertoire. Je cherche vraiment un moyen d'obtenir la fonctionnalité de liste blanche du fichier .gitignore.
Nate
1
Je ne vois pas en quoi c'est un doublon. L'autre question demande comment mettre en liste blanche certains fichiers, tandis que celle-ci demande comment mettre en liste blanche certains types de fichiers, y compris les sous-dossiers. En fait, cela ressemble plus à un double de stackoverflow.com/questions/8024924/… .
Big McLargeHuge

Réponses:

144

Si vous essayez de cette façon, cela échouera, car vous finirez par mettre sur liste noire les répertoires de votre structure.

Pour résoudre, vous voulez mettre sur liste noire tout ce qui n'est pas un répertoire, et qui ne fait pas partie des types de fichiers que vous souhaitez valider, sans mettre sur liste noire les répertoires .

Le .gitignorefichier qui fera cela:

# First, ignore everything
*
# Now, whitelist anything that's a directory
!*/
# And all the file types you're interested in.
!*.one
!*.two
!*.etc

J'ai testé cela dans une liste blanche de structure à trois niveaux pour les .txtfichiers en présence de *.one, *.twoet les *.threefichiers à l'aide d'un .gitignoresitué dans le répertoire racine du référentiel - fonctionne pour moi. Vous n'aurez pas à ajouter de .gitignorefichiers à tous les répertoires de votre structure.

Informations que je l' habitude de trouver la réponse est venue, entre autres, ce (stackoverflow.com).

Simont
la source
18
Vous avez également besoin de l'entrée !.gitignore, lors de l'utilisation *, n'est-ce pas?
sjas
2
Voir ma réponse ici: stackoverflow.com/questions/987142/ ... Il peut être plus utile d'utiliser /*pour mettre sur liste noire uniquement le dossier de niveau supérieur, mais pas tous les dossiers de manière récursive, ce qui signifie en fait .gitignorene devrait pas regarder dans les sous-dossiers d'un dossier en liste blanche.
Ryan Taylor
1

Un moyen plus simple d'y parvenir est:

# Blacklist all files...
*.*

# ...except the ones we want
!*.txt

Cela fonctionne car gitignoreapplique des modèles qui ne commencent pas par /à tous les niveaux sous le .gitignorefichier:

S'il y a un séparateur au début ou au milieu (ou les deux) du modèle, alors le modèle est relatif au niveau de répertoire du fichier .gitignore particulier lui-même. Sinon, le modèle peut également correspondre à n'importe quel niveau en dessous du niveau .gitignore.

Si vous vouliez faire cela avec des fichiers dans un répertoire , les choses deviennent plus complexes:

# Blacklist all files in all directories inside subdir...
/subdir/**/*.*

# ...except the ones we want
!/subdir/**/*.txt

Cela fonctionne car gitignorea des règles spéciales pour **:

Deux astérisques consécutifs (" **") dans les motifs mis en correspondance avec le chemin complet peuvent avoir une signification particulière:

  • Une barre oblique suivie de deux astérisques consécutifs puis une barre oblique correspond à zéro ou plusieurs répertoires. Par exemple, " a/**/b" correspond à " a/b", " a/x/b", " a/x/y/b" et ainsi de suite.

L'élément clé est de vous assurer que vous n'ignorez pas les répertoires, car alors chaque fichier de ce répertoire est ignoré indépendamment des autres règles.

Sharadh
la source
0

J'ai cherché pendant longtemps:

  1. Supposons que j'ai une grande structure de dossiers avec ~ 100 000 répertoires imbriqués de manière récursive. Dans ces dossiers, il y a environ 30 000 fichiers de type .txt(dans mon cas: type *.md). À côté de ces *.mdfichiers, il y a, disons, 500 Go de (un million +) fichiers que je ne veux pas suivre.

  2. Je veux que git ne suive que .txt(ou *.md) les fichiers dans tous les dossiers et sous-répertoires.

La bonne réponse devrait être: ce n'est pas possible dans Git.

Ce que j'ai fait à la place:

[modifier: n'a pas non plus fonctionné - j'ai essayé de créer un dossier avec des liens symboliques (ou des liens physiques) et d'utiliser git là-bas, mais git ne suit pas les liens symboliques et écrase les liens physiques. Doh!]

Alex
la source