Comment fonctionnent les règles d'exclusion de gitignore?

j'essaie de résoudre un problème de gitignore sur une structure de répertoire large, mais pour simplifier ma question je l'ai réduite à ce qui suit.

j'ai la structure de répertoire suivante de deux fichiers (foo, bar) dans un tout nouveau dépôt git (no commits so far):

a/b/c/foo
a/b/c/bar

évidemment, un 'statut git-u' Montre:

# Untracked files:
...
#       a/b/c/bar
#       a/b/c/foo

Ce que je veux faire c'est créer un .gitignore fichier qui ignore tout à l'intérieur a / b / C mais n'ignore pas le fichier 'foo'.

si je crée un .gitignore ainsi:

c/

puis un 'statut git-u' Montre à la fois foo et bar comme ignoré:

# Untracked files:
...
#       .gitignore

ce qui est normal.

maintenant si j'ajoute une règle d'exclusion pour foo, donc:

c/
!foo

D'après la page de manuel de gitignore, je m'attendais à ce que ça marche. Mais il ne le fait pas - il ignore toujours foo:

# Untracked files:
...
#       .gitignore

ça ne marche pas non plus:

c/
!a/b/c/foo

ni l'un ni l'autre:

c/*
!foo

Donne:

# Untracked files:
...
#       .gitignore
#       a/b/c/bar
#       a/b/c/foo

dans ce cas, même si foo n'est plus ignoré, bar n'est pas non plus ignoré.

L'ordre des règles .gitignore ne semble pas compter non plus.

cela aussi ne fait pas ce que je m'attendais:

a/b/c/
!a/b/c/foo

que l'on ignore à la fois foo et bar.

une situation qui fonctionne est si je crée le fichier a/b/c/.gitignore et mis là:

*
!foo

Mais le problème, c'est que finalement il y aura d'autres sous-répertoires sous/b/c et je ne veux pas avoir à mettre un séparé .gitignore dans chaque un seul - j'espérais créer "basé sur le projet".les fichiers gitignore qui peuvent s'asseoir dans le répertoire supérieur de chaque projet, et couvrir toute la structure du sous-répertoire "standard".

cela semble aussi être équivalent:

a/b/c/*
!a/b/c/foo

cela pourrait être la chose la plus proche de" travailler " que je puisse réaliser, mais les chemins relatifs complets et les exceptions explicites doivent être indiquées, ce qui va être une douleur si j'ai beaucoup de fichiers de nom 'foo' dans différents niveaux de l'arbre de sous-répertoire.

de toute façon, soit je ne comprends pas tout à fait comment les règles d'exclusion fonctionnent, ou ils ne fonctionnent pas du tout lorsque les répertoires (plutôt que les jokers) sont ignorés - par une règle se terminant par un /

quelqu'un peut-il nous éclairer là-dessus?

y a-t-il un moyen de faire en sorte que gitignore utilise quelque chose de sensé comme des expressions régulières au lieu de cette syntaxe maladroite basée sur l'interpréteur de commandes?

j'utilise et observe ceci avec git-1.6.6.1 sur Cygwin/bash3 et git-1.7.1 sur Ubuntu/bash3.

130
demandé sur meowsqueak 2010-06-09 02:46:52

5 réponses

/a/b/c/*
!foo

semble fonctionner pour moi (git 1.7.0.4 sur Linux). Le * est important car sinon vous ignorez le répertoire lui-même (donc git ne regardera pas à l'intérieur) au lieu des fichiers du répertoire (ce qui permet l'exclusion).

pensez aux exclusions comme disant " mais pas celui - ci "plutôt que" mais incluez ceci " - "ignorez ce répertoire ( /a/b/c/ ) mais pas celui-ci ( foo ) "n'a pas beaucoup de sens;" ignorez tous les fichiers dans ce répertoire ( /a/b/c/* ) mais pas celui-ci ( foo )". Pour citer la page de manuel:

un préfixe facultatif ! ce qui annule le modèle; tout fichier de correspondance exclu par un modèle précédent sera inclus à nouveau.

i.e., le fichier doit avoir déjà été exclu pour être inclus à nouveau. Espérons que jette un peu de lumière.

131
répondu Chris 2010-06-08 23:00:44

j'ai une situation similaire, ma solution était d'utiliser:

/a/**/*
!/a/**/foo

qui devrait fonctionner pour un nombre arbitraire de répertoires intermédiaires si je lis correctement ** .

22
répondu medge799 2012-03-07 16:11:18

Voici une autre option:

*
!/a*
!/a/*
!/a/*/*
!/a/*/*/*

qui ignorerait tous les fichiers et répertoires, à l'exception des fichiers/répertoires à trois niveaux au sein d'un.

6
répondu Peter Petrik 2011-02-06 00:18:27

ce n'est certainement pas clair de la .gitignore page de man. Cela fonctionne:

*
!/a
!/a/b
!/a/b/c
!/a/b/c/foo

# don't forget this one
!.gitignore

comme mentionné par Chris un répertoire n'est même pas ouvert s'il est exclu. Donc si vous voulez pouvoir ignorer * mais certains fichiers, vous devez construire le chemin vers ces fichiers comme ci-dessus. Pour moi, c'est pratique, parce que je veux faire une revue de code sur 1 fichier d'une bibliothèque et si je veux faire un autre plus tard, je viens de l'ajouter, et tout le reste est ignoré.

4
répondu 2010-11-10 00:42:39

sur une note plus générale, git1.8.2 inclura le patch (aussi dans son v4 , poussé par une question de débordement de pile ) de Adam Spiers au sujet de déterminer quelle règle gitignore ignore réellement votre fichier.

voir git1.8.2 notes de version et la question " que la règle de gitignore ignore mon dossier ":

ce sera la commande git check-ignore .

4
répondu VonC 2017-05-23 12:10:30