Quelle est la différence entre l' ajout bin
, bin/
, bin/*
et bin/**
dans mon dossier .gitignore? J'ai utilisé bin/
, mais en regardant d' autres fichiers .gitignore (dans le fichier eclipse, les étoiles double et simple sont même utilisées ensemble comme ceci: tmp/**/*
qu'est-ce qui se passe avec ça?) Je vois que les deux premiers modèles sont également largement utilisés. Quelqu'un peut-il expliquer les différences entre les trois?
89
**
: stackoverflow.com/questions/1470572/…Réponses:
bin
correspond à tous les fichiers ou répertoires nommés «bin».bin/
correspond à tous les répertoires nommés 'bin', ce qui signifie en fait tout son contenu puisque Git ne suit pas seul les répertoires.bin/*
correspond directement à tous les fichiers et répertoires dans anybin/
. Cela empêche Git de trouver automatiquement des fichiers dans ses sous-répertoires, mais si, par exemple, unbin/foo
sous-répertoire est créé, cette règle ne correspondra pas aufoo
contenu de.bin/**
correspond à tous les fichiers et répertoires dans n'importe quelbin/
répertoire et tous ses sous-répertoires.Le mot «any» est critique ici car les règles ne sont pas relatives à la racine du référentiel et s'appliquent n'importe où dans l'arborescence du système de fichiers. Vous devez commencer les règles par un
/
(ou!/
pour un-ignorer) qui signifie la racine du référentiel, pas la racine du système, afin de ne correspondre qu'à ce qui était prévu.AVERTISSEMENT: Vous devriez ne jamais utiliser des règles comme
dir/*
,/dir/**
, etc. seul à moins que vous aussi non ignorer quelque chose qui existe à l' intérieur de ce répertoire . Omettez l'astérisque ou vous pourriez perdre définitivement beaucoup de données à cause de certaines invocations degit gc
,git stash
et plus encore.Je ne sais pas vraiment ce que l'
tmp/**/*
on veut faire. J'ai d'abord pensé qu'il pouvait être utilisé pour faire correspondre des fichiers dans les sous-répertoires detmp/
mais pas des fichiers directement présents entmp/
lui-même. Mais un simple test semble suggérer que cela ignore tous les fichiers danstmp/
.la source
bin/
etbin/**
?bin/
que j'ignorerai le répertoire bin, alorsbin/**
qu'il inclura le répertoire bin mais aucun de son contenubin/
ignorera le répertoire lui-même (y compris tous les sous-répertoires et fichiers), alors quebin/**
tous les fichiers du répertoire bin et de ses sous-répertoires seront ignorés, mais pas le répertoire bin lui-même. Que ce soit exact ou non, je ne suis pas sûr.bin/** \n !bin/*
(car je ne vois pas comment forcer un saut de ligne dans mini-Markdown)bin
correspond à la fois à un fichier nommébin
et au contenu dubin
dossier. Troisièmement,bin/*
correspond à tous les fichiers de ses sous-répertoires. Avez-vous même testé ça?bin
etbin/
ne diffèrent que par le fait que ce dernier ne correspondra qu'à un répertoire.bin/**/*
est le même quebin/**
(apparemment depuis le 1.8.2, selon la réponse de @ VonC).La délicate, que je viens de passer une heure ou déchirant mes cheveux plus, est que
bin/
etbin/**
ne sont pas tout à fait la même chose! Puisque le premier ignore le répertoire dans son ensemble et que le dernier ignore chacun des fichiers qu'il contient, et que git dans presque tous les cas ne se soucie pas des répertoires, il n'y a normalement aucune différence. Cependant, si vous essayez d'utiliser!
pour désignorer un sous-chemin, vous constaterez que git (ahem) l' ignore si vous avez ignoré le répertoire parent! (encore une fois, plutôt que le contenu du répertoire)Ceci est plus clair par exemple, donc pour un référentiel nouvellement lancé configuré ainsi:
Les fichiers non suivis suivants existent:
Mais vous pouvez voir que les fichiers suivants ne sont pas ignorés:
Et si vous essayez d'ajouter, vous obtenez:
Je considère ce comportement comme un bug. (Tout est allumé
git version 1.8.4.msysgit.0
)la source
dir/
etdir/**
re. la annulation de l'ignorance avec!
se produit car "Il n'est pas possible de ré-inclure un fichier si un répertoire parent de ce fichier est exclu" [source ]. Confus, mais fait pour des raisons de performances. Voir une question SO connexe .Notez qu'à proprement parler, git ne suit pas les répertoires, seulement les fichiers. Il n'est donc pas possible d'ajouter un répertoire, seulement son contenu .
Dans le contexte de
.gitignore
cependant, git prétend comprendre les répertoires pour la seule raison queQu'est-ce que cela signifie pour les modèles d'exclusion? Passons en revue en détail:
bin
Cela ignore
bin
.bin
Vous pouvez
bin
ajouter des fichiers et des dossiers ignorés à la liste blanche en ajoutant des!
entrées ultérieures , mais vous ne pouvez pas mettre en liste blanche le contenu des dossiers nommésbin
bin/
Idem que ci-dessus, sauf qu'il ne correspond pas aux fichiers nommés
bin
. L'ajout d'une fin/
indique à git de ne rechercher que les répertoires.bin/*
Cela ignore
bin
bin
bin/**
Cela ignore
bin
bin
la source
Je viens de faire un nouveau repo et j'ai essayé certaines choses. Voici mes résultats:
NOUVEAUX RÉSULTATS
git version 2.10.1.windows.1
bin
répertoire de plusieurs couches de profondeurbin.txt
Test.txt
bin/a/b/bin.txt
bin/a/b/Test.txt
bin/a/bin/bin.txt
bin/a/bin/Test.txt
bin/a/bin.txt
bin/a/Test.txt
bin/bin.txt
bin/Test.txt
bin
à gitignore: Résultatsbin
répertoire (et plus profond) est maintenant ignorébin
dansbin/
dans le gitignore: Résultatsbin/
versbin/*
bin/*
versbin/**
bin/**
versbin/**/
bin/bin.txt
etbin/Test.txt
ne sont plus ignorésbin/**/
versbin/**/*
bin/bin.txt
etbin/Test.txt
sont de nouveau ignorésANCIENS RÉSULTATS
version git: 2.7.0.windows.1
bin
répertoire de plusieurs couches de profondeurbin/a/b/Test.txt
bin/a/bin/Test.txt
bin/a/Test.txt
bin/Test.txt
bin
à gitignore: Résultatsbin
répertoire (et plus profond) est maintenant ignorébin
dansbin/
dans le gitignore: Résultatsbin
répertoire (et plus profond) est toujours ignoré (pas de changement)bin/
versbin/*
bin
répertoire (et plus profond) est toujours ignoré (pas de changement)bin/*
versbin/**
bin
répertoire (et plus profond) est toujours ignoré (pas de changement)bin/**
versbin/**/
bin/Test.txt
n'est plus ignorébin/**/
versbin/**/*
bin
répertoire (et plus profond) est à nouveau ignoréla source
Notez que le '
**
', lorsqu'il est combiné avec un sous-répertoire (**/bar
), doit avoir changé de son comportement par défaut, puisque la note de publication de git1.8.2 mentionne maintenant:La règle à retenir (et qui aide à comprendre la différence d'intention derrière ces syntaxes) est:
Il n'est pas possible de ré-inclure un fichier si un répertoire parent de ce fichier est exclu.
En règle générale, si vous souhaitez exclure des fichiers d'un sous-dossier d'un dossier ignoré f, procédez comme suit:
C'est:
f/
, le dossierf/
serait ignoré et les règles ci-dessous concernantf
n'auraient pas d'importance.f/**
obtenir la même chose quef/
, mais ignorer tous les sous-éléments (fichiers et sous-dossiers).Cela vous donne la possibilité de mettre sur liste blanche (exclure de gitignore) les sous-dossiers:
!f/**/
.f
sous-dossiers ne sont pas ignorés, vous pouvez ajouter une règle pour exclure un fichier (!f/a/sub/folder/someFile.txt
)la source
Il y a une autre différence entre
bin/*
etbin/
.bin/
correspondfoo/bin/test.txt
(comme prévu), maisbin/*
pas, ce qui semble étrange, mais c'est documenté: https://git-scm.com/docs/gitignoreLa raison à cela semble être ces règles:
Donc, si le modèle se termine par une barre oblique, la barre oblique est supprimée et elle est traitée comme un modèle de shell glob, auquel cas
bin
correspondfoo/bin/test.txt
. Si elle se termine par/*
, la barre oblique n'est pas supprimée et elle est passée à fnmatch, qui ne correspond pas dans les sous-répertoires.Cependant, il n'en va pas de même pour
foo/bin/
etfoo/bin/*
, car même après avoir supprimé la barre oblique de finfoo/bin/
, elle contient toujours une barre oblique, elle est donc traitée comme un modèle fnmatch, pas comme un glob. Ie ça ne correspondra pasbar/foo/bin/test.txt
la source