Whitelisting e subdiretórios no Git

90

Eu criei uma lista branca apenas para arquivos de texto.

*
!*.txt

Agora, eu tenho um arquivo de texto não rastreado em um subdiretório - sub/dir/file.txte isso NÃO é mostrado (ele é ignorado). Arquivos de texto no diretório raiz são mostrados, entretanto.

Por que isso acontece e como faço para corrigir isso?

Nate
fonte
1
Relacionado: stackoverflow.com/q/987142/78845
Johnsyweb
Os arquivos que você deseja incluir em um subdiretório? Nesse caso, este subdiretório já pode ser ignorado pela primeira estrela em seu .gitignore.
fajran
Sim. Esses arquivos estarão tão baixos na estrutura de diretório quanto a pasta 11.1.102.55 em meu exemplo. O aninhamento nem sempre é o mesmo entre pastas / produtos.
Nate
1
Eu conheço essa funcionalidade. Temos centenas de diretórios. Seria mais rápido simplesmente ignorar explicitamente os tipos de arquivos que não queremos do que criar um gitignore para cada diretório. Estou realmente procurando uma maneira de obter a funcionalidade de lista de permissões do arquivo .gitignore.
Nate
1
Não vejo como isso é uma duplicata. A outra pergunta é como colocar na lista de permissões certos arquivos, enquanto esta pergunta como colocar na lista de permissões certos tipos de arquivos, incluindo subpastas. Na verdade, é mais como uma duplicata de stackoverflow.com/questions/8024924/… .
Big McLargeHuge

Respostas:

144

Se você tentar dessa forma, ele falhará, porque você acabará colocando os diretórios na lista negra de sua estrutura.

Para resolver, você deseja colocar na lista negra tudo o que não é um diretório e não é um dos tipos de arquivo que deseja enviar, enquanto não coloca os diretórios na lista negra .

O .gitignorearquivo que fará isso:

# First, ignore everything
*
# Now, whitelist anything that's a directory
!*/
# And all the file types you're interested in.
!*.one
!*.two
!*.etc

Testei isso em uma lista branca de estrutura de três níveis para .txtarquivos na presença de *.one, *.twoe *.threearquivos usando um .gitignorelocalizado no diretório raiz do repositório - funciona para mim. Você não terá que adicionar .gitignorearquivos a todos os diretórios em sua estrutura.

As informações que usei para descobrir a resposta vieram, entre outras coisas, deste (stackoverflow.com).

simont
fonte
18
Você também precisa da entrada !.gitignore, ao usar *, não é?
sjas
2
Veja minha resposta aqui: stackoverflow.com/questions/987142/… Pode ser mais útil usar /*para colocar na lista negra apenas a pasta de nível superior, mas não todas as pastas recursivamente, o que realmente significa .gitignoreque não deve olhar para as subpastas de uma pasta na lista de permissões.
Ryan Taylor
1

Uma maneira mais simples de conseguir isso é:

# Blacklist all files...
*.*

# ...except the ones we want
!*.txt

Isso funciona porque gitignoreaplica padrões que não começam com /todos os níveis abaixo do .gitignorearquivo:

Se houver um separador no início ou no meio (ou ambos) do padrão, o padrão é relativo ao nível de diretório do próprio arquivo .gitignore específico. Caso contrário, o padrão também pode corresponder em qualquer nível abaixo do nível .gitignore.

Se você quiser fazer isso com arquivos dentro de um diretório , as coisas ficam mais complexas:

# Blacklist all files in all directories inside subdir...
/subdir/**/*.*

# ...except the ones we want
!/subdir/**/*.txt

Isso funciona porque gitignoretem regras especiais para **:

Dois asteriscos consecutivos (" **") em padrões combinados com o nome do caminho completo podem ter um significado especial:

  • Uma barra seguida por dois asteriscos consecutivos e uma barra corresponde a zero ou mais diretórios. Por exemplo, " a/**/b" corresponde a " a/b", " a/x/b", " a/x/y/b" e assim por diante.

A peça chave é ter certeza de não ignorar os diretórios, porque então todos os arquivos dentro desse diretório serão ignorados independentemente de outras regras.

Sharadh
fonte
0

Eu procurei por muito tempo:

  1. Suponha que eu tenha uma grande estrutura de pastas com aproximadamente 100.000 diretórios aninhados recursivamente. Nessas pastas, existem cerca de 30.000 arquivos do tipo .txt(no meu caso: tipo *.md). Ao lado desses *.mdarquivos, há, digamos, 500 GB de (mais de um milhão) de arquivos que não desejo rastrear.

  2. Eu quero que o git rastreie apenas .txt(ou *.md) arquivos em todas as pastas e subdiretórios.

A resposta correta deveria ser: isso não é possível no Git.

O que eu fiz em vez disso:

[editar: também não funcionou - tentei criar uma pasta com links simbólicos (ou links físicos) e usar o git lá, mas o git não segue links simbólicos e sobrescreve links físicos. Doh!]

Alex
fonte