Como rastrear diretórios, mas não seus arquivos com Git?

86

Recentemente, comecei a usar o Git e estou tendo problemas com apenas uma coisa. Como posso rastrear diretórios sem rastrear seu conteúdo?

Por exemplo, o site em que estou trabalhando permite uploads. Eu quero rastrear o diretório de uploads para que ele seja criado durante a ramificação, etc., mas obviamente não os arquivos dentro dele (arquivos de teste durante o branch de desenvolvimento ou os arquivos reais no master).

No meu .gitignore, tenho o seguinte:

uploads /*.*

Também tentei (o que ignora todo o diretório):

uploads /

Este diretório também pode conter subdiretórios (uploads / thumbs / uploads / videos /) Eu gostaria de poder rastreá-los, mas não seus arquivos.

Isso é possível com Git? Procurei em todos os lugares sem encontrar uma resposta.

Ben
fonte
Git apenas rastreia arquivos. O que você pode fazer é brincar com git hooks e rastrear um arquivo que conterá a listagem do diretório (gerado automaticamente usando os hooks). Embora eu não tenha certeza se isso seria possível.
Šimon Tóth
Mais concreto: o Git rastreia o conteúdo e (para o git) um diretório vazio não é conteúdo. Você pode argumentar, concordando ou não, mas como outra "solução alternativa", você pode pensar em criar os diretórios em build / install / when-needed. No entanto: eu uso a .placeholdersolução "-file" também;)
KingCrunch de
1
Em vez de usar .placeholder, eu uso um arquivo .gitignore. Isso não apenas cuida das exclusões dentro do diretório, mas também atua como um marcador de posição.
Abizern

Respostas:

114

Git não rastreia diretórios, ele rastreia arquivos, então para conseguir isso você precisa rastrear pelo menos um arquivo. Então, supondo que seu .gitignorearquivo seja algo assim:

upload/*

Você consegue fazer isso:

$ touch upload/.placeholder
$ git add -f upload/.placeholder

Se você esquecer o, -fverá:

$ git add upload / .placeholder
Os seguintes caminhos são ignorados por um de seus arquivos .gitignore:
Envio
Use -f se você realmente deseja adicioná-los.
fatal: nenhum arquivo adicionado

Então, quando você fizer isso, git statusvocê verá:

# No branch master
#
# Commit inicial
#
# Mudanças a serem confirmadas:
# (use "git rm --cached ..." para descompactar)
#
# novo arquivo: upload / .placeholder
#

Obviamente, você pode fazer:

$ touch upload/images/.placeholder
$ git add -f upload/images/.placeholder
Peter Farmer
fonte
Obrigado, isso é exatamente o que eu preciso.
Ben
11
Uma convenção comum para um espaço reservado é um arquivo gitignore.
Cascabel
2
@Jefromi De fato, conforme meus comentários ao Abizern, nunca havia considerado usar o .gitignorearquivo como espaço reservado.
Peter Farmer
1
Opa, de alguma forma perdi esses comentários.
Cascabel
3
Git não rastreia diretórios, ele rastreia arquivos parece engraçado quando eles ensinam que tudo é um arquivo no UNIX, até mesmo um diretório é um arquivo
Verde
38

Eu escrevi sobre isso aqui .

Adicione um .gitignore ao diretório.

Abizern
fonte
1
Bom pequeno artigo e comentários! Nunca tinha considerado usar .gitignore como o arquivo de espaço reservado ....
Peter Farmer
Obrigado. Aprendi algo apenas escrevendo um post e recebendo comentários.
Abizern
1
Parece haver uma convenção de nomenclatura popular agora para usar.gitkeep
tarabyte de
acabei de receber aquele mooment "ha-ha" agora, gostaria de poder votar 6 vezes diferentes
adelowo
13

A melhor solução até agora:

1) Crie um arquivo .gitignore

2) Escreva dentro:

*
*/
!.gitignore

3) Adicione o arquivo .gitignore à pasta desejada.

Fonte: https://stackoverflow.com/a/5581995/2958543

mejiamanuel57
fonte
6

Para rastrear apenas os diretórios, mas não os arquivos, fiz o seguinte. Graças ao comentário de @PeterFarmer sobre git tracking only files, consegui manter todos os diretórios, excluindo os arquivos, conforme descrito abaixo.

# exclude everything in every folder
/data/**/*.*

# include only .gitkeep files
!/data/**/*.gitkeep

Adicionar isso ao arquivo .gitignore fará o trabalho. A seguir está minha estrutura de pastas.

data/
├── processed
│   ├── dataset1.csv
│   └── dataset2.csv
├── raw
│   ├── raw_dataset1.json
└── test
    ├── subfolder
    │   └── dataset2.csv
    └── reviews.csv

Quando eu faço isso git add . && git status, o git reconhece apenas as pastas, mas não os arquivos.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   .gitignore
        new file:   data/processed/.gitkeep
        new file:   data/raw/.gitkeep
        new file:   data/test/.gitkeep
        new file:   data/test/subfolder/.gitkeep

Lembre-se do seguinte para seus arquivos .gitignore:

A barra precedente procura apenas o diretório raiz.

/ dir

Asterisco duplo procura zero ou mais diretórios.

/ ** /

Metinsenturk
fonte
Obrigado! Estou usando dessa forma e é muito útil
sebasira