Comment fonctionnent les modèles annulés dans .gitignore?

93

J'essaie d'utiliser un fichier .gitignore avec des motifs inversés (lignes commençant par!), Mais cela ne fonctionne pas comme je m'y attendais.

À titre d'exemple minimal, j'ai la structure de répertoires suivante:

C:/gittest
 -- .gitignore
 -- aaa/
   -- bbb/
     -- file.txt
   -- ccc/
     -- otherfile.txt

et dans mon fichier gitignore, j'ai ceci:

aaa/
!aaa/ccc/

Ma compréhension (basée sur cette page de documentation ) est que le fichier aaa / ccc / otherfile.txt ne doit pas être ignoré, mais en fait git ignore tout sous aaa.

Ai-je mal compris cette phrase: "Un préfixe facultatif! Qui annule le modèle; tout fichier correspondant exclu par un modèle précédent sera de nouveau inclus."?

BTW, c'est sur Windows avec msysgit 1.7.0.2.

Chris Perkins
la source

Réponses:

159

Je pense que ce que vous voulez vraiment faire est:

aaa/*
!aaa/ccc

Vous lui dites "ne pas regarder aaa" pour qu'il n'examine même jamais le chemin aaa/ccc. Si vous utilisez le caractère générique, il lit toujours le contenu de aaa, puis chaque entrée correspond au caractère générique et est ignorée, sauf celle aaa/cccqui est remise.

Cascabel
la source
2
@iconoclast: Alors vous faites probablement quelque chose de différent. Postez une autre question (avec des informations complètes) si vous avez besoin d'aide.
Cascabel
Cela n'a pas fonctionné pour moi non plus: / apps / *! / Apps / myApps / FluidTest / bin /
Jarrod Smith
5
@Jarrod Cela fonctionne; vous faites juste quelque chose de différent. Vous devrez utiliser cette méthode de manière récursive, pour exactement les raisons données dans la réponse. ! apps / myApps, apps / myApps / * et ainsi de suite.
Cascabel
Ahh désolé je comprends maintenant. Mais SO ne me laisse pas encore voter.
Jarrod Smith
Je me demande pourquoi cela ne fonctionne pas pour aaa / ** / *! Aaa / ccc / eee (ignorer tout, sauf les fichiers à un certain chemin)
Phương Nguyễn
21

Si vous souhaitez tout exclure aaa, mais inclure aaa/cccet tout ce qui se trouve en dessous, vous devez utiliser:

aaa/*
!aaa/ccc
!aaa/ccc/*

La première ligne dit à git d'ignorer tout ce qui se trouve en dessous aaa, la seconde lui dit de ne pas ignorer le dossier aaa/cccqui "active" la troisième ligne qui lui dit alors de ne pas tout ignorer en dessous aaa/ccc.

xmak
la source
1
La troisième ligne n'a fait aucune différence pour moi.
James Hopkin
3
Pour pouvoir tout inclure dans n'importe quel sous-répertoire ou aaa/cccà n'importe quel niveau, ce qui a fonctionné pour moi était !aaa/ccc/**au lieu de!aaa/ccc/*
boclodoa
3

Si quelqu'un ne voit toujours pas les éléments nouvellement non ignorés dans une main en git statuscours d'exécution, un git update-indexavant peut aider git à voir les changements (au moins dans la version 1.9.x de gitbash).

alexkb
la source