55 votes

Différence entre les chemins dans le fichier .gitignore ?

J'ai utilisé git mais j'ai toujours des doutes sur le .gitignore les chemins d'accès aux fichiers.

Alors, quelle est la différence entre les deux chemins suivants en .gitignore fichier ?

tmp/\*
public/documents/\*\*/\*

Je peux comprendre que tmp/* ignorera tous les fichiers et dossiers qu'il contient. Ai-je raison ? Mais que signifie le chemin d'accès de la deuxième ligne ?

55voto

John Feminella Points 116878

Cela dépend du comportement de votre shell. Git ne fait aucun travail pour déterminer comment les développer. En général, * correspond à un seul fichier ou dossier :

/a/*/z
 matches        /a/b/z
 matches        /a/c/z
 doesn't match  /a/b/c/z

** correspond à n'importe quelle chaîne de dossiers :

/a/**/z
 matches        /a/b/z
 matches        /a/b/c/z
 matches        /a/b/c/d/e/f/g/h/i/z
 doesn't match  /a/b/c/z/d.pr0n

Combinez ** con * pour faire correspondre des fichiers dans une arborescence de dossiers entière :

/a/**/z/*.pr0n
 matches        /a/b/c/z/d.pr0n
 matches        /a/b/z/foo.pr0n
 doesn't match  /a/b/z/bar.txt

16voto

cdunn2001 Points 3597

Mise à jour (08-Mar-2016)

Aujourd'hui, je suis incapable de trouver une machine où ** ne fonctionne pas comme prévu. Cela inclut OSX-10.11.3 (El Capitan) et Ubuntu-14.04.1 (Trusty). Il est possible que git-ignore ait été mis à jour, ou que des mises à jour récentes aient été effectuées. fnmatch poignées ** comme les gens s'y attendent. Ainsi, la réponse acceptée semble maintenant être correcte dans la pratique.


Poste original

El ** n'a pas de signification particulière dans git . Il s'agit d'une fonctionnalité de bash >= 4.0, par le biais de

shopt -s globstar

Mais git n'utilise pas bash . Pour voir ce que git fait, vous pouvez expérimenter avec git add -nv et des fichiers dans plusieurs niveaux de sous-répertoires.

Pour l'OP, j'ai essayé toutes les combinaisons auxquelles je peux penser pour la .gitignore et rien ne fonctionne mieux que ça :

public/documents/

Ce qui suit ne fait pas ce que tout le monde semble penser :

public/documents/**/*.obj

Je n'arrive pas à le faire fonctionner quoi que j'essaie, mais au moins, c'est cohérent avec l'approche de la git docs . Je pense que lorsque les gens ajoutent cela à .gitignore cela fonctionne par accident, seulement parce que leur .obj sont précisément d'un sous-répertoire. Ils ont probablement copié le double-astérix à partir d'un script bash. Mais peut-être y a-t-il des systèmes où fnmatch(3) peut gérer le double-astérisque comme le fait bash.

15voto

emk Points 27772

Si vous utilisez un shell tel que Bash 4, ** est essentiellement une version récursive de *, qui correspondra à un nombre quelconque de sous-répertoires.

Cela a plus de sens si vous ajoutez une extension de fichier à vos exemples. Pour faire correspondre les fichiers journaux immédiatement à l'intérieur de tmp, vous devez taper :

/tmp/*.log

Pour faire correspondre les fichiers journaux n'importe où dans n'importe quel sous-répertoire de tmp, vous devez taper :

/tmp/**/*.log

Mais en testant avec la version 1.6.0.4 de git et la version 3.2.17(1)-release de bash, il apparaît que git ne supporte pas du tout ** globs. Le site la page de manuel la plus récente pour gitignore ne mentionne pas non plus **, donc ceci est soit (1) très nouveau, (2) non supporté, ou (3) dépendant d'une manière ou d'une autre de l'implémentation de globbing sur votre système.

De plus, il y a quelque chose de subtil dans vos exemples. Cette expression :

tmp/*

...signifie en fait "ignorer tout fichier à l'intérieur de un répertoire tmp, n'importe où dans l'arbre des sources, mais n'ignorez pas les répertoires tmp eux-mêmes". Dans des circonstances normales, vous écrirez probablement simplement :

/tmp

...qui ignorerait un seul répertoire tmp de premier niveau. Si vous avez besoin de conserver les répertoires tmp, tout en ignorant leur contenu, vous devriez placer un fichier .gitignore vide dans chaque répertoire tmp pour vous assurer que git crée effectivement le répertoire.

14voto

VonC Points 414372

Notez que le ' ** ', lorsqu'il est combiné avec un sous-répertoire ( **/bar ), doit avoir changé par rapport à son comportement par défaut, puisque la fonction note de publication pour git1.8.2 mentionne maintenant :

Les motifs dans .gitignore y .gitattributes Les fichiers peuvent avoir **/ comme un motif qui correspond à 0 ou plusieurs niveaux de sous-répertoire.

Par exemple, " foo/**/bar " correspond " bar " dans " foo "lui-même ou dans un sous-répertoire de " foo ".


Voir commit 4c251e5cb5c245ee3bb98c7cedbe944df93e45f4 :

" foo/**/bar " correspond " foo/x/bar ", " foo/x/y/bar "... mais pas" foo/bar ".
Nous faisons un cas particulier, lorsque foo/**/ est détecté (et " foo/ "est déjà appariée), essayez d'apparier " bar " avec le reste de la chaîne.

La sémantique "Match one or more directories" peut être facilement réalisée en utilisant " foo/*/**/bar ".

Cela rend également " **/foo " match " foo " en plus de " x/foo ", " x/y/foo "..

Signé par : Nguyễn Thái Ngọc Duy <pclouds@gmail.com>


Simon Buchan également a commenté :

la documentation actuelle ( .gitignore page de manuel ) sont assez clairs sur le fait qu'aucun sous-répertoire n'est nécessaire, x/** correspond à tous les fichiers sous (éventuellement vide) x

El .gitignore est mentionné dans la page de manuel :

Un " " de queue /** " correspond à tout ce qui se trouve à l'intérieur. Par exemple, " abc/** " correspond à tous les fichiers du répertoire " abc ", par rapport à l'emplacement de la .gitignore avec une profondeur infinie.

Une barre oblique suivie de deux astérisques consécutifs puis d'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.

5voto

Hazok Points 825

Lorsque ** n'est pas pris en charge, le "/" est essentiellement un caractère de terminaison pour le caractère générique, donc lorsque vous avez quelque chose comme :

public/documents/**/*

il recherche essentiellement deux éléments joker entre les barres obliques et ne prend pas en compte les barres obliques elles-mêmes. Par conséquent, ce serait la même chose que :

public/documents/*/*

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