Como os padrões negados funcionam no .gitignore?

Eu estou tentando usar um arquivo .gitignore com padrões negados (linhas começando com!), Mas não está funcionando do jeito que eu esperava.

Como exemplo mínimo, tenho a seguinte estrutura de diretórios:

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

e no meu arquivo gitignore, eu tenho isto:

 aaa/ !aaa/ccc/ 

Meu entendimento (baseado nesta página doc ) é que o arquivo aaa / ccc / otherfile.txt não deve ser ignorado, mas na verdade git está ignorando tudo sob aaa.

Estou entendendo mal esta frase: “Um prefixo opcional! Que nega o padrão; qualquer arquivo correspondente excluído por um padrão anterior será incluído novamente”.

BTW, isso é no Windows com o msysgit 1.7.0.2.

Eu acho que o que você realmente quer fazer é:

 aaa/* !aaa/ccc 

Você está dizendo “não olhe no aaa “, então ele nunca examina o caminho aaa/ccc . Se você usar o caractere curinga, ele ainda lerá o conteúdo de aaa , então cada input corresponderá ao curinga e será ignorada, exceto aaa/ccc que é colocado de volta.

Se você quiser excluir tudo em aaa , mas include aaa/ccc e tudo abaixo dele, você deve usar:

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

A primeira linha diz ao git para ignorar everthing sob aaa , o segundo diz para não ignorar a pasta aaa/ccc que na verdade “ativa” a terceira linha que então diz para não ignorar tudo sob aaa/ccc .

Se alguém ainda não estiver vendo itens recém-ignorados em um git status executando um git update-index antes da mão pode ajudar git para ver as mudanças (pelo menos na versão 1.9.x do gitbash).