A solução apresentada como a resposta mais votada é incorreta e facilmente demonstrável como tal.
Comece ignorando tudo nos uploads / *:
mkdir -p uploads/rubbish/stuff/KEEP_ME
touch uploads/a uploads/rubbish/a uploads/rubbish/stuff/a uploads/rubbish/stuff/KEEP_ME/a
echo '/uploads/*' >> .gitignore
git init
git add .
git commit -m "Initial commit"
Agora cancele a ignorar o diretório pai das coisas ignoradas como acima:
echo 'uploads/rubbish/stuff/KEEP_ME/' >> .gitignore
echo 'uploads/rubbish/stuff/KEEP_ME/*' >> .gitignore
git status -u
Não mostra arquivos não rastreados.
Para fazê-lo funcionar, você precisa ignorar todos os arquivos sob a uploads/
árvore ( uploads/**/*
não apenas o nível superior uploads/*
) e, em seguida, adicionar todos os diretórios pais da árvore que deseja manter
echo '/uploads/**/*' > .gitignore
echo '!/uploads/rubbish/' >> .gitignore
echo '!/uploads/rubbish/stuff' >> .gitignore
echo '!/uploads/rubbish/stuff/KEEP_ME' >> .gitignore
echo '!/uploads/rubbish/stuff/KEEP_ME/*' >> .gitignore
git status -u
Que dá:
On branch master
...
Untracked files:
(use "git add <file>..." to include in what will be committed)
uploads/rubbish/stuff/KEEP_ME/a
Se tivéssemos usado uploads/*
na .gitignore
acima, em seguida, todos os arquivos intermediários teria sido incluído, bem como, assim, por exemplo uploads/rubbish/a
iria aparecer no comando status acima.