Como os padrões negados funcionam em .gitignore?

93

Estou tentando usar um arquivo .gitignore com padrões negados (linhas começando com!), Mas não está funcionando da maneira que esperava.

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

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

e em meu arquivo gitignore, tenho este:

aaa/
!aaa/ccc/

Meu entendimento (com base nesta página de 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 está no Windows com msysgit 1.7.0.2.

Chris Perkins
fonte

Respostas:

159

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

aaa/*
!aaa/ccc

Você está dizendo "não olhe aaa" para que ele nunca examine o caminho aaa/ccc. Se você usar o curinga, ele ainda lê o conteúdo de aaa, então cada entrada corresponde ao curinga e é ignorada, exceto o aaa/cccque é colocado de volta.

Cascabel
fonte
2
@iconoclast: Então provavelmente você está fazendo algo diferente. Poste outra pergunta (com informações completas) se quiser ajuda.
Cascabel de
Isso também não funcionou para mim: / apps / *! / Apps / myApps / FluidTest / bin /
Jarrod Smith
5
@Jarrod Funciona; você está apenas fazendo algo diferente. Você terá que usar esse método recursivamente, exatamente pelas razões fornecidas na resposta. ! apps / myApps, apps / myApps / * e assim por diante.
Cascabel
Ahh desculpe, eu entendo agora. Mas SO não me deixa votar novamente.
Jarrod Smith
Me pergunto por que não funciona para aaa / ** / *! Aaa / ccc / eee (ignore tudo, exceto arquivos em determinado caminho)
Phương Nguyễn
21

Se você deseja excluir tudo em aaa, mas incluir aaa/ccce tudo abaixo dele, você deve usar:

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

A primeira linha diz ao git para ignorar tudo abaixo aaa, a segunda diz a ele para não ignorar a pasta aaa/cccque realmente "ativa" a terceira linha que diz a ele para não ignorar tudo abaixo aaa/ccc.

xmak
fonte
1
A terceira linha não fez diferença para mim.
James Hopkin,
3
Para poder incluir tudo em qualquer subdiretório de aaa/cccqualquer nível, o que funcionou para mim foi em !aaa/ccc/**vez de!aaa/ccc/*
boclodoa
3

Se alguém ainda não está vendo itens não ignorados recentemente em git statusexecução, git update-indexpode ajudar o git a ver as mudanças (pelo menos na versão 1.9.x do gitbash).

alexkb
fonte